public void BasicIniciativeTest() { var game = new GameInstance(3); var m2 = game.AddMobWithInfo(new MobInfo(TeamColor.Blue, 10, 10, 2, new List <int>())); var m3 = game.AddMobWithInfo(new MobInfo(TeamColor.Blue, 10, 10, 3, new List <int>())); var m4 = game.AddMobWithInfo(new MobInfo(TeamColor.Red, 10, 10, 4, new List <int>())); var m1 = game.AddMobWithInfo(new MobInfo(TeamColor.Red, 10, 10, 1, new List <int>())); game.PrepareEverything(); Assert.AreEqual(game.CurrentMob, m1); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m2); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m3); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m4); // At this point a new turn should start ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m1); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m2); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m3); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(game.CurrentMob, m4); }
/// <summary> /// Runs a playout with two given controllers and reports the result. /// </summary> public static PlayoutResult Playout(GameInstance game, IMobController ai1, IMobController ai2) { var hub = new GameEventHub(game); game.MobManager.Teams[TeamColor.Red] = ai1; game.MobManager.Teams[TeamColor.Blue] = ai2; const int maxIterations = 100; int i = 0; for (; i < maxIterations && !game.IsFinished; i++) { game.CurrentController.FastPlayTurn(hub); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); } float totalMaxHp = 0; float totalCurrentHp = 0; foreach (var mobId in game.MobManager.Mobs) { totalMaxHp += game.MobManager.MobInfos[mobId].MaxHp; totalCurrentHp += Math.Max(0, game.State.MobInstances[mobId].Hp); } int red = 0; int blue = 0; Utils.Log(LogSeverity.Error, nameof(GameEvaluator), $"Playout time limit reached at {maxIterations} rounds"); if (i < maxIterations && game.VictoryTeam.HasValue) { if (game.VictoryTeam.Value == TeamColor.Red) { red++; } else { blue++; } Accounting.IncrementWinner(game.VictoryController); } var gamePercentage = totalCurrentHp / totalMaxHp; Debug.Assert(gamePercentage >= 0); var mobsCount = game.MobManager.Mobs.Count; var dis = new Normal(mobsCount * 2, mobsCount); dis.Density(mobsCount * 2); return(new PlayoutResult(i, gamePercentage, game.State.AllPlayed, i == maxIterations, red, blue)); }
/// <summary> /// Simulates the playout till the end and calculates a reward. /// </summary> public static float DefaultPolicy(GameInstance game, TeamColor startingTeam) { if (game.IsFinished) { Debug.Assert(game.VictoryTeam.HasValue || game.AllDead, "game.VictoryTeam.HasValue"); return(CalculateDeltaReward(game, startingTeam, game.VictoryTeam)); } Debug.Assert(game.CurrentTeam.HasValue, "game.CurrentTeam.HasValue"); var copy = game.CopyStateOnly(); const int maxDefaultPolicyIterations = 200; int iterations = maxDefaultPolicyIterations; ReplayRecorder.Instance.Clear(); bool wasMove = false; while (!copy.IsFinished && iterations-- > 0) { var action = ActionGenerator.DefaultPolicyAction(copy); if (action.Type == UctActionType.Move) { if (wasMove) { action = UctAction.EndTurnAction(); } wasMove = true; } if (action.Type == UctActionType.EndTurn) { wasMove = false; } if (action.Type == UctActionType.Null) { throw new InvalidOperationException(); } ActionEvaluator.FNoCopy(copy, action); } if (iterations <= 0) { ReplayRecorder.Instance.SaveAndClear(game, 0); //throw new InvariantViolationException("MCTS playout timeout"); Utils.Log(LogSeverity.Error, nameof(UctAlgorithm), $"DefaultPolicy ran out of time (over {maxDefaultPolicyIterations} iterations for playout), computed results are likely wrong."); return(0); } TeamColor?victoryTeam = copy.VictoryTeam; return(CalculateDeltaReward(game, startingTeam, victoryTeam)); }
public void FastPlayTurn(GameEventHub eventHub) { do { var possibleActions = ActionGenerator.PossibleActions(_gameInstance, null, true, true); var chosenAction = possibleActions[Generator.Random.Next(possibleActions.Count)]; if (chosenAction.Type == UctActionType.EndTurn) { break; } ActionEvaluator.FNoCopy(_gameInstance, chosenAction); } while (!_gameInstance.IsFinished); }
public void FastPlayTurn(GameEventHub eventHub) { var uct = new UctAlgorithm(_thinkTime, _expoExplo); var result = uct.UctSearch(_gameInstance); foreach (var action in result.Actions) { Debug.Assert(action.Type != UctActionType.EndTurn, "node.Action.Type != UctActionType.EndTurn"); ActionEvaluator.FNoCopy(_gameInstance, action); } ExponentialMovingAverage.Instance.Average(result.MillisecondsPerIteration); LogActions(result); }
public void IsFinishedFastAutoUpdateTest() { var game = new GameInstance(3); var a1 = game.AddAbilityWithInfo(new AbilityInfo(5, 1, 5, 0)); var m1 = game.AddMobWithInfo(new MobInfo(TeamColor.Red, 1, 10, 0, new[] { a1 })); var m2 = game.AddMobWithInfo(new MobInfo(TeamColor.Blue, 1, 10, 0, new[] { a1 })); game.PrepareEverything(); Assert.IsFalse(game.IsFinished); ActionEvaluator.FNoCopy(game, UctAction.AbilityUseAction(a1, m1, m2)); Assert.IsTrue(game.IsFinished); }
public void FastPlayTurn(GameEventHub eventHub) { do { var action = ActionGenerator.RuleBasedAction(_gameInstance); if (action.Type == UctActionType.EndTurn) { break; } ActionEvaluator.FNoCopy(_gameInstance, action); if (action.Type == UctActionType.DefensiveMove) { break; } } while (!_gameInstance.IsFinished); }
public void DefaultPolicyTest() { var game = new GameInstance(3); var ability1 = new AbilityInfo(1, 1, 1, 0); var a1 = game.AddAbilityWithInfo(ability1); var ability2 = new AbilityInfo(3, 1, 1, 0); var a2 = game.AddAbilityWithInfo(ability2); var abilities1 = new List <int>(); var abilities2 = new List <int> { a1, a2 }; var info1 = new MobInfo(TeamColor.Red, 5, 1, 0, abilities1); var info2 = new MobInfo(TeamColor.Blue, 5, 1, 1, abilities2); game.AddMobWithInfo(info1); game.AddMobWithInfo(info2); game.PrepareEverything(); Assert.IsFalse(game.IsFinished); var uct = new UctAlgorithm(100); var result = UctAlgorithm.DefaultPolicy(game, TeamColor.Red); Assert.AreEqual(0, result); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); Assert.AreEqual(TeamColor.Blue, game.CurrentTeam); var bestAction = ActionGenerator.DefaultPolicyAction(game); Console.WriteLine($"Best: {bestAction}"); var node = uct.UctSearch(game); Console.WriteLine(node); }
/// <summary> /// Runs a playout with the given encounter defined by a DNA pair and both controllers. /// </summary> public static int Playout(GameInstance game, DNA d1, DNA d2, IMobController c1, IMobController c2) { GameSetup.OverrideGameDna(game, d1, d2); game.AssignAiControllers(c1, c2); int iterations = Constants.MaxPlayoutEvaluationIterations; var hub = new GameEventHub(game); while (!game.IsFinished && iterations-- > 0) { game.CurrentController.FastPlayTurn(hub); ActionEvaluator.FNoCopy(game, UctAction.EndTurnAction()); } if (Constants.GetLogBuffer().ToString().Length != 0) { Console.WriteLine(Constants.GetLogBuffer()); } Constants.ResetLogBuffer(); return(Constants.MaxPlayoutEvaluationIterations - iterations); }