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); }