/// <summary> /// Runs the commander away from opponents /// </summary> private static void DoCommander(BotMain bot, TerritoryStanding cmdrTerritory, Commander cmdr) { var directive = CommanderDirective(bot, cmdrTerritory.ID); if (directive.HasValue) { AILog.Log("SpecialUnits", "Directive directs us to move the commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(directive.Value)); if (directive.Value != cmdrTerritory.ID) { bot.Orders.AddAttack(cmdrTerritory.ID, directive.Value, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies, false, commanders: true); } bot.AvoidTerritories.Add(cmdrTerritory.ID); //add this so we don't deploy there, we want the commander to stay alone return; } var powerDiff = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys .Select(o => bot.Standing.Territories[o]) .Where(o => bot.IsOpponent(o.OwnerPlayerID) && o.NumArmies.Fogged == false) .Sum(o => o.NumArmies.AttackPower) - cmdrTerritory.NumArmies.DefensePower; var toDeploy = Math.Max(0, powerDiff); if (powerDiff > 0) { if (bot.UseRandomness) { toDeploy = SharedUtility.Round(toDeploy * RandomUtility.BellRandom(0.5, 1.5)); } if (toDeploy > bot.MakeOrders.IncomeTracker.RemainingUndeployed) { toDeploy = bot.MakeOrders.IncomeTracker.RemainingUndeployed; } if (toDeploy > 0 && bot.Orders.TryDeploy(cmdrTerritory.ID, toDeploy)) { AILog.Log("SpecialUnits", "Deployed " + toDeploy + " to defend commander"); } } //Consider this territory and all adjacent territories. Which is the furthest from any enemy? var terrDistances = bot.Map.Territories[cmdrTerritory.ID].ConnectedTo.Keys.ConcatOne(cmdrTerritory.ID) .Where(o => bot.Standing.Territories[o].OwnerPlayerID == bot.PlayerID || bot.Standing.Territories[o].NumArmies.DefensePower <= 4) //don't go somewhere that's defended heavily .ToDictionary(o => o, o => bot.DistanceFromEnemy(o)); AILog.Log("SpecialUnits", "Commander run options: " + terrDistances.Select(o => bot.TerrString(o.Key) + " dist=" + o.Value).JoinStrings(", ")); var sorted = terrDistances.OrderByDescending(o => o.Value).ToList(); sorted.RemoveWhere(o => o.Value < sorted[0].Value); var runTo = bot.UseRandomness ? sorted.Random().Key : sorted[0].Key; if (runTo == cmdrTerritory.ID) { return; //already there } AILog.Log("SpecialUnits", "Moving commander from " + bot.TerrString(cmdrTerritory.ID) + " to " + bot.TerrString(runTo)); bot.Orders.AddAttack(cmdrTerritory.ID, runTo, AttackTransferEnum.AttackTransfer, cmdrTerritory.NumArmies.NumArmies + toDeploy, false, commanders: true); }
public static void PrintTerritoryValues(BotMap map, BotMain BotState) { AILog.Log("Territory attack values:"); foreach (BotTerritory territory in map.Territories.Values) { if (territory.IsVisible && BotState.IsOpponent(territory.OwnerPlayerID)) { AILog.Log(territory.Details.Name + ": " + territory.AttackTerritoryValue); } } AILog.Log("Territory expansion values:"); foreach (BotTerritory territory in map.Territories.Values) { if (territory.IsVisible && territory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) { AILog.Log(territory.Details.Name + ": " + territory.ExpansionTerritoryValue); } } AILog.Log("Territory defend values:"); foreach (BotTerritory territory in map.Territories.Values) { if (territory.OwnerPlayerID == BotState.Me.ID && territory.GetOpponentNeighbors().Count > 0) { AILog.Log(territory.Details.Name + ": " + territory.DefenceTerritoryValue); } } }
private void DeleteBadAttacks(Moves movesSoFar) { var interestingAttacks = new List <BotOrderAttackTransfer>(); foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>()) { if (atm.Armies.AttackPower > 1 && BotState.IsOpponent(atm.To.OwnerPlayerID)) { var isInteresting = false; var attackTerritory = atm.To.IncomingMoves[0].From; foreach (var incomingMove in atm.To.IncomingMoves) { if (incomingMove.From != attackTerritory) { isInteresting = true; } } if (isInteresting) { interestingAttacks.Add(atm); } } } var territoriesWithInterestingAttacks = new HashSet <BotTerritory>(); foreach (BotOrderAttackTransfer atm_1 in interestingAttacks) { territoriesWithInterestingAttacks.Add(atm_1.From); } }
private static bool PlayBombCard(BotMain bot, CardInstance card) { var allBombableEnemyTerritories = bot.Standing.Territories.Values .Where(o => o.OwnerPlayerID == bot.PlayerID) .SelectMany(o => bot.Map.Territories[o.ID].ConnectedTo.Keys) .Distinct() .Select(o => bot.Standing.Territories[o]) .Where(o => bot.IsOpponent(o.OwnerPlayerID) && o.NumArmies.Fogged == false) .ToList(); var minArmies = !bot.UseRandomness ? bot.BaseIncome.Total * 2 : SharedUtility.Round(bot.BaseIncome.Total * RandomUtility.BellRandom(1, 3)); var weights = allBombableEnemyTerritories.Where(o => o.NumArmies.NumArmies > minArmies).ToDictionary(o => o.ID, o => o.NumArmies.NumArmies - minArmies); if (weights.Count == 0) { return(false); } var bomb = bot.UseRandomness ? RandomUtility.WeightedRandom(weights.Keys, o => weights[o]) : weights.OrderByDescending(o => o.Value).First().Key; AILog.Log("PlayCards", "Bombing " + bot.TerrString(bomb)); bot.Orders.AddOrder(GameOrderPlayCardBomb.Create(card.ID, bot.PlayerID, bomb)); return(true); }
public static Moves CalculateMoveIdleArmiesTask(BotMain state) { var outvar = new Moves(); foreach (var ownedTerritory in state.VisibleMap.GetOwnedTerritories()) { var outgoingMoves = ownedTerritory.OutgoingMoves; BotOrderAttackTransfer mostImportantMove = null; var currentHighestValue = -1; foreach (var atm in outgoingMoves) { if (state.IsOpponent(atm.To.OwnerPlayerID) && atm.Armies.AttackPower > 1 && atm.Message != AttackMessage.TryoutAttack) { var attackValue = atm.To.AttackTerritoryValue; if (attackValue > currentHighestValue) { currentHighestValue = attackValue; mostImportantMove = atm; } } } var idleArmies = ownedTerritory.GetIdleArmies(); if (mostImportantMove != null && idleArmies.IsEmpty == false) { var atm_1 = new BotOrderAttackTransfer(state.Me.ID, ownedTerritory, mostImportantMove.To, ownedTerritory.GetIdleArmies(), "MoveIdleArmiesTask1"); outvar.AddOrder(atm_1); } } return(outvar); }
private static void HasSeenOpponent(BotMain state) { foreach (BotTerritory terr in state.VisibleMap.Territories.Values) { if (state.IsOpponent(terr.OwnerPlayerID)) { hasSeenOpponent = true; return; } } hasSeenOpponent = false; }
public static Moves CalculateNoPlanAttackBestTerritoryTask(BotMain state, int maxDeployment) { var outvar = new Moves(); // If true attacks are possible then go with them // If true attacks are possible then go with them var sortedOpponentTerritories = state.TerritoryValueCalculator.GetSortedAttackValueTerritories(); var territoriesToAttack = NoPlanBreakBestTerritoryTask.RemoveTerritoriesThatWeTook (state, sortedOpponentTerritories); foreach (var territory in territoriesToAttack) { if (territory.IsVisible) { var attackTerritoryMoves = AttackTerritoryTask.CalculateAttackTerritoryTask(state, territory, maxDeployment); if (attackTerritoryMoves != null) { return(attackTerritoryMoves); } // If we can't truly attack then attack with 1's var allowedSmallAttacks = territory.Armies.NumArmies - state.MustStandGuardOneOrZero; allowedSmallAttacks -= GetAlreadyPresentSmallAttacks(territory); foreach (var ownedNeighbor in territory.GetOwnedNeighbors()) { if (allowedSmallAttacks > 0 && ownedNeighbor.GetIdleArmies().NumArmies > 0 && !IsTerritoryAlreadySmallAttackedFromOurTerritory(ownedNeighbor, territory)) { var alreadyAttacksOpponent = false; foreach (var atm in ownedNeighbor.OutgoingMoves) { if (atm.Armies.AttackPower > 1 && state.IsOpponent(atm.To.OwnerPlayerID)) { alreadyAttacksOpponent = true; } } if (!alreadyAttacksOpponent) { var atm_1 = new BotOrderAttackTransfer(state.Me.ID, ownedNeighbor, territory, new Armies(1), "NoPlanAttackBestTerritoryTask"); outvar.AddOrder(atm_1); allowedSmallAttacks--; } } } if (outvar.Orders.OfType <BotOrderAttackTransfer>().Any()) { return(outvar); } } } // If absolutely no attack possible then return null return(null); }
private static bool IsRiskyAttackPresent(BotMain state, Moves movesSoFar) { foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>()) { if (state.IsOpponent(atm.To.OwnerPlayerID)) { var attackingArmies = atm.Armies; var maxOpponentArmies = atm.To.Armies.Add(new Armies(state.GetGuessedOpponentIncome(atm.To.OwnerPlayerID, state.VisibleMap))); if (attackingArmies.AttackPower > 1 && attackingArmies.AttackPower * state.Settings.OffensiveKillRate <= maxOpponentArmies.DefensePower * state.Settings.DefensiveKillRate) { return(true); } } } return(false); }
private int GetCounteredTerritories(BotBonus bonus, PlayerIDType playerID) { var outvar = 0; foreach (var territory in bonus.Territories) { if (territory.GetOpponentNeighbors().Count > 0 && playerID == BotState.Me.ID) { outvar++; } else if (territory.GetOwnedNeighbors().Count > 0 && BotState.IsOpponent(playerID)) { outvar++; } } return(outvar); }
private static bool PlayDiplomacyCard(BotMain bot, CardInstance card) { var canDip = bot.Players.Values.Where(o => o.State == GamePlayerState.Playing && //only diplomacy people in the game bot.IsOpponent(o.ID) && //only diplomacy opponents bot.Orders.Orders.Concat(bot.Standing.ActiveCards.Select(z => (GameOrder)z.Card)).OfType <GameOrderPlayCardDiplomacy>().None(z => z.AffectsPlayer(o.ID) && z.AffectsPlayer(bot.PlayerID)) //don't diplomacy someone we're already in diplomacy with, or that we already played a diplomacy card on this turn ).ToList(); if (canDip.Count == 0) { return(false); } var dip = bot.UseRandomness ? RandomUtility.WeightedRandom(canDip, o => bot.WeightedNeighbors[o.ID]) : canDip.OrderByDescending(o => bot.WeightedNeighbors[o.ID]).First(); AILog.Log("PlayCards", "Playing a diplomacy card between myself and " + dip); bot.Orders.AddOrder(GameOrderPlayCardDiplomacy.Create(card.ID, bot.PlayerID, bot.PlayerID, dip.ID)); return(true); }
private List <PossibleAttack> WeightAttacks() { //build all possible attacks List <PossibleAttack> ret = Bot.Standing.Territories.Values .Where(o => o.OwnerPlayerID == Bot.PlayerID && !Bot.AvoidTerritories.Contains(o.ID)) .SelectMany(us => Bot.Map.Territories[us.ID].ConnectedTo.Keys .Select(k => Bot.Standing.Territories[k]) .Where(k => Bot.IsOpponent(k.OwnerPlayerID) && !Bot.AvoidTerritories.Contains(k.ID)) .Select(k => new PossibleAttack(Bot, us.ID, k.ID))).ToList(); foreach (PossibleAttack a in ret) { a.Weight(Bot.WeightedNeighbors); } NormalizeWeights(ret); return(ret); }
private static int CalculateAmountOfSafeMoves(BotMain state, Moves movesSoFar) { var outvar = 0; foreach (var atm in movesSoFar.Orders.OfType <BotOrderAttackTransfer>()) { if (atm.Armies.AttackPower <= 1 || state.IsOpponent(atm.To.OwnerPlayerID)) { outvar++; } else { var maxOpponentArmies = atm.To.Armies.Add(new Armies(state.GetGuessedOpponentIncome(atm.To.OwnerPlayerID, state.VisibleMap))); var attackingArmies = atm.Armies; if (attackingArmies.AttackPower * state.Settings.OffensiveKillRate > maxOpponentArmies.DefensePower * state.Settings.DefensiveKillRate) { outvar++; } } } return(outvar); }
public List <BotTerritory> GetSortedAttackValueTerritories() { var outvar = new List <BotTerritory>(); var opponentTerritories = BotState.VisibleMap.Territories.Values.Where(o => BotState.IsOpponent(o.OwnerPlayerID)).ToList(); var copy = new List <BotTerritory>(); copy.AddRange(opponentTerritories); while (!copy.IsEmpty()) { var maxAttackValue = 0; var maxAttackValueTerritory = copy[0]; foreach (var territory in copy) { if (territory.AttackTerritoryValue > maxAttackValue) { maxAttackValue = territory.AttackTerritoryValue; maxAttackValueTerritory = territory; } } copy.Remove(maxAttackValueTerritory); outvar.Add(maxAttackValueTerritory); } return(outvar); }
private static void DoBoss(BotMain bot, TerritoryStanding terr, SpecialUnit su) { AILog.Log("SpecialUnits", "Considering boss " + su.ID + " on " + bot.TerrString(terr.ID)); var routes = bot.Directives.Where(o => o.StartsWith("BossRoute ")).Select(o => new BossRoute(o, bot)).ToList(); var routeNexts = routes.Select(o => new { Route = o, Terr = o.NextTerr(terr.ID) }).Where(o => o.Terr.HasValue).ToList(); if (routeNexts.Count > 0) { var routeNext = routeNexts.WeightedRandom(o => o.Route.Weight); AILog.Log("SpecialUnits", routeNexts.Count + " matching routes: " + routeNexts.Select(o => o.Route.Name).JoinStrings(", ") + ", selected " + routeNext.Route); if (RandomUtility.RandomPercentage() > routeNext.Route.Chance) { AILog.Log("SpecialUnits", "Skipping boss route to " + routeNext.Terr.Value + " due to failed random chance. "); } else { AILog.Log("SpecialUnits", "Moving boss along route to " + bot.TerrString(routeNext.Terr.Value) + ". "); bot.Orders.AddAttack(terr.ID, routeNext.Terr.Value, AttackTransferEnum.AttackTransfer, 0, true, bosses: true); bot.AvoidTerritories.Add(routeNext.Terr.Value); return; } } else if (routes.Count > 0) { //Move towards the nearest route territory. If there's a tie, take the one that's furthest along in that route var terrRoutes = routes.SelectMany(r => r.Route.Select((t, i) => new { Route = r, Terr = t, Index = i })) .GroupBy(o => o.Terr) .Select(o => o.MaxSelectorOrDefault(r => r.Index)) .ToDictionary(o => o.Terr, o => o); var visited = new HashSet <TerritoryIDType>(); visited.Add(terr.ID); while (true) { var visit = visited.SelectMany(o => bot.Map.Territories[o].ConnectedTo.Keys).ToHashSet(false); if (visit.Count == 0) { throw new Exception("Never found route territory"); } var visitOnRoute = visit.Where(o => terrRoutes.ContainsKey(o)).ToList(); if (visitOnRoute.Count > 0) { var final = visitOnRoute.Select(o => terrRoutes[o]).MaxSelectorOrDefault(o => o.Index); if (RandomUtility.RandomPercentage() > final.Route.Chance) { AILog.Log("SpecialUnits", "Skipping moving boss to route due to failed random check: " + final.Route); break; } else { var move = FindPath.TryFindShortestPath(bot, terr.ID, t => t == final.Terr); AILog.Log("SpecialUnits", "Moving boss to get back to route. Moving to " + bot.TerrString(move[0]) + " to get to " + bot.TerrString(final.Terr) + " index=" + final.Index + " " + final.Route); bot.Orders.AddAttack(terr.ID, move[0], AttackTransferEnum.AttackTransfer, 0, true, bosses: true); bot.AvoidTerritories.Add(final.Terr); return; } } visited.AddRange(visit); } } var attackCandidates = bot.Map.Territories[terr.ID].ConnectedTo.Keys.Select(o => bot.Standing.Territories[o]) .Where(o => !bot.IsTeammateOrUs(o.OwnerPlayerID) && o.NumArmies.DefensePower < 300 && !bot.AvoidTerritories.Contains(o.ID)) .ToList(); if (attackCandidates.Count > 0) { var ranks = attackCandidates.ToDictionary(o => o.ID, ts => { if (bot.IsOpponent(ts.OwnerPlayerID)) { return(bot.Players[ts.OwnerPlayerID].IsAI ? 3 : 2); //prefer human player } else if (ts.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) { return(1); } else { throw new Exception("Unexpected owner " + ts.OwnerPlayerID); } }); var max = ranks.Values.Max(); var to = ranks.Where(o => o.Value == max).Random().Key; AILog.Log("SpecialUnits", "Normal boss move to " + bot.TerrString(to)); bot.Orders.AddAttack(terr.ID, to, AttackTransferEnum.AttackTransfer, 0, false, bosses: true); bot.AvoidTerritories.Add(to); } else { //Surrounded by ourself or teammates. Move towards enemy var move = bot.MoveTowardsNearestBorderNonNeutralThenNeutral(terr.ID); if (move.HasValue) { AILog.Log("SpecialUnits", "Landlocked boss move to " + bot.TerrString(move.Value)); bot.Orders.AddAttack(terr.ID, move.Value, AttackTransferEnum.AttackTransfer, 0, false, bosses: true); } } }
private void FillMoveTypes(List <BotOrder> unhandledMoves, BotMap movesMap) { foreach (var atm in unhandledMoves.OfType <BotOrderAttackTransfer>()) { var mmToTerritory = movesMap.Territories[atm.To.ID]; var mmFromTerritory = movesMap.Territories[atm.From.ID]; if (atm.Message == AttackMessage.EarlyAttack) { EarlyAttacks.Add(atm); } else { // Opponent attack moves if (BotState.IsOpponent(mmToTerritory.OwnerPlayerID)) { if (atm.Armies.AttackPower == 1) { DelayAttackMoves.Add(atm); } else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && GetSlipperyOpponentTerritoryNumber(atm.To) > -1 && IsProbablyCrushingMove(atm)) { CrushingAttackMovesToSlipperyTerritories.Add(atm); } else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && IsAlwaysGoodAttackMove(atm)) { SafeAttackMovesWithGoodAttack.Add(atm); } else if (!CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From) && !IsAlwaysGoodAttackMove(atm)) { SafeAttackMovesWithPossibleBadAttack.Add(atm); } else if (CanOpponentAttackTerritory(mmToTerritory.OwnerPlayerID, atm.From)) { RiskyAttackMoves.Add(atm); } } else if (mmToTerritory.OwnerPlayerID == BotState.Me.ID) // Transfer moves { if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanOpponentBreakTerritory(mmToTerritory)) { SupportMovesWhereOpponentMightBreak.Add(atm); } else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanOpponentGetAGoodAttack(mmToTerritory)) { SupportMovesWhereOpponentMightGetAGoodAttack.Add(atm); } else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && CanAnyOpponentAttackTerritory(mmToTerritory)) { SupportMovesWhereOpponentMightAttack.Add(atm); } else if (mmToTerritory.GetOpponentNeighbors().Count > 0 && !CanAnyOpponentAttackTerritory(mmToTerritory)) { NormalSupportMoves.Add(atm); } else if (mmToTerritory.GetOpponentNeighbors().Count == 0) { TransferMoves.Add(atm); } } else if (mmToTerritory.OwnerPlayerID == TerritoryStanding.NeutralPlayerID) // Expansion moves { if (atm.Message == AttackMessage.Snipe) { SnipeMoves.Add(atm); } else if (Math.Round(atm.Armies.AttackPower * BotState.Settings.OffensiveKillRate) < mmToTerritory.Armies.DefensePower) { TransferingExpansionMoves.Add(atm); } else if (atm.Armies.AttackPower > 3 && !CanAnyOpponentAttackTerritory(mmFromTerritory)) { BigExpansionMovesNonAttack.Add(atm); } else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count == 0 && !CanAnyOpponentAttackTerritory(mmFromTerritory)) { NonOpponentBorderingSmallExpansionMovesNonAttack.Add(atm); } else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count > 0 && !CanAnyOpponentAttackTerritory(mmFromTerritory)) { OpponentBorderingSmallExpansionMovesNonAttack.Add(atm); } else if (atm.Armies.AttackPower > 3 && CanAnyOpponentAttackTerritory(mmFromTerritory)) { BigExpansionMovesWithAttack.Add(atm); } else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count == 0 && CanAnyOpponentAttackTerritory(mmFromTerritory)) { NonOpponentBorderingSmallExpansionMovesWithAttack.Add(atm); } else if (atm.Armies.AttackPower <= 3 && mmToTerritory.GetOpponentNeighbors().Count > 0 && CanAnyOpponentAttackTerritory(mmFromTerritory)) { OpponentBorderingSmallExpansionMovesWithAttack.Add(atm); } } } } }
private static bool PlayBlockadeCard(BotMain bot, CardInstance card) { //Look for bonuses that we can't hold and should blockade foreach (var bonus in bot.Map.Bonuses.Values) { var grouped = bonus.Territories.GroupBy(o => bot.Standing.Territories[o].OwnerPlayerID).ToDictionary(o => o.Key, o => o); if (!grouped.ContainsKey(bot.PlayerID)) { continue; //we're not in it } if (grouped.ContainsKey(TerritoryStanding.NeutralPlayerID)) { continue; //only complete bonuses -- if it's never been taken, don't blockade } var opps = grouped.Keys.Where(o => bot.IsOpponent(o)).ToList(); if (opps.Count == 0) { continue; //no opponents in it } if (bonus.Territories.Any(t => bot.AvoidTerritories.Contains(t))) { continue; //already doing something here, perhaps already blockading it. } var oppTerrs = opps.SelectMany(o => grouped[o].ToList()).ToHashSet(false); var friendlyTerrs = grouped.Where(o => bot.IsTeammateOrUs(o.Key)).SelectMany(o => o.Value.ToList()).ToList(); var friendlyArmies = friendlyTerrs.Sum(o => bot.Standing.Territories[o].NumArmies.DefensePower); var enemyArmies = oppTerrs.Sum(o => ExpansionHelper.GuessNumberOfArmies(bot, o).AttackPower); var ratio = bot.UseRandomness ? RandomUtility.BellRandom(1, 3) : 2; if (friendlyArmies * ratio > enemyArmies) { continue; } var armies = SharedUtility.Round(bot.EffectiveIncome.FreeArmies * (bot.UseRandomness ? RandomUtility.BellRandom(.1, .4) : .25)); if (armies < 5) { armies = 5; } var canBlockade = friendlyTerrs.Where(o => bot.Standing.Territories[o].OwnerPlayerID == bot.PlayerID && bot.Map.Territories[o].ConnectedTo.Keys.None(t => oppTerrs.Contains(t)) && bot.Standing.Territories[o].NumArmies.SpecialUnits.Length == 0 && bot.Standing.Territories[o].NumArmies.NumArmies < armies * 2 ).ToList(); if (canBlockade.Count == 0) { continue; } var blockade = bot.UseRandomness ? canBlockade.Random() : canBlockade.First(); var deploy = Math.Max(0, armies - bot.Standing.Territories[blockade].NumArmies.NumArmies); if (!bot.Orders.TryDeploy(blockade, deploy)) { continue; } AILog.Log("PlayCards", "Blockading " + bot.TerrString(blockade) + " with " + armies + " (had to deploy " + deploy + ")"); bot.Orders.AddOrder(GameOrderPlayCardBlockade.Create(card.ID, bot.PlayerID, blockade)); bot.AvoidTerritories.Add(blockade); return(true); } return(false); }
private static bool PlaySanctionsCard(BotMain bot, CardInstance card) { var canSanction = bot.Players.Values.Where(o => o.State == GamePlayerState.Playing && bot.IsOpponent(o.ID)).Select(o => o.ID).ToList(); if (canSanction.Count == 0) { return(false); } var sanction = bot.UseRandomness ? RandomUtility.WeightedRandom(canSanction, o => bot.WeightedNeighbors[o]) : canSanction.OrderByDescending(o => bot.WeightedNeighbors[o]).First(); AILog.Log("PlayCards", "Sanctioning " + sanction); bot.Orders.AddOrder(GameOrderPlayCardSanctions.Create(card.ID, bot.PlayerID, sanction)); return(true); }
private void CalculateNoPlanBreakDefendMoves(Moves moves, bool lowImportance, bool mediumImportance, bool highImportance, BotTerritory.DeploymentType lowerConservative, BotTerritory.DeploymentType upperConservative) { List <BotTerritory> territoriesToDefend = new List <BotTerritory>(); foreach (var territory in BotState.VisibleMap.GetOwnedTerritories()) { var importance = territory.DefenceTerritoryValue; var lowImportant = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var highImportant = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE; if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant)) { territoriesToDefend.Add(territory); } } var possibleTerritoriesToAttack = new List <BotTerritory>(); foreach (var opponentTerritory in BotState.VisibleMap.Territories.Values.Where(o => o.IsVisible && BotState.IsOpponent(o.OwnerPlayerID))) { var wmOpponentTerritory = BotState.WorkingMap.Territories[opponentTerritory.ID]; if (BotState.IsOpponent(wmOpponentTerritory.OwnerPlayerID)) { possibleTerritoriesToAttack.Add(opponentTerritory); } } var territoriesToAttack = new List <BotTerritory>(); foreach (var territory_1 in possibleTerritoriesToAttack) { var importance = territory_1.AttackTerritoryValue; var lowImportant = importance < TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var mediumImportant = importance < TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE && importance >= TerritoryValueCalculator.LOWEST_MEDIUM_PRIORITY_VALUE; var highImportant = importance >= TerritoryValueCalculator.LOWEST_HIGH_PRIORITY_VALUE; if ((lowImportance && lowImportant) || (mediumImportance && mediumImportant) || (highImportance && highImportant)) { territoriesToAttack.Add(territory_1); } } var combinedTerritories = new List <BotTerritory>(); combinedTerritories.AddRange(territoriesToDefend); combinedTerritories.AddRange(territoriesToAttack); var sortedTerritories = BotState.TerritoryValueCalculator.SortTerritoriesAttackDefense(combinedTerritories); foreach (var territory_2 in sortedTerritories) { var maxDeployment = BotState.MyIncome.Total - moves.GetTotalDeployment(); Moves defendBreakMoves = null; if (territory_2.OwnerPlayerID == BotState.Me.ID) { defendBreakMoves = BotState.DefendTerritoryTask.CalculateDefendTerritoryTask(territory_2, maxDeployment, true, lowerConservative, upperConservative); } else { defendBreakMoves = BotState.BreakTerritoryTask.CalculateBreakTerritoryTask(territory_2, maxDeployment, lowerConservative, upperConservative, "CalculateNoPlanBreakDefendMoves"); } if (defendBreakMoves != null) { MovesCommitter.CommittMoves(BotState, defendBreakMoves); moves.MergeMoves(defendBreakMoves); } } }