Example #1
0
        public int MonteCarloSearch(Board rootState, double searchTimer)
        {
            //Check if we can find a winning move in one move
            string deb = "";

            if (true)
            {
                int winCheck = GetHighestValueMove(rootState, 1);
                if (winCheck == (rootState.width * rootState.width) / 2)
                {
                    return((rootState.width * rootState.width) / 2);
                }
                Board copy = new Board(rootState);
                copy.ChangeSquare(winCheck);
                int value = rootState.blackTurn ? EvaluateBoard(copy) : -EvaluateBoard(copy);
                deb += "Highest 1 ply value move is: " + winCheck.ToString() + ", value " + value.ToString() + ".\n  ";
                if (value > 9999)
                {
                    rootState.DebugWrite(deb);
                    return(winCheck);
                }
            }
            Node      root = new Node(rootState.lastSquare, null, rootState, 1);
            Stopwatch s    = new Stopwatch();

            s.Start();
            while (s.Elapsed.Seconds < searchTimer)
            {
                Node  node  = root;
                Board state = new Board(rootState);
                //Select
                while (node.untriedMoves.Count == 0 && node.nodes.Count != 0)
                {
                    node = NodeSelection(node);
                    state.ChangeSquare(node.move);
                    state.EndTurn();
                }
                //Expand
                if (node.untriedMoves.Count != 0)
                {
                    int move = node.GetRandomMove();
                    state.ChangeSquare(move);
                    state.EndTurn();
                    node = node.AddChild(move, state);
                }
                //Rollout
                int lastMove = node.move;
                while (EvaluateBoard(state) == 0)
                {
                    //int move = RootAlphaBeta(int.MinValue, int.MaxValue, state, 2);
                    int move = GetHighestValueMove(state, 1);
                    state.ChangeSquare(move);
                    state.EndTurn();
                    lastMove = move;
                }
                //Backpropagate
                int result = state.CheckWin(lastMove);
                while (node != null)
                {
                    node.games++;
                    if (result == -1)
                    {
                        node.wins += 0.4;
                    }
                    else if ((result == 1 && rootState.blackTurn) || (result == 2 && !rootState.blackTurn))
                    {
                        node.wins += 1;
                    }
                    else
                    {
                        node.wins += 0;
                    }
                    node = node.parent;
                }
            }
            int    bestI     = 0;
            double bestValue = double.MinValue;

            for (int i = 0; i < root.nodes.Count; i++)
            {
                double val = root.nodes[i].games * (root.nodes[i].wins / root.nodes[i].games);
                if (val > bestValue)
                {
                    deb      += "Move: " + root.nodes[i].move.ToString() + " has Wins " + root.nodes[i].wins.ToString("0.0") + ", games " + root.nodes[i].games.ToString() + ", = " + (root.nodes[i].wins / root.nodes[i].games).ToString("0.000") + ".\n  ";
                    bestI     = i;
                    bestValue = val;
                }
            }
            rootState.DebugWrite(deb);
            //rootState.DebugWrite("Done finding move from " + root.nodes.Count.ToString() + " available.");
            return(root.nodes[bestI].move);
        }