示例#1
0
        public bool ReceiveTurn(Move m)
        {
            if (Root.Children != null)
            {
                foreach (UCTNode child in Root.Children)
                {
                    if (child.Position.Equals(m))
                    {
                        Console.WriteLine("UCTTurbo-{0} had {1} nodes, lost {2} nodes and now has {3} nodes", _player == 1?"Black":"White", Root.MeasureTree(), Root.MeasureTree() - child.MeasureTree(), child.MeasureTree());
                        Root = child;
                        Root.Parent.Children = null;
                        child.Parent         = null;
                        if (child.Children == null)
                        {
                            child.CreateChildren();
                        }
                        return(true);
                    }
                }
            }
            Board newBoard = Root.BoardState.Clone();

            if (newBoard.PlaceStone(m) == false)
            {
                throw new ArgumentException("invalid turn");
            }
            Console.WriteLine("UCTTurbo-{0} had {1} nodes, lost {1} nodes and now has {2} nodes", _player == 1 ? "Black" : "White", Root.MeasureTree(), 1);
            Root.Children = null; //break the link for garbage collection
            UCTNode newRoot = new UCTNode(null, new Move(m), newBoard);

            newRoot.CreateChildren();
            Root = newRoot;
            return(true);
        }
示例#2
0
 public MonteCarloUCT(byte player, bool randomSims, bool resetTreeEachTurn)
 {
     if (player != 1 && player != 2)
         throw new ArgumentOutOfRangeException("player");
     Root = new UCTNode(null, new Move(-5, -5), new Board());
     Root.CreateChildren();
     _player = player;
     _randomUCT = randomSims;
     _resetTreeEachTurn = resetTreeEachTurn;
     _sims = GameParameters.UCTSimulations;
 }
示例#3
0
 public MonteCarloUCT(byte player, bool randomSims, bool resetTreeEachTurn)
 {
     if (player != 1 && player != 2)
     {
         throw new ArgumentOutOfRangeException("player");
     }
     Root = new UCTNode(null, new Move(-5, -5), new Board());
     Root.CreateChildren();
     _player            = player;
     _randomUCT         = randomSims;
     _resetTreeEachTurn = resetTreeEachTurn;
     _sims = GameParameters.UCTSimulations;
 }
示例#4
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);
        }
示例#5
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;
 }
示例#6
0
 public bool ReceiveTurn(Move m)
 {
     if (Root.Children != null)
     {
         foreach (UCTNode child in Root.Children)
         {
             if (child.Position.Equals(m))
             {
                 Console.WriteLine("UCTTurbo-{0} had {1} nodes, lost {2} nodes and now has {3} nodes", _player==1?"Black":"White", Root.MeasureTree(), Root.MeasureTree()-child.MeasureTree(), child.MeasureTree());
                 Root = child;
                 Root.Parent.Children = null;
                 child.Parent = null;
                 if (child.Children == null)
                     child.CreateChildren();
                 return true;
             }
         }
     }
     Board newBoard = Root.BoardState.Clone();
     if (newBoard.PlaceStone(m) == false)
         throw new ArgumentException("invalid turn");
     Console.WriteLine("UCTTurbo-{0} had {1} nodes, lost {1} nodes and now has {2} nodes", _player == 1 ? "Black" : "White", Root.MeasureTree(), 1);
     Root.Children = null; //break the link for garbage collection
     UCTNode newRoot = new UCTNode(null, new Move(m), newBoard);
     newRoot.CreateChildren();
     Root = newRoot;
     return true;
 }