protected int EvaluateRecursive(AwariPosition position, int depth)
        {
            if (depth == 0)
            {
                return(position.Position[AwariPosition.SOUTH_AWARI] - position.Position[AwariPosition.NORTH_AWARI]);
            }

            var moves = position.CanSow();

            if (moves.Count == 0)
            {
                return(position.Position[AwariPosition.SOUTH_AWARI] - position.Position[AwariPosition.NORTH_AWARI]);
            }

            var score = -1000;

            foreach (var move in moves)
            {
                position.Sow(move);

                var eval = -EvaluateRecursive(position, depth - 1);

                if (eval > score)
                {
                    score = eval;
                }

                position.MoveBack();
            }

            return(score);
        }
        public override int Evaluate(AwariPosition position, int depth)
        {
            var results = EvaluateParallel(position, depth);

            return(results.GroupBy(x => x.FirstMove)
                   .Select(x => new EvaluationResult(value: x.Min(y => y.Value), firstMove: x.Key))
                   .OrderByDescending(x => x.Value)
                   .First()
                   .Value);
        }
        private List <EvaluationResult> EvaluateParallel(AwariPosition position, int depth)
        {
            var evaluations = new List <Evaluation>();
            var results     = new List <EvaluationResult>();

            var first = position.CanSow();

            if (first.Count == 0)
            {
                results.Add(new EvaluationResult(position.Position[AwariPosition.SOUTH_AWARI] - position.Position[AwariPosition.NORTH_AWARI]));
            }
            else
            {
                foreach (var f in first)
                {
                    var p1 = position.Copy();
                    p1.Sow(f);

                    var second = p1.CanSow();

                    if (second.Count == 0)
                    {
                        results.Add(new EvaluationResult(p1.Position[AwariPosition.NORTH_AWARI] - p1.Position[AwariPosition.SOUTH_AWARI], f));
                        continue;
                    }
                    foreach (var s in second)
                    {
                        var p2 = position.Copy();
                        p2.Sow(f);
                        p2.Sow(s);
                        evaluations.Add(new Evaluation(position: p2, firstMove: f, secondMove: s));
                    }
                }
            }

            Parallel.ForEach(evaluations, x => {
                results.Add(
                    new EvaluationResult(
                        value: EvaluateRecursive(x.Position, depth - 2),
                        firstMove: x.FirstMove,
                        secondMove: x.SecondMove));
            });


            return(results);
        }
 public Evaluation(AwariPosition position, int firstMove = -1, int secondMove = -1, int value = 0)
 {
     Position   = position;
     FirstMove  = firstMove;
     SecondMove = secondMove;
 }
 public virtual int Evaluate(AwariPosition position, int depth)
 {
     return(EvaluateRecursive(position, depth));
 }