private byte[] PredictBestMove(int depth, OthelloGame game, BoardStates player)
        {
            byte[]        bestMove = new byte[] { byte.MaxValue, byte.MaxValue };
            List <byte[]> moves    = game.GetPossiblePlayList();

            double bestScore = int.MinValue + 1;

            if (game.GetPieceCount(BoardStates.empty) > 58)//first two moves, don't compute
            {
                return(OpeningMove(player, game));
            }
            else if (moves.Count == 1) //don't compute if there is only 1 move
            {
                return(moves[0]);
            }

            foreach (byte[] move in moves)
            {
                OthelloGame testGame = game.DeepCopy();
                testGame.MakeMove(move);
                double thisScore = MinimaxAlphaBeta(testGame, depth - 1, double.MinValue, double.MaxValue, player);
                if (thisScore > bestScore)
                {
                    bestScore = thisScore;
                    bestMove  = move;
                }
            }
            return(bestMove);
        }
Exemple #2
0
        public static OthelloGame GetReflectedAcrossA1H8(OthelloGame game)
        {
            OthelloGame newGame = game.DeepCopy();

            for (int i = 0; i <= game.GetMovesMade(); i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    for (int k = 0; k < BOARD_SIZE; k++)
                    {
                        if (game.BoardHistory[i] != null)
                        {
                            newGame.BoardHistory[i][j, k] = game.BoardHistory[i][k, j];
                        }
                    }
                }
            }

            for (int i = 0; i < BOARD_SIZE; i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    newGame.Board[i, j] = game.Board[j, i];
                }
            }
            return(newGame);
        }
Exemple #3
0
        public static OthelloGame GetInverseGame(OthelloGame game)
        {
            OthelloGame newGame = game.DeepCopy();

            for (int i = 0; i <= game.GetMovesMade(); i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    for (int k = 0; k < BOARD_SIZE; k++)
                    {
                        if (game.BoardHistory[i] != null)
                        {
                            newGame.BoardHistory[i][j, k] = OpposingPlayer(game.BoardHistory[i][j, k]);
                        }
                    }
                }
            }

            for (int i = 0; i < BOARD_SIZE; i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    newGame.Board[i, j] = OpposingPlayer(game.Board[i, j]);
                }
            }
            return(newGame);
        }
Exemple #4
0
        public static OthelloGame GetHalfPiRotation(OthelloGame game)
        {
            OthelloGame newGame = game.DeepCopy();

            for (int i = 0; i <= game.GetMovesMade(); i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    for (int k = 0; k < BOARD_SIZE; k++)
                    {
                        if (game.BoardHistory[i] != null)
                        {
                            newGame.BoardHistory[i][j, k] = game.BoardHistory[i][BOARD_SIZE - k - 1, j];
                        }
                    }
                }
            }

            for (int i = 0; i < BOARD_SIZE; i++)
            {
                for (int j = 0; j < BOARD_SIZE; j++)
                {
                    newGame.Board[i, j] = game.Board[BOARD_SIZE - j - 1, i];
                }
            }
            return(newGame);
        }
        private double MinimaxAlphaBeta(OthelloGame board, int depth, double a, double b, BoardStates player)// bool isMaxPlayer)
        {
            // The heart of our AI. Minimax algorithm with alpha-beta pruning to speed up computation.
            // Higher search depths = greater difficulty.
            //from oliverzh200/reversi https://github.com/oliverzh2000/reversi

            if (depth == 0 || board.GameComplete)
            {
                return(HeuristicEval(player, board));
            }
            double        bestScore  = double.MinValue;
            List <byte[]> validMoves = board.GetPossiblePlayList();

            if (validMoves.Count > 0)
            {
                foreach (byte[] move in validMoves)
                {
                    OthelloGame childBoard = board.DeepCopy();
                    childBoard.MakeMove(move);
                    double nodeScore = MinimaxAlphaBeta(childBoard, depth - 1, a, b, player);

                    bestScore = Math.Max(bestScore, nodeScore);
                    a         = Math.Max(bestScore, a);

                    if (b <= a) //Prune
                    {
                        break;
                    }
                }
            }
            else
            {
                return(MinimaxAlphaBeta(board, depth, a, b, player));
            }
            return(bestScore);
        }
Exemple #6
0
        private byte[] PredictBestMove(int depth, OthelloGame game, BoardStates player)
        {
            byte[]        bestMove = new byte[] { byte.MaxValue, byte.MaxValue };
            List <byte[]> moves    = game.GetPossiblePlayList();

            double bestScore = int.MinValue + 1;

            foreach (byte[] move in moves)
            {
                OthelloGame testGame = game.DeepCopy();
                testGame.MakeMove(move);
                double thisScore = MinimaxAlphaBeta(testGame, depth - 1, double.MinValue, double.MaxValue, player);
                if (thisScore > bestScore)
                {
                    bestScore = thisScore;
                    bestMove  = move;
                }
            }
            if ((bestMove[0] == byte.MaxValue || bestMove[1] == byte.MaxValue) && moves.Count > 0)
            {//All moves are valued at -inf, return one of em
                return(moves[0]);
            }
            return(bestMove);
        }