Example #1
0
        private Estimate FindImpl(Game game, Estimate alpha, Estimate beta, int depth, int maxDepth, Metadata meta)
        {
            Player player = game.State.NextMovePlayer;
            bool   isMax  = player == Player.Maximizing;

            if (maxDepth - depth == 0)
            {
                return(game.State.StaticEstimate);
            }

            if (game.State.IsTerminate)
            {
                // make AI pick shortest path to terminate state
                // otherwise there will be funny situation then AI seeing that it won
                // w/o chances for other side will not purse the winning

                Estimate terminateEstimate = game.State.StaticEstimate;

                EstimateHelper.AdjustTerminalStateEstimate(depth, ref terminateEstimate);

                return(terminateEstimate);
            }

            Estimate v = isMax
                ? Estimate.MinInf
                : Estimate.MaxInf;

            List <Move> moves = game.GetAllowedMoves()
                                .OrderByDescending(x => x.Priority)
                                .ToList();

            foreach (Move move in moves)
            {
                meta.MovesChecked += 1;

                using (DisposableMoveHandle.New(game, move))
                {
                    Estimate curEstimate = FindImpl(game, alpha, beta, depth + 1, maxDepth, meta);

                    bool betterMoveFound = isMax
                        ? curEstimate > v
                        : curEstimate < v;

                    if (betterMoveFound)
                    {
                        v = curEstimate;

                        if (depth == 1)
                        {
                            meta.BestMove = move;
                        }
                    }

                    if (isMax)
                    {
                        alpha = Estimate.Max(alpha, v);
                    }
                    else
                    {
                        beta = Estimate.Min(beta, v);
                    }

#if DEBUG
                    if (depth <= 3)
                    {
                        Trace.WriteLine($"{ new string(' ', depth) } - Move {move} for {player} -- {curEstimate} -- Term? {game.State.IsTerminate}");
                    }
#endif

                    if (alpha >= beta)
                    {
                        // alpha/beta cut-off
                        //Trace.WriteLine($"cut-off on depth {depth}");
                        break;
                    }
                }
            }

            return(v);
        }