void GenerateChildren() { children = new List <MCTSNode>(); foreach (Spot spot in game.AvailableSpots) { game.Play(spot, false, true); // make the move children.Add(new MCTSNode(game, spot, this)); game.UndoLastMove(true); // undo that move } }
/// <summary> /// Play <paramref name="game"/> randomly to the end /// Return positive if the player to make the first move won /// Return negative if the player to make the first move lost /// Return 0 if the game ends in a tie /// </summary> /// <param name="game"></param> /// <returns></returns> int Simulate(GlobalGame game) { Player activePlayer = game.ActivePlayer(); GlobalGame copy = CopyGlobalGame(game); while (!copy.GameOver()) { List <Spot> moves = copy.AvailableSpots; bool moveFound = false; // If there's a game-winning move, play it // This shortens simulations and makes them more realistic foreach (Spot spot in moves) { copy.Play(spot, false, true); if (copy.Winner != null) { moveFound = true; break; } copy.UndoLastMove(true); } // Otherwise play a random move if (!moveFound) { Spot randomSpot = moves[UnityEngine.Random.Range(0, moves.Count)]; copy.Play(randomSpot, false, true); } } if (copy.Winner == activePlayer) { return(1); } if (copy.Winner == null) { return(0); } return(-1); }