Beispiel #1
0
        public Move MinMaxRoot(int depth, Game g, bool IsMaximizingPlayer)
        {
            MoveGenerationResult result = g.GetMoves();

            count += result.Moves.Count;
            if (result.Endgame == EndgameType.Checkmate)
            {
                throw new CheckmateException();
            }
            else if (result.Endgame == EndgameType.Stalemate)
            {
                throw new StalemateException();
            }

            double bestMove      = -999999 * (g.WhiteToMove ? 1 : -1);
            Random r             = new Random();
            Move   bestMoveFound = result.Moves[r.Next(result.Moves.Count - 1)];

            string FENFEN = g.ToFENString();

            var exceptions = new ConcurrentQueue <Exception>();
            ConcurrentBag <Tuple <Move, double> > resultVal = new ConcurrentBag <Tuple <Models.Move, double> >();

            Parallel.ForEach(result.Moves, (move) =>
            {
                Game g2 = new Game(FENFEN);
                move    = g2.Move(move);
                try
                {
                    double value = MiniMax(depth - 1, g2, -1000000, 1000000, !IsMaximizingPlayer, move.To);
                    resultVal.Add(new Tuple <Move, double>(move, value));
                }
                catch (Exception w)
                {
                    exceptions.Enqueue(w);
                }
                g2.Undo();
            });

            if (exceptions.Count > 0 && resultVal.Count == 0)
            {
                Exception ex;
                exceptions.TryDequeue(out ex);
                throw ex;
            }

            foreach (Tuple <Move, double> moveTuple in resultVal)
            {
                if ((g.WhiteToMove && (moveTuple.Item1.MaterialScore >= bestMove)) || (!g.WhiteToMove && (moveTuple.Item1.MaterialScore <= bestMove)))
                {
                    bestMove      = moveTuple.Item2;
                    bestMoveFound = moveTuple.Item1;
                }
            }

            return(bestMoveFound);
        }
Beispiel #2
0
        public double MiniMax(int depth, Game g, double alpha, double beta, bool IsMaximizingPlayer, int thisMove)
        {
            if (depth == 0)
            {
                return(g.BoardValue());
            }

            MoveGenerationResult result = g.GetMoves();

            if (result.Endgame == EndgameType.Checkmate)
            {
                if (g.WhiteToMove)
                {
                    return(-10000000);
                }
                else
                {
                    return(10000000);
                }
            }
            if (result.Endgame == EndgameType.Stalemate)
            {
                if (g.WhiteToMove)
                {
                    return(10000000);
                }
                else
                {
                    return(-10000000);
                }
            }
            count += result.Moves.Count;

            if (g.WhiteToMove)
            {
                double bestMove = -999999;

                foreach (Move move in result.Moves)
                {
                    g.Move(move);
                    bestMove = Math.Max(bestMove, MiniMax(depth - 1, g, alpha, beta, !IsMaximizingPlayer, move.To));
                    g.Undo();

                    alpha = Math.Max(alpha, bestMove);
                    if (beta <= alpha)
                    {
                        return(bestMove);
                    }
                }
                return(bestMove);
            }
            else
            {
                double bestMove = 999999;
                foreach (Move move in result.Moves)
                {
                    g.Move(move);
                    bestMove = Math.Min(bestMove, MiniMax(depth - 1, g, alpha, beta, !IsMaximizingPlayer, move.To));
                    g.Undo();

                    beta = Math.Min(beta, bestMove);
                    if (beta <= alpha)
                    {
                        return(bestMove);
                    }
                }
                return(bestMove);
            }
        }