public override Node PrepareAction(Node currState, Player oponent) { Node nextPlay = null; // Verify if the last state belongs to the mcts game tree // If the curr state is null, that means the previous player had no moves // and the game state did not changed. if (currState != null) { if (!GameTree.Childs.Contains(currState)) { GameTree = currState; } else { foreach (Node node in GameTree.Childs) { if (node.Equals(currState)) { GameTree = node; break; } } } } if (Selection != null && Simulation != null) { List <Node> selectionPath = new List <Node>(); Stopwatch cron = new Stopwatch(); TimeSpan max = new TimeSpan(0, 0, MAX_TIME); SelectionParameters args; int simulationResult = 0; Node auxRoot = GameTree; selectionPath.Add(auxRoot); // Traverse the game tree searching until it reaches a node that has no childs if (auxRoot != null) { while ((auxRoot.Childs != null) && (auxRoot.Childs.Count > 0)) { args.root = auxRoot; args.validStates = auxRoot.Childs; auxRoot = Selection.Execute(args); auxRoot.VisitCount++; selectionPath.Add(auxRoot); } } // Starts to simulate games from the last node visited in the previous loop cron.Start(); while (cron.Elapsed < max) { if (auxRoot != null) { simulationResult = RunSimulation(auxRoot); Backpropagation(selectionPath, simulationResult); selectionPath.Clear(); } auxRoot = GameTree; } Random rnd = new Random(); nextPlay = GameTree.Childs.ElementAt(rnd.Next(auxRoot.Childs.Count)); GameTree = nextPlay; } return(nextPlay); }