Ejemplo n.º 1
0
        /// <summary>
        /// This method executes the simulation of a game. It decides the statistics (wins and simulations)
        /// for a certain starting node. Based on the current board and the current player, chooses the next move
        /// until the end of the game. If the current player (the bot) wins, it returns 1 (1 win) and updates
        /// (back-propagates the results) back in the recursion stack.
        /// </summary>
        /// <param name="token">Cancellation token used to stop the execution of the thread executing this function.</param>
        /// <param name="b">The current board.</param>
        /// <param name="n">The current node, representing the board configuration.</param>
        /// <param name="expansion">Object representing the expansion strategy.</param>
        /// <param name="expandColor">The color of the next player.</param>
        /// <returns></returns>
        private int Simulate(CancellationTokenSource token, Board b, Node n, IExpansion expansion, Color expandColor)
        {
            //Console.WriteLine("Expand " + expandColor.ToString());
            int res = 0;

            if (token.IsCancellationRequested == false)
            {
                /* check if game is finished. */
                if (b.IsFinished(thisPlayer) == true || b.IsFinished(opponent) == true || (b.GetScore(1) + b.GetScore(2) == 64) ||
                    b.PlayerHasPossibleMoves(thisPlayer) == false || b.PlayerHasPossibleMoves(opponent) == false)
                {   /* set this node as terminal. */
                    n.expandable = false;
                    /* find the game result. */
                    if (b.GetScore(1) == b.GetScore(2))
                    {
                        res = 0;
                    }
                    else if (b.GetScore(1) > b.GetScore(2))
                    {   /* player 1(black) won. */
                        res = (thisPlayer.GetColor() == Color.black) ? 1 : -1;
                    }
                    else
                    {   /* player 2(white) won. */
                        res = (thisPlayer.GetColor() == Color.black) ? -1 : 1;
                    }
                }
                else
                {   /* continue simulating. */
                    /* expand, if necessary. */
                    expansion.SetBoard(b);
                    List <Node> chl = expansion.Expand(n, expandColor);
                    expandColor = SwitchColor(expandColor);
                    /* choose random child. */
                    Node nextNode = chl[rand.Next(chl.Count)];
                    /* update board. */
                    Piece pct = new Piece(nextNode.X, nextNode.Y, GetOwner(b, n));
                    if (b.pieces[nextNode.X, nextNode.Y] != null)
                    {
                        throw new MCTSException("next node is not null!");
                    }
                    PlacePieceOnBoard(b, pct);
                    /* simulate. */
                    res = Simulate(token, b, nextNode, expansion, expandColor);
                    /* update node statistics if cancellation is not set. */
                    if (res != -2)
                    {
                        n.IncWins(res); /* res could be -1, 0 or 1. */
                        n.IncVisits(1);
                    }
                }
            }
            else
            {   /* cancel request while simulating. */
                res = -2;
            }
            return(res); /* return result. */
        }
Ejemplo n.º 2
0
 /**
  * IncPlayerScore - increments player score.
  *
  * @p: the player whoose score needs to be incremented.
  */
 private void IncPlayerScore(IMCTSPlayer p)
 {
     if (p.GetColor() == player.Color.black)
     {   /* player 1. */
         playerOneScore++;
     }
     else
     {   /* player 2. */
         playerTwoScore++;
     }
     if (playerOneScore + playerTwoScore > 64)
     {
         throw new MCTSException("[Board/IncPlayerScore()] - players scores are invalid ( > 64).");
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// This method returns the color of the current player based on the current node.
        /// </summary>
        /// <param name="b">Current board.</param>
        /// <param name="n">current node representing the state of the board.</param>
        /// <returns></returns>
        private Color GetColor(Board b, Node n)
        {
            Color color;

            if (n.X == -1 || n.Y == -1)
            {
                color = Color.black;
            }
            else if (b.pieces[n.X, n.Y].owner == thisPlayer)
            {   /* this player moved last. it's opponent's turn. */
                color = opponent.GetColor();
            }
            else
            {   /* opponent moved last. this player's turn. */
                color = thisPlayer.GetColor();
            }
            return(color);
        }
Ejemplo n.º 4
0
 /**
  * DecPlayerScore - decrements player score.
  *
  * @p: current player.
  */
 private void DecPlayerScore(IMCTSPlayer p)
 {
     if (p.GetColor() == player.Color.black)
     {
         playerOneScore--;
         if (playerOneScore < 0)
         {
             throw new MCTSException("[Board/DecPlayerScore()] - player one score is negative!");
         }
     }
     else
     {
         playerTwoScore--;
         if (playerTwoScore < 0)
         {
             throw new MCTSException("[Board/DecPlayerScore()] - player two score is negative!");
         }
     }
 }