public GameEffect ChooseBestAction(GameChoice choice, Game game) { game = game.Clone(); // Inform the game and its descendents that it is a hypothetical game, so all players use the strategy of the player doing the imagining Readable_GamePlayer chooser = game.Get_ReadableSnapshot(choice.ControllerID); game.Strategy = game.GetStrategy(chooser); IEnumerable <GameEffect> effects = choice.Options; // create the base game Analyzed_GameState rootState = new Analyzed_GameState(game, null, null, this.GameEvaluator.EstimateWinProbabilities(game)); rootState.ChoosingPlayerID = choice.ControllerID; // Put the first set of choices onto the starting gameState this.PutGameOptions(rootState, choice); // loop until we run out of time while (rootState.NumDescendents < this.NumTimeSteps) { // Find the current best path and explore it for one more time unit this.ProcessOnce(rootState); double winProbability = rootState.WinProbabilities[choice.ControllerID]; if (winProbability == 0 || winProbability == 1) { break; } } if (this.ShouldPrint) { Console.WriteLine("Plan for " + chooser.ToString()); rootState.printBestPath(); } return(rootState.FavoriteChild.SourceEffect); }
private void ProcessOnce(Analyzed_GameState gameState) { // follow the series of game states that we predict to take place in the actual game while (gameState.FavoriteChild != null) { gameState = gameState.FavoriteChild; } // Generate a child game for each possibility Game currentGame = gameState.Game; this.PutGameOptions(gameState, currentGame.Get_NextChoice()); }
public Analyzed_GameState(Game resultantGame, Analyzed_GameState parent, GameEffect sourceEffect, Dictionary <ID <Readable_GamePlayer>, double> winProbabilities) { this.Game = resultantGame; this.SourceEffect = sourceEffect; //this.ChoosingPlayerID = choosingPlayerID; this.winProbabilities = winProbabilities; foreach (KeyValuePair <ID <Readable_GamePlayer>, double> entry in winProbabilities) { if (entry.Value < 0) { Console.WriteLine("Error: cannot have negative win probability"); } } this.Parent = parent; }
private void PutGameOptions(Analyzed_GameState gameState, GameChoice choice) { if (choice.Options.Count() < 1) { Console.WriteLine("Error: a GameChoice must always have options"); } gameState.ChoosingPlayerID = choice.ControllerID; foreach (GameEffect effect in choice.Options) { // quickly do a lazy clone of the game (we just use pointers to the other game until anything actually changes) Game newGame = gameState.Game.Clone(); // make a new effect and execute it GameEffect clonedEffect = effect.Clone((GameEffect)null); clonedEffect.Process(newGame); new Analyzed_GameState(newGame, gameState, effect, this.GameEvaluator.EstimateWinProbabilities(newGame)); } }
public void RemoveChild(Analyzed_GameState child) { this.Children.Remove(child); this.InvalidateAggregates(); }
public void AddChild(Analyzed_GameState child) { this.Children.Add(child); this.InvalidateAggregates(); }