public override PlayerTask GetMove(POGame poGame) { if (poGame.Turn != turn) { turnWatch.Restart(); turn = poGame.Turn; } actWatch.Restart(); int actTime = (int)((30000 - turnWatch.ElapsedMilliseconds) * 0.75); var player = poGame.CurrentPlayer.PlayerId; var openTasks = new Stack <SimGame>(); openTasks.Push(new SimGame(poGame, SearchDepth)); // lookahead all solutions until SearchDepth reached int bestScore = int.MinValue; SimGame bestSim = null; while (openTasks.Any()) { var currentSim = openTasks.Pop(); var children = currentSim.Next(); for (int j = 0; j < children.Length; j++) { if (!children[j].hasChildren) { int score = children[j].GameValue(player, scoreDict); if (score > bestScore) { bestScore = score; bestSim = children[j]; } } else { openTasks.Push(children[j]); } } if (actWatch.ElapsedMilliseconds >= actTime) { break; } } //Debug.WriteLine($"Turn {poGame.Turn}|{poGame.CurrentPlayer.Hero.Health - poGame.CurrentOpponent.Hero.Health} took {actWatch.ElapsedMilliseconds}ms to find {bestSim.tasks[0]}"); //var foo = poGame.CurrentPlayer.Options(); //var bar = poGame.Simulate(foo); return(bestSim?.tasks[0] ?? poGame.Simulate(poGame.CurrentPlayer.Options()).Keys.First()); }
public SimGame[] Next() { if (depth <= 0) { return(new SimGame[0]); } var options = game.CurrentPlayer.Options(); var retval = new SimGame[options.Count]; var sims = game.Simulate(options); int i = 0; foreach (var sim in sims) { var newTasks = new PlayerTask[tasks.Length + 1]; Array.Copy(tasks, newTasks, tasks.Length); newTasks[tasks.Length] = sim.Key; retval[i] = new SimGame(sim.Value, sim.Key.PlayerTaskType == PlayerTaskType.END_TURN ? 0 : depth - 1, newTasks, step + 1); i++; } return(retval); }