public Node(Move move, Node parent, State state, Deck deck) { this.state = state; this.generatingMove = move; this.parent = parent; this.results = 0; this.visits = 0; this.children = new List<Node>(); this.untriedMoves = state.GetMoves(deck); }
// adds a child node to the list of children // after exploring a move - removes the move from untried public Node AddChild(Move move, State state, Deck deck) { Node child = new Node(move, this, state, deck); this.untriedMoves.Remove(move); this.children.Add(child); return child; }
// Time limited MCTS private Node TimeLimited(State rootState, int timeLimit, Stopwatch timer, Deck deck) { Node rootNode = new Node(null, null, rootState, deck); while (true) { if (timer.ElapsedMilliseconds > timeLimit) { if (FindBestChild(rootNode.Children) == null && !rootNode.state.IsGameOver()) { timeLimit += 10; timer.Restart(); } else { return rootNode; } } Node node = rootNode; State state = rootState.Clone(); Deck clonedDeck = deck.Clone(); // 1: Select while (node.UntriedMoves.Count == 0 && node.Children.Count != 0) { node = node.SelectChild(); state = state.ApplyMove(node.GeneratingMove); if (node.GeneratingMove is ComputerMove) { clonedDeck.Remove(((ComputerMove)node.GeneratingMove).Card); if (clonedDeck.IsEmpty()) clonedDeck = new Deck(); } } // 2: Expand if (node.UntriedMoves.Count != 0) { Move randomMove = node.UntriedMoves[random.Next(0, node.UntriedMoves.Count)]; if (randomMove is ComputerMove) { if (clonedDeck.IsEmpty()) clonedDeck = new Deck(); clonedDeck.Remove(((ComputerMove)randomMove).Card); state = state.ApplyMove(randomMove); node = node.AddChild(randomMove, state, clonedDeck); } else { state = state.ApplyMove(randomMove); node = node.AddChild(randomMove, state, clonedDeck); } } // 3: Simulation while (state.GetMoves(clonedDeck).Count != 0) { Move move = state.GetRandomMove(clonedDeck); if (move is ComputerMove) { if (clonedDeck.IsEmpty()) clonedDeck = new Deck(); clonedDeck.Remove(((ComputerMove)move).Card); state = state.ApplyMove(move); } else { state = state.ApplyMove(move); } } // 4: Backpropagation while (node != null) { node.Update(state.GetResult()); node = node.Parent; } } }