예제 #1
0
 public UCTNode(UCTNode parent, Move m, Board boardState)
 {
     if (m == null || boardState == null)
         throw new ArgumentNullException("m");
     BoardState = boardState.Clone();
     Parent = parent;
     Children = null;
     Position = new Move(m);
     Wins = 0;
     Visits = 0;
 }
예제 #2
0
 public void CopyStateFrom(Board b)
 {
     TurnNumber = b.TurnNumber;
     Passes = b.Passes;
     ActivePlayer = b.ActivePlayer;
     State = b.State;
     for (int i = 0; i < Size; i++)
         for (int j = 0; j < Size; j++)
         {
             _visited[i, j] = b._visited[i, j];
             _board[i, j] = b[i, j];
             _lastPosition[i, j] = b._lastPosition[i, j];
         }
 }
예제 #3
0
 int GetAvailableMoves(Board b)
 {
     if (_availableMoves == null)
         _availableMoves = new Move[Size*Size+1];
     int moveCount = 0;
     for (int i = 0; i < Size; i++)
     {
         for (int j = 0; j < Size; j++)
         {
             //is on empty space on the board and not a friendly eye
             if (b[i, j] == 0 && b.IsEye(i, j) != b.ActivePlayer)
             {
                 _availableMoves[moveCount++] = new Move(i, j);
             }
         }
     }
     return moveCount;
 }
예제 #4
0
 public int PlaySimulation()
 {
     if (_testingBoard == null)
         _testingBoard = new Board();
     _testingBoard.CopyStateFrom(_startingTestingBoard);
     int turnsSimulated = 0;
     while (turnsSimulated < GameParameters.GameDepth && _testingBoard.IsGameOver() == false)
     {
         turnsSimulated++;
         Move m = new Move(-1, -1);
         do
         {
             m.row= RandomGen.Next(-1, GameParameters.BoardSize);
             m.column = RandomGen.Next(-1, GameParameters.BoardSize);
         } while (_testingBoard.PlaceStone(m) == false);
     }
     int winner = _testingBoard.DetermineWinner();
     return winner;
 }
예제 #5
0
 double GetWinrate(Move move)
 {
     if (_startingTestingBoard == null)
         _startingTestingBoard = new Board();
     _startingTestingBoard.CopyStateFrom(_actualBoard);
     if (_startingTestingBoard.PlaceStone(move) == false)
         return -1;
     UInt64 sim = 0;
     int wins = 0;
     while (sim < GameParameters.RandomSimulations)
     {
         int winner = PlaySimulation();
         if (winner != 0)
         {
             sim++;
             if (winner == _actualBoard.ActivePlayer)
                 wins++;
         }
     }
     return sim > 0 ? (double)wins / sim : -1;
 }
예제 #6
0
 public int PlaySimulation()
 {
     if (_testingBoard == null)
         _testingBoard = new Board();
     _testingBoard.CopyStateFrom(_startingTestingBoard);
     int turnsSimulated = 0;
     while (turnsSimulated < GameParameters.GameDepth && _testingBoard.IsGameOver() == false)
     {
         turnsSimulated++;
         int moveCount = GetAvailableMoves(_testingBoard);
         Move pass = new Move(-1, -1); //добавить в список возможных ходов пас
         _availableMoves[moveCount++] = pass;
         _availableMoves.Shuffle(moveCount);
         for (int i = 0; i < moveCount; i++)
         {
             if (_testingBoard.PlaceStone(_availableMoves[i]) == true)
             {
                 break;
             }
         }
     }
     int winner = _testingBoard.DetermineWinner();
     return winner;
 }
예제 #7
0
 public Board Clone()
 {
     Board result = new Board();
     result.CopyStateFrom(this);
     return result;
 }
예제 #8
0
 private static int ApplyHeuristics(Board board, int turnCount)
 {
     int k = 0;
     int j = 0;
     if (board.TurnNumber < 5)
     {
         while (j < turnCount)
         {
             Move m = _availableMoves[j++];
             if (m.row > 1 && m.row < 7 && m.column > 1 && m.column < 7)
                 _availableMoves[k++] = m;
         }
     }
     else if (board.TurnNumber < 10)
     {
         while (j < turnCount)
         {
             Move m = _availableMoves[j++];
             if (m.row > 0 && m.row < 8 && m.column > 0 && m.column < 8)
                 _availableMoves[k++] = m;
         }
     }
     else k = turnCount;
     return k;
 }
예제 #9
0
 private int PlaySimulation(UCTNode n)
 {
     if (_boardClone == null)
         _boardClone = new Board();
     int randomWinner = 0;
     if (n.IsSolved == true) //should always be false (only for single thread! - can be true for multiple threads)
     {
         int solvedCurrentPlayerWins = n.SolvedWinner == _player ? 1 : 0;
         n.Update(solvedCurrentPlayerWins); //update node (Node-wins are associated with moves in the Nodes)
         return n.SolvedWinner;
     }
     if (n.Children == null && n.Visits < GameParameters.UCTExpansion && n.IsSolved == false)
     {
         if (_boardClone == null)
             _boardClone = new Board();
         randomWinner = PlayMoreOrLessRandomGame(n);
     }
     else
     {
         if (n.HasChildren == false)
             n.CreateChildren();
         UCTNode next = UCTSelect(n); // select a move
         if (next == null) //only happens in finished positions and solved nodes - we can start backpropagating ideal result
         {
             n.IsSolved = true;
             if (n.Children.Count == 0) //this is a terminal position - there can be no nodes after it
             {
                 n.SolvedWinner = n.BoardState.DetermineWinner();
             }
             else //this is a non-terminal position for which all possible subsequent moves have been checked
             {
                 if (n.BoardState.ActivePlayer == _player) //if, for this node, it's this player's turn, then we take the best result
                 {
                     foreach (UCTNode child in n.Children)
                     {
                         if (child.IsSolved == false)
                             throw new ImpossibleException("solved node's child is not solved", "PlaySimulation");
                         if (child.SolvedWinner == _player) //if we find a choice that leads to sure win for current player, we immediately take it
                         {
                             n.SolvedWinner = _player;
                             n.Update(1);
                             return 1;
                         }
                         //if we don't find a node that leads to current player's victory
                         n.SolvedWinner = 3 - _player;
                         n.Update(0);
                         return 0;
                     }
                 }
                 else //if it's enemy's turn on this node, then we take the worst result
                 {
                     foreach (UCTNode child in n.Children)
                     {
                         if (child.IsSolved == false)
                             throw new ImpossibleException("solved node's child is not solved", "PlaySimulation");
                         if (child.SolvedWinner != _player) //if we find a choice that leads to sure win for enemy, we immediately take it
                         {
                             n.SolvedWinner = 3 - _player;
                             n.Update(0);
                             return 0;
                         }
                         //if we don't find a node that leads to enemy's victory, we assume that this is our winning node
                         n.SolvedWinner = _player;
                         n.Update(1);
                         return 1;
                     }
                 }
             }
         }
         else
         {
             randomWinner = PlaySimulation(next);
         }
     }
     int currentPlayerWins = randomWinner == _player ? 1 : 0;
     n.Update(currentPlayerWins); //update node (Node-wins are associated with moves in the Nodes)
     return randomWinner;
 }
예제 #10
0
        public static void PlayGame(IPlayer blackPlayer, IPlayer whitePlayer)
        {
            gameRecord.AppendLine("(;FF[4]GM[1]SZ[9]AP[dotNetGo]");

            gameRecord.AppendLine(String.Format("PB[{0}]", blackPlayer.Name));
            gameRecord.AppendLine("HA[0]");
            gameRecord.AppendLine(String.Format("PW[{0}]", whitePlayer.Name));
            gameRecord.AppendLine("KM[6.5]");
            gameRecord.AppendLine("RU[Chinese]");
            gameRecord.AppendLine("");
            gameRecord.AppendLine("");
            Board board = new Board();
            while (board.IsGameOver() == false)
            {
                Move move;
                switch (board.ActivePlayer)
                {
                    case 1:
                        move = blackPlayer.GetMove();
                        break;
                    default: //case 2:
                        move = whitePlayer.GetMove();
                        break;
                }
                if (blackPlayer.ReceiveTurn(move) == false)
                    throw new ImpossibleException("somehow invalid turn made it through", "PlayGame");
                if (whitePlayer.ReceiveTurn(move) == false)
                    throw new ImpossibleException("somehow invalid turn made it through", "PlayGame");
                if (move.row >= 0 && move.column >= 0)
                    gameRecord.AppendFormat(";{0}[{1}{2}]", board.ActivePlayer == 1? "B": "W", alphabet[move.column], alphabet[move.row]);
                if (board.PlaceStone(move) == false)
                    throw new ImpossibleException("somehow invalid turn made it through", "PlayGame");
                Console.WriteLine(board);
                //Console.ReadLine();
            }
            switch (board.State)
            {
                case Board.GameState.BlackSurrendered:
                    Console.WriteLine("White won by resignation, last position:");
                    break;
                case Board.GameState.WhiteSurrendered:
                    Console.WriteLine("Black won by resignation, last position:");
                    break;
                case Board.GameState.DoublePass:
                    double blackScore, whiteScore;
                    board.DetermineWinner(out blackScore, out whiteScore);
                    gameRecord.AppendFormat(";RE[{0}+{1}]", blackScore > whiteScore?"B":"W", Math.Abs(blackScore-whiteScore));
                    Console.WriteLine(board);
                    Console.WriteLine("Turn: {0}", board.TurnNumber);
                    Console.WriteLine("Black score: {0}; White score: {1}", blackScore, whiteScore);
                    Console.WriteLine("last position:");
                    break;
            }
            Console.WriteLine(board);
            gameRecord.Append(")");
            DateTime dt = DateTime.Now;
            string filename = String.Format("{0}-{1}-{2}-{3}-{4}-{5}.sgf",
                dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
            File.WriteAllText(filename, gameRecord.ToString(), Encoding.UTF8);
        }