// Implementation of hook method which performs the move on the actual
        // Tic Tac Toe game board
        protected override AbstractMCTSNode <Pos, CellState> DoMakeMove(Pos move)
        {
            // Get a copy of the game board
            Board boardCopy = board.Copy();

            // Perform the move
            boardCopy.DoMove(move);

            // Return a new node representing the new state of the board
            return(new TicTacToeMCTSNode(boardCopy, move));
        }
        // Perform a playout / simulation using the given strategy
        public override CellState Playout(Func <IList <Pos>, Pos> strategy)
        {
            // Do the playout on a copy of the board
            Board boardCopy = board.Copy();

            // Keep playing using the given strategy until an endgame is reached
            while (!boardCopy.Status().HasValue)
            {
                // Use the given strategy to obtain a move
                Pos move = strategy(ValidMovesFromBoard(boardCopy));

                // Perform move
                boardCopy.DoMove(move);
            }

            return(boardCopy.Status().Value);
        }
Esempio n. 3
0
 // Perform a move
 public void Move(Pos pos)
 {
     gameBoard.DoMove(pos);
 }
Esempio n. 4
0
        // Process given board with ABNegamax
        private (float score, Pos move) Negamax(Board board, int depth)
        {
            // Increment number of evaluations (recursive ABNegamax calls)
            numEvals++;

            // Check what's the status of this board
            if (board.Status().HasValue)
            {
                // GAME OVER! Who won?

                if (board.Status().Value == CellState.Undecided)
                {
                    // It's a tie, return 0
                    return(0, Board.NoMove);
                }
                else if (board.Status().Value == board.Turn)
                {
                    // Current player wins, return max heuristic value
                    return(heuristic.WinScore, Board.NoMove);
                }
                else
                {
                    // The other player won, return min heuristic value
                    return(-heuristic.WinScore, Board.NoMove);
                }
            }
            else if (depth == maxDepth)
            {
                // We reached the max depth, return the heuristic value for this
                // board
                return(heuristic.Evaluate(board, board.Turn), Board.NoMove);
            }
            else
            {
                // Game is not over and we haven't reached maximum depth, so let's
                // recursively call Negamax on all possible moves

                // Declare best move, which for now is no move at all
                (float score, Pos move)bestMove =
                    (float.NegativeInfinity, Board.NoMove);

                // Try to play on all board positions
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        // Get the current board position
                        Pos pos = new Pos(i, j);

                        // Only consider making a move at this position if it's
                        // not already occupied
                        if (board.GetStateAt(pos) == CellState.Undecided)
                        {
                            // Score for current move
                            float score;

                            // Make a virtual move at this position
                            board.DoMove(pos);

                            // Get score for this move
                            score = -Negamax(board, depth + 1).score;

                            // Undo the move we just evaluated
                            board.UndoMove();

                            // Is this the best move so far?
                            if (score > bestMove.score)
                            {
                                // If so, keep it
                                bestMove = (score, pos);
                            }
                        }
                    }
                }
                // Return the best move found among all the tested moves
                return(bestMove);
            }
        }