public void StateDeepCopyTest() { var game = new GameInstance(3); var ability = new AbilityInfo(3, 1, 1, 0); var abilityId = game.AddAbilityWithInfo(ability); var abilities1 = new List <int>(); var abilities2 = new List <int> { abilityId }; var info1 = new MobInfo(TeamColor.Red, 5, 1, 0, abilities1); var info2 = new MobInfo(TeamColor.Blue, 5, 1, 1, abilities2); var m1 = game.AddMobWithInfo(info1); var m2 = game.AddMobWithInfo(info2); game.PrepareEverything(); var copy = game.CopyStateOnly(); TestHelpers.GameInstancesEqual(game, copy); var copy2 = copy.CopyStateOnly(); ActionEvaluator.F(copy2, UctAction.AbilityUseAction(abilityId, m1, m2)); TestHelpers.GameInstancesEqual(game, copy); TestHelpers.MobManagersEqual(game.MobManager, copy2.MobManager); TestHelpers.MapsEqual(game.Map, copy2.Map); }
/// <summary> /// Returns a list of best possible actions until the end of a turn. /// </summary> private List <UctAction> SelectBestActions(UctNode root) { var result = new List <UctAction>(); UctNode current = root; do { if (current.Children.Count == 0) { break; } UctNode max = current.Children.FastMax(c => c.Q / c.N); if (max.Q / max.N < 0.2) { var state = current.State.CopyStateOnly(); do { var action = ActionGenerator.RuleBasedAction(state); state = ActionEvaluator.F(state, action); if (action.Type == UctActionType.EndTurn) { goto done; } else { result.Add(action); if (action.Type == UctActionType.DefensiveMove) { goto done; } } } while (true); } if (max.Action.Type != UctActionType.EndTurn) { if (max.IsTerminal) { //Console.WriteLine("Found terminal"); } result.Add(max.Action); } current = max; } while (current.Action.Type != UctActionType.EndTurn); done: return(result); }
/// <summary> /// Expands a given node, adding a new possible state. /// </summary> /// <param name="node"></param> /// <returns></returns> public static UctNode Expand(UctNode node) { var type = node.Action.Type; var allowMove = type != UctActionType.Move && type != UctActionType.DefensiveMove; node.PrecomputePossibleActions(allowMove, true || type != UctActionType.EndTurn); var action = node.PossibleActions[node.Children.Count]; var child = new UctNode(0, 0, action, ActionEvaluator.F(node.State, action)); child.Parent = node; node.Children.Add(child); return(child); }
public static UctNode FromAction(GameInstance game, UctAction action) { return(new UctNode(action, ActionEvaluator.F(game, action))); }
/// <summary> /// Generates possible attack move actions. /// </summary> public static void GenerateAttackMoveActions(GameInstance state, CachedMob mob, List <UctAction> result) { var mobInfo = mob.MobInfo; var mobInstance = mob.MobInstance; foreach (var enemyId in state.MobManager.Mobs) { var target = state.CachedMob(enemyId); if (!GameInvariants.IsTargetableNoSource(state, mob, target)) { continue; } AxialCoord myCoord = mobInstance.Coord; AxialCoord?closestCoord = null; int? distance = null; int? chosenAbilityId = null; foreach (var coord in state.Map.EmptyCoords) { if (!state.Map.IsVisible(coord, target.MobInstance.Coord)) { continue; } var possibleMoveAction = GameInvariants.CanMoveTo(state, mob, coord); if (possibleMoveAction.Type == UctActionType.Null) { continue; } Debug.Assert(possibleMoveAction.Type == UctActionType.Move); foreach (var abilityId in mobInfo.Abilities) { if (!GameInvariants.IsAbilityUsableFrom(state, mob, coord, target, abilityId)) { continue; } int myDistance = state.Pathfinder.Distance(myCoord, coord); if (!closestCoord.HasValue) { chosenAbilityId = abilityId; closestCoord = coord; distance = myDistance; } else if (distance.Value > myDistance) { chosenAbilityId = abilityId; closestCoord = coord; distance = myDistance; } } } if (closestCoord.HasValue) { if (Constants.AttackMoveEnabled) { var action = UctAction.AttackMoveAction(mob.MobId, closestCoord.Value, chosenAbilityId.Value, target.MobId); var after = ActionEvaluator.F(state, action.ToPureMove()); GameInvariants.AssertValidAbilityUseAction(after, action.ToPureAbilityUse()); GameInvariants.AssertValidAction(state, action); result.Add(action); } else { var action = UctAction.MoveAction(mob.MobId, closestCoord.Value); GameInvariants.AssertValidAction(state, action); result.Add(action); } } } }
public static float PlayoutAction(GameInstance game, UctAction action, TeamColor startingTeam) { return(DefaultPolicy(ActionEvaluator.F(game, action), startingTeam)); }