view src/main/csharp/jp.ac.u-ryukyu.ie.cr/jungle-main/traverser/DefaultTraverser.cs @ 17:01a08cf4b2d9

Liq Files
author Kazuma
date Mon, 07 Nov 2016 01:05:24 +0900
parents abe0c247f5a5
children
line wrap: on
line source

using System.Collections.Generic;
using System.Collections;
using UnityEngine;
using System;
// yet write.
public class DefaultTraverser : Traverser  {


	public Either<Error, Traversal> traverse(TreeNode _root, Evaluator _evaluator) {
		// 無名クラスを書いてない
		Children warper = new InnerChildren(_root, _evaluator);

		Children chs = warper;
		Either<Error, List<Direction<TreeNode>>> ret = _traverse(chs, _evaluator, -1);

		if (ret.isA ()) {
			return DefaultEither<Error, Traversal>.newA (ret.a ());
		}

		List<Direction<TreeNode>> list = ret.b ();
		IEnumerator<Direction<TreeNode>> iterable = list.iterator ();
		TreeNode destination = ret.b ().headList ().getTarget ();

		Traversal traversal = new InnerTraversal (iterable, destination);

		return DefaultEither<Error, Traversal>.newB (traversal);

	}


	private Either<Error, List<Direction<TreeNode>>> _traverse(Children _chs, Evaluator _evaluator, int _pos) {
		int pos = _pos;
		TreeNode ch;
		for (int i = 0; i < _chs.size(); i++) {
			Either<Error,TreeNode> either = _chs.at(i);
			if (either.isA ()) {
				break;
			}

			ch = either.b();
			Evaluation e = _evaluator.evaluate (ch, pos);
			Result r = e.results();

			if (r == Result.ACCEPT) {
				return _accept (ch, pos, e.evaluators ());
			}

			if (r == Result.GOAL) {
				return DefaultEither<Error,List<Direction<TreeNode>>>.newB(_goal(ch, pos));
			}

			if (r == Result.BREAK) {
				break;
			}

			if (r == Result.CONTINUE) {
				pos++;
				continue;
			}

			return DefaultEither<Error, List<Direction<TreeNode>>>.newA (TraverserError.UNDEFINED_OPERATOR);
		}
		return DefaultEither<Error, List<Direction<TreeNode>>>.newA (TraverserError.PATH_NOT_FOUND);
	}


	private List<Direction<TreeNode>> _goal( TreeNode _current, int _pos) {
		Direction<TreeNode> d  = new InnerDirection<TreeNode> (_pos, _current);

		List<Direction<TreeNode>> list = new List<Direction<TreeNode>> ();
		List<Direction<TreeNode>> newList = list.addLast (d);

		return newList;
	}


	private Either<Error, List<Direction<TreeNode>>> _accept(TreeNode _current, int _pos,Evaluator _evaluator)
	{
		Children chs = _current.getChildren ();
		Either<Error, List<Direction<TreeNode>>> either = _traverse (chs, _evaluator, 0);
		if (either.isA ()) {
			return either;
		}
		List<Direction<TreeNode>> list = either.b ();
		Direction<TreeNode> d = new InnerDirection<TreeNode> (_pos, _current);

		List<Direction<TreeNode>> newList = list.addLast (d);
		return DefaultEither<Error,List<Direction<TreeNode>>>.newB (newList);
	}

	public class InnerTraversal : Traversal{
		IEnumerator<Direction<TreeNode>> iterable;
		TreeNode destination;

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		public IEnumerator<Direction<TreeNode>> GetEnumerator()
		{
			return iterable;
		}


		public InnerTraversal(IEnumerator<Direction<TreeNode>> _iterable, TreeNode _distination){
			this.iterable = _iterable;
			this.destination = _distination;
		}

	
		public TreeNode destinations() {
			return destination;
		}

	}

	public class InnerChildren : Children{
		TreeNode root;
		Evaluator evaluator;

		public InnerChildren(TreeNode _root, Evaluator _evaluator){
			this.root = _root;
			this.evaluator = _evaluator;
		}

		public IEnumerator<TreeNode> iterator() {
			List<TreeNode> list = new List<TreeNode> ();
			return list.addLast (root).iterator ();
		}

		public int size() {
			return 1;
		}

		public Either<Error, TreeNode> at(int _pos) {
			if (_pos != 0) {
				return DefaultEither<Error, TreeNode>.newA (NodeEditorError.INDEX_OUT_OF_BOUNDS);
			}
			return DefaultEither<Error, TreeNode>.newB (root);
		}
	}

	public class InnerDirection<TreeNode> : Direction<TreeNode>{
		int pos;
		TreeNode current;

		public InnerDirection(int _pos, TreeNode _current) {
			this.pos = _pos;
			this.current = _current;
		}

		public int getPosition() {
			return pos;
		}

		public TreeNode getTarget(){
			return current;
		}
	}

}