/// <summary> /// Returns 0 if it is an ememy, and a positive number otherwise indicating how many turns away from an enemy it is /// </summary> /// <param name="terrID"></param> /// <returns></returns> public int DistanceFromEnemy(TerritoryIDType terrID) { if (IsTeammateOrUs(Standing.Territories[terrID].OwnerPlayerID) == false) { return(0); } var terrIDs = new HashSet <TerritoryIDType>(); terrIDs.Add(terrID); var distance = 1; while (true) { var toAdd = terrIDs.SelectMany(o => Map.Territories[o].ConnectedTo.Keys).Except(terrIDs).ToList(); if (toAdd.Count == 0) { return(int.MaxValue); //no enemies found on the entire map } if (toAdd.Any(o => Standing.Territories[o].IsNeutral == false && IsTeammateOrUs(Standing.Territories[o].OwnerPlayerID) == false)) { break; //found an enemy } terrIDs.AddRange(toAdd); distance++; } return(distance); }
public BotTerritory(CowzowBot bot, TerritoryIDType id) { this.Bot = bot; this.ID = id; this.OwnerPlayerID = TerritoryStanding.FogPlayerID; this.Armies = 0; }
public void Deploy(TerritoryIDType terr, int armies, bool force = false) { if (!TryDeploy(terr, armies, force)) { throw new Exception("Deploy failed. Territory=" + terr + ", armies=" + armies + ", us=" + Bot.PlayerID + ", Income=" + Bot.EffectiveIncome.ToString() + ", IncomeTrakcer=" + Bot.MakeOrders.IncomeTracker.ToString()); } }
public TerritoryIDType?MoveTowardsNearestBorder(TerritoryIDType id, bool neutralOk) { var neighborDistances = new KeyValueList <TerritoryIDType, int>(); foreach (var immediateNeighbor in Map.Territories[id].ConnectedTo.Keys) { var nearestBorder = FindNearestBorder(immediateNeighbor, id, neutralOk); if (nearestBorder != null) { neighborDistances.Add(immediateNeighbor, nearestBorder.Depth); } } if (neighborDistances.Count == 0) { return(null); } var ret = neighborDistances.GetKey(0); int minValue = neighborDistances.GetValue(0); for (int i = 1; i < neighborDistances.Count; i++) { if (neighborDistances.GetValue(i) < minValue) { ret = neighborDistances.GetKey(i); minValue = neighborDistances.GetValue(i); } } return(ret); }
private TerritoryIDType?MoveTowardsNearestBorder(TerritoryIDType id) { var neighborDistances = new List <KeyValuePair <TerritoryIDType, int> >(); foreach (var immediateNeighbor in Map.Territories[id].ConnectedTo) { FindNearestBorderResult nearestBorder = FindNearestBorder(immediateNeighbor, new Nullable <TerritoryIDType>(id)); if (nearestBorder != null) { neighborDistances.Add(new KeyValuePair <TerritoryIDType, int>(immediateNeighbor, nearestBorder.Depth)); } } if (neighborDistances.Count == 0) { return(new Nullable <TerritoryIDType>()); } var ret = neighborDistances[0].Key; int minValue = neighborDistances[0].Value; for (int i = 1; i < neighborDistances.Count; i++) { if (neighborDistances[i].Value < minValue) { ret = neighborDistances[i].Key; minValue = neighborDistances[i].Value; } } return(new Nullable <TerritoryIDType>(ret)); }
/// <summary> /// Estimate how many turns it would take us to complete the bonus, assuming we start in the passed territory and can use full deployment every turn /// </summary> /// <param name="bonusID"></param> /// <param name="bonusPath"></param> /// <returns></returns> private static CaptureTerritories TurnsToTake(BotMain bot, TerritoryIDType terrID, BonusIDType bonusID, BonusPath path) { var bonus = bot.Map.Bonuses[bonusID]; var terrsToTake = bonus.Territories.ExceptOne(terrID).ToHashSet(true); return(CaptureTerritories.TryFindTurnsToTake(bot, path, bot.Settings.InitialPlayerArmiesPerTerritory, bot.Settings.MinimumArmyBonus, terrsToTake, o => o.OwnerPlayerID == TerritoryStanding.AvailableForDistribution ? bot.Settings.InitialNeutralsInDistribution : o.NumArmies.DefensePower)); }
public bool TryDeploy(TerritoryIDType terrID, int armies, bool force = false) { if (!force && Bot.AvoidTerritories.Contains(terrID)) { return(false); } Assert.Fatal(Bot.Standing.Territories[terrID].OwnerPlayerID == Bot.PlayerID, "Not owned"); if (armies == 0) { return(true); //just pretend like we did it } Assert.Fatal(armies > 0); if (!Bot.MakeOrders.IncomeTracker.TryRecordUsedArmies(terrID, armies)) { return(false); } var existing = Orders.OfType <GameOrderDeploy>().FirstOrDefault(o => o.DeployOn == terrID); if (existing != null) { existing.NumArmies += armies; } else { AddOrder(GameOrderDeploy.Create(Bot.PlayerID, armies, terrID)); } return(true); }
private static float GetExpansionWeight(BotMain bot, TerritoryIDType terrID) { var td = bot.Map.Territories[terrID]; var bonusPaths = td.PartOfBonuses .Where(o => bot.BonusValue(o) > 0) .Select(o => BonusPath.TryCreate(bot, o, ts => ts.ID == terrID)) .Where(o => o != null) .ToDictionary(o => o.BonusID, o => o); var turnsToTake = bonusPaths.Keys.ToDictionary(o => o, o => TurnsToTake(bot, td.ID, o, bonusPaths[o])); foreach (var cannotTake in turnsToTake.Where(o => o.Value == null).ToList()) { turnsToTake.Remove(cannotTake.Key); bonusPaths.Remove(cannotTake.Key); } var bonusWeights = bonusPaths.Keys.ToDictionary(o => o, o => ExpansionHelper.WeighBonus(bot, o, ts => ts.ID == terrID, turnsToTake[o].NumTurns)); var weight = 0.0f; weight += ExpansionHelper.WeighMultipleBonuses(td.PartOfBonuses.Where(o => bonusWeights.ContainsKey(o)).ToDictionary(o => o, o => bonusWeights[o])); AILog.Log("PickTerritories", "Expansion weight for terr " + bot.TerrString(terrID) + " is " + weight + ". " + td.PartOfBonuses.Select(b => "Bonus " + bot.BonusString(b) + " Weight=" + (bonusWeights.ContainsKey(b) ? bonusWeights[b] : 0) + " TurnsToTake=" + (turnsToTake.ContainsKey(b) ? turnsToTake[b].ToString() : "") + " Path=" + (bonusPaths.ContainsKey(b) ? bonusPaths[b].ToString() : "")).JoinStrings(", ")); return(weight); }
private void Deploy(TerritoryIDType terr, int armies) { if (!TryDeploy(terr, armies)) { throw new Exception("Deploy failed. Territory=" + terr + ", armies=" + armies + ", us=" + PlayerID + ", Income=" + Income.ToString() + ", IncomeTrakcer=" + IncomeTracker.ToString()); } }
public BotTerritory(BotMap parent, TerritoryIDType id, PlayerIDType playerID, Armies armies) { this.Parent = parent; this.ID = id; this.OwnerPlayerID = playerID; this.Armies = armies; }
public EdgeHashSet GetOrders(TerritoryIDType r) { if (Orders.ContainsKey(r)) { return(Orders[r]); } return(new EdgeHashSet()); }
public PathNode(BotTerritory terr) { territory = terr.ID; minPath = new List <TerritoryIDType>(); adjacent = new List <TerritoryIDType>(); minDistance = int.MaxValue; SetAdjacentTerrId(terr); }
private int GetNonOwnedNeighborTerritoryCount (TerritoryIDType territory, List <TerritoryIDType> territoryRange, Dictionary <TerritoryIDType, TerritoryStanding> territoryStandings) { var nonOwnedNeighborTerritories = MapInformer.GetNonOwnedNeighborTerritories(territory, territoryStandings).Keys.ToList(); nonOwnedNeighborTerritories.RemoveWhere(t => !territoryRange.Contains(t)); return(nonOwnedNeighborTerritories.Count()); }
public PossibleExpandTarget(BotMain bot, TerritoryIDType id, Dictionary <BonusIDType, PossibleExpandTargetBonus> bonuses) { this.Bot = bot; this.ID = id; this.Bonuses = bonuses; //Add a tie breaker 1 point if we're on the critical path to completing this bonus WeightFromCriticalPath = bonuses.Values.Count(o => o.Path.TerritoriesOnCriticalPath.Contains(ID)); }
public static List <TerritoryIDType> GetNeighborTerritories(TerritoryIDType territory) { MapDetails map = GameState.Map; List <TerritoryDetails> territoryDetails = map.Territories.Select(o => o.Value).ToList(); TerritoryDetails territoryInQuestion = territoryDetails.Where(o => o.ID == territory).First(); List <TerritoryIDType> connectedTerritoryIds = territoryInQuestion.ConnectedTo.Keys.ToList(); return(connectedTerritoryIds); }
public static GameOrderDeploy Create(int numArmies, PlayerIDType playerID, TerritoryIDType deployOn) { var o = new GameOrderDeploy(); o.NumArmies = numArmies; o.PlayerID = playerID; o.DeployOn = deployOn; return(o); }
/// <param name="id">: a Territory id number</param> /// <returns>: the matching Territory object</returns> public BotTerritory GetTerritory(TerritoryIDType id) { var result = Territories[id]; if (result == null) { throw new Exception("Could not find territory with id: " + id); } return(result); }
public static GameOrderDeploy Create(PlayerIDType playerID, int numArmies, TerritoryIDType deployOn, string reason) { var o = new GameOrderDeploy(); o.NumArmies = numArmies; o.PlayerID = playerID; o.DeployOn = deployOn; o.Reason = reason; return(o); }
public bool IsBorderTerritory(GameStanding standing, TerritoryIDType terrID) { var ts = standing.Territories[terrID]; if (ts.OwnerPlayerID != PlayerID) { return(false); } return(this.Map.Territories[terrID].ConnectedTo.Keys.Any(c => standing.Territories[c].OwnerPlayerID != this.PlayerID)); }
private MultiAttackPathToBonus(BotMain bot, TerritoryIDType startFrom, BonusIDType bonusID, int jumpsToGetToBonus, int armiesNeededToCapture, int armiesNeedToKillToGetThere, List <TerritoryIDType> pathToGetThere) { this.Bot = bot; this.StartFrom = startFrom; this.BonusID = bonusID; this.JumpsToGetToBonus = jumpsToGetToBonus; this.EstArmiesNeededToCapture = armiesNeededToCapture; this.ArmiesNeedToKillToGetThere = armiesNeedToKillToGetThere; this.PathToGetThere = pathToGetThere; }
public TerritoryIDType?MoveTowardsNearestBorderNonNeutralThenNeutral(TerritoryIDType terrID) { var move = this.MoveTowardsNearestBorder(terrID, false); if (!move.HasValue) { move = this.MoveTowardsNearestBorder(terrID, true); } return(move); }
public PathNode GetNode(TerritoryIDType terrId) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].territory == terrId) { return(nodes[i]); } } return(null); }
public bool Contains(TerritoryIDType terrId) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].territory == terrId) { return(true); } } return(false); }
private static TerritoryIDType?CommanderDirective(BotMain bot, TerritoryIDType commanderOn) { var directive = bot.Directives.SingleOrDefault(o => o.StartsWith("CommanderRunTo ")); if (directive == null) { return(null); } var runTo = (TerritoryIDType)int.Parse(directive.RemoveFromStartOfString("CommanderRunTo ")); return(FindPath.TryFindShortestPath(bot, commanderOn, t => t == runTo)[0]); }
public PathNode Remove(TerritoryIDType terrId) { for (int i = 0; i < nodes.Count; i++) { if (nodes[i].territory == terrId) { PathNode removedNode = nodes[i]; nodes.RemoveAt(i); return(removedNode); } } return(null); }
public static List <TerritoryIDType> ChooseRandom(List <TerritoryIDType> from, int amount) { List <TerritoryIDType> copy = new List <TerritoryIDType>(from); List <TerritoryIDType> result = new List <TerritoryIDType>(); for (int i = 0; i < amount; i++) { TerritoryIDType randomElement = copy.Random(); copy.Remove(randomElement); result.Add(randomElement); amount--; } return(result); }
private static int DistanceToTerrs(BotMain bot, TerritoryIDType startFrom, HashSet <TerritoryIDType> terrs, GameStanding standing, int maxDistance, out HashSet <TerritoryIDType> terrsWeEntered) { Assert.Fatal(terrs.Count > 0, "No terrs"); var visited = new HashSet <TerritoryIDType>(); visited.Add(startFrom); var contains = visited.Where(o => terrs.Contains(o)).ToHashSet(true); if (contains.Count > 0) { //We're already there terrsWeEntered = new HashSet <TerritoryIDType>(); return(0); } int distance = 1; while (true) { var expand = visited.SelectMany(o => bot.Map.Territories[o].ConnectedTo.Keys).Where(o => visited.Contains(o) == false && standing.Territories[o].OwnerPlayerID != bot.PlayerID).ToHashSet(false); if (expand.Count == 0) { terrsWeEntered = null; return(int.MaxValue); } contains = expand.Where(o => terrs.Contains(o)).ToHashSet(true); if (contains.Count > 0) { //Found it terrsWeEntered = contains; return(distance); } distance++; if (distance > maxDistance) { terrsWeEntered = null; return(int.MaxValue); } visited.AddRange(expand); } #if CS2HX || CSSCALA throw new Exception("Never"); #endif }
public TerritoryIDType?NextTerr(TerritoryIDType from) { for (int i = 0; i < Route.Count; i++) { if (Route[i] == from) { var next = i + 1 == Route.Count ? Route[0] : Route[i + 1]; //wrap around if (!Bot.Map.Territories[from].ConnectedTo.ContainsKey(next)) { return(null); } return(next); } } return(null); }
// Only yields one path in case there are multiple ones. Also take care in case of circles public List <GameOrderAttackTransfer> GetMovePath(TerritoryIDType attackedTerritory) { List <GameOrderAttackTransfer> movePath = new List <GameOrderAttackTransfer>(); var currentAttackTerritory = attackedTerritory; while (true) { var attackingMoves = AttackMoves.Where(a => a.To == currentAttackTerritory).ToList(); if (attackingMoves.Count == 0) { return(movePath); } else { currentAttackTerritory = attackingMoves.First().From; movePath.Add(attackingMoves.First()); } } }
/// <summary> /// Tells us how many armies of ours on our territory that we haven't committed to another action /// </summary> /// <param name="terrID"></param> /// <returns></returns> private int GetArmiesAvailable(TerritoryIDType terrID) { Assert.Fatal(Standing.Territories[terrID].OwnerPlayerID == PlayerID); int armies = Standing.Territories[terrID].NumArmies.NumArmies; IEnumerable <GameOrderDeploy> deploys = Orders.OfType <GameOrderDeploy>(); IEnumerable <GameOrderAttackTransfer> attacks = Orders.OfType <GameOrderAttackTransfer>(); //Add in armies we deployed armies += deploys.Where(o => o.DeployOn == terrID).Select(o => o.NumArmies).Sum(); //Subtract armies we've attacked with armies -= attacks.Where(o => o.From == terrID).Select(o => o.NumArmies.NumArmies).Sum(); //TODO: Cards (subtract airlift out's, return 0 if abandoning) //TODO: Subtract 1, since one must remain return(armies); }