public MultiMoves CalculateTakeTerritoriesMoves(List <TerritoryIDType> territoriesToTake, MultiMoves precondition) { MultiMoves resultMoves = precondition.Clone(); List <TerritoryIDType> territoriesToTakeCopy = new List <TerritoryIDType>(territoriesToTake); while (territoriesToTakeCopy.Count > 0) { var reachableTerritories = FilterNonBorderingTerritories(territoriesToTakeCopy, resultMoves); if (reachableTerritories.Count == 0) { return(null); } var bestStartTerritory = GetBestAttackingTerritory(reachableTerritories, resultMoves); var bestAttackTerritory = GetBestAttackTerritory(reachableTerritories, territoriesToTakeCopy, bestStartTerritory, resultMoves); int neededAttackArmies = AttackInformer.GetNeededBreakArmies (resultMoves.GetTerritoryStandingsAfterAllMoves()[bestAttackTerritory].NumArmies.ArmiesOrZero); GameOrderAttackTransfer attackOrder = GameOrderAttackTransfer.Create (GameState.MyPlayerId, bestStartTerritory, bestAttackTerritory, AttackTransferEnum.AttackTransfer, new Armies(neededAttackArmies), REASON); var standing = resultMoves.GetTerritoryStandingsAfterAllMoves().Where(o => o.Key == attackOrder.From).First().Value; int leftoverArmies = standing.NumArmies.ArmiesOrZero - standing.ArmiesMarkedAsUsed.ArmiesOrZero - 1; int armiesToPump = Math.Max(0, attackOrder.NumArmies.ArmiesOrZero - leftoverArmies); bool successfull = resultMoves.PumpArmies(attackOrder.From, armiesToPump, REASON); if (!successfull) { return(null); } resultMoves.AddAttackOrder(attackOrder); territoriesToTakeCopy.Remove(bestAttackTerritory); } return(resultMoves); }
public MultiMoves CalculateMoveArmiesToBorderMoves(MultiMoves presentMoves) { MultiMoves result = presentMoves.Clone(); var nonOwnedTerritories = MapInformer.GetNonOwnedTerritories(result.GetTerritoryStandingsAfterAllMoves().Values.ToList(), GameState.MyPlayerId); var keys = new List <TerritoryIDType>(); nonOwnedTerritories.ForEach(k => keys.Add(k.ID)); var distances = MapInformer.GetDistancesFromTerritories(keys); foreach (TerritoryIDType territoryId in distances.Keys) { int distance = distances[territoryId]; if (distance <= 1) { continue; } var neighbors = MapInformer.GetNeighborTerritories(territoryId); var lowestDistanceNeighborValue = neighbors.Min(c => distances[c]); var lowestDistanceNeighbor = neighbors.Where(n => distances[n] == lowestDistanceNeighborValue).First(); TerritoryStanding theTerritory = result.GetTerritoryStandingsAfterAllMoves()[territoryId]; int armiesAvailable = theTerritory.NumArmies.ArmiesOrZero - theTerritory.ArmiesMarkedAsUsed.ArmiesOrZero - 1; if (armiesAvailable == 0) { continue; } GameOrderAttackTransfer attackMove = GameOrderAttackTransfer.Create (GameState.MyPlayerId, territoryId, lowestDistanceNeighbor, AttackTransferEnum.AttackTransfer, new Armies(armiesAvailable), REASON); result.AddAttackOrder(attackMove); } return(result); }
public void AddAttackOrder(GameOrderAttackTransfer attackOrder) { standingCache = null; var alreadyPresentAttackMove = AttackMoves.Where(a => a.From == attackOrder.From && a.To == attackOrder.To).FirstOrDefault(); if (alreadyPresentAttackMove == null) { AttackMoves.Add(attackOrder); } else { alreadyPresentAttackMove.NumArmies = new Armies(alreadyPresentAttackMove.NumArmies.ArmiesOrZero + attackOrder.NumArmies.ArmiesOrZero); } }
private int GetClassification(GameOrderAttackTransfer attackMove) { var initialState = GameState.CurrentTurn().LatestTurnStanding.Territories; bool opponentAttack = initialState[attackMove.To].OwnerPlayerID == GameState.OpponentPlayerId; var attackFromNeighbors = MapInformer.GetNeighborTerritories(initialState[attackMove.From].ID); var opponentTerritories = MapInformer.GetOwnedTerritories(initialState.Values.ToList(), GameState.OpponentPlayerId); var opponentNeighboringAttack = false; foreach (var opponentTerritory in opponentTerritories) { if (attackFromNeighbors.Contains(opponentTerritory.ID)) { opponentNeighboringAttack = true; } } bool clearOpponentBreak = false; int opponentIncome = GameState.CurrentTurn().Incomes[GameState.OpponentPlayerId].FreeArmies; int maxOpponentArmies = 0; if (opponentAttack) { maxOpponentArmies = initialState[attackMove.To].NumArmies.ArmiesOrZero + opponentIncome; int maxNeededArmies = AttackInformer.GetNeededBreakArmies(maxOpponentArmies); if (attackMove.NumArmies.ArmiesOrZero >= maxNeededArmies) { clearOpponentBreak = true; } } bool isTransfer = initialState[attackMove.To].OwnerPlayerID == GameState.MyPlayerId; bool isExpansion = initialState[attackMove.To].IsNeutral; if (clearOpponentBreak) { return(1); } if (isTransfer) { return(2); } if (isExpansion && !opponentNeighboringAttack) { return(3); } if (isExpansion && opponentNeighboringAttack) { return(4); } // non clear opponent attacks return(5); }
private GameOrderAttackTransfer GetBiggestAttackMove(MultiMoves movesSoFar) { if (movesSoFar.AttackMoves.Count() == 0) { return(null); } GameOrderAttackTransfer biggestAttack = movesSoFar.AttackMoves.First(); foreach (GameOrderAttackTransfer attackMove in movesSoFar.AttackMoves) { if (attackMove.NumArmies.ArmiesOrZero > biggestAttack.NumArmies.ArmiesOrZero) { biggestAttack = attackMove; } } return(biggestAttack); }
public MultiMoves CalculateNoPlanMoves(MultiMoves presentMoves) { MultiMoves resultMoves = presentMoves.Clone(); // we currently assume the biggest attack has to start from an owned territory GameOrderAttackTransfer biggestAttack = GetBiggestAttackMove(resultMoves); int stillAvailableDeployment = GameState.CurrentTurn().GetMyIncome() - resultMoves.GetCurrentDeployment(); if (biggestAttack != null) { PumpBiggestAttack(resultMoves, biggestAttack, stillAvailableDeployment); } else { AddBorderTerritoryDeployment(resultMoves, stillAvailableDeployment); } return(resultMoves); }
private void AddAttack(TerritoryIDType from, TerritoryIDType to, AttackTransferEnum attackTransfer, int numArmies, bool attackTeammates) { IEnumerable <GameOrderAttackTransfer> attacks = Orders.OfType <GameOrderAttackTransfer>(); var existingFrom = attacks.Where(o => o.From == from).ToList(); var existingFromTo = existingFrom.Where(o => o.To == to).ToList(); if (existingFromTo.Any()) { existingFromTo.Single().NumArmies = existingFromTo.Single().NumArmies.Add(new Armies(numArmies)); } else { var specials = Standing.Territories[from].NumArmies.SpecialUnits; if (specials.Length > 0) { var used = existingFrom.SelectMany(o => o.NumArmies.SpecialUnits).Select(o => o.ID).ToHashSet(false); specials = specials.Where(o => used.Contains(o.ID) == false).ToArray(); } AddOrder(GameOrderAttackTransfer.Create(this.PlayerID, from, to, attackTransfer, false, new Armies(numArmies, false, specials), attackTeammates)); } }
// Returns an already calculated attack path from an owned territory to a territory in the path to which we want to pump extra deployment. private List <GameOrderAttackTransfer> GetPumpPath(TerritoryIDType territoryToPumpTo) { // we can't pump from transfer moves GameStanding gameStanding = GameState.CurrentTurn().LatestTurnStanding; List <TerritoryIDType> ownedTerritories = gameStanding.Territories.Values.Where(o => o.OwnerPlayerID == GameState.MyPlayerId).Select(o => o.ID).ToList(); var attackMoves = AttackMoves.Where(o => !ownedTerritories.Contains(o.To)).ToList(); List <GameOrderAttackTransfer> pumpPath = new List <GameOrderAttackTransfer>(); TerritoryIDType currentPumpToTerritory = territoryToPumpTo; while (true) { if (ownedTerritories.Contains(currentPumpToTerritory)) { break; } GameOrderAttackTransfer pumpOrder = attackMoves.Find(o => o.To == currentPumpToTerritory); pumpPath.Insert(0, pumpOrder); currentPumpToTerritory = pumpOrder.From; } return(pumpPath); }
private void PumpBiggestAttack(MultiMoves movesSoFar, GameOrderAttackTransfer biggestAttack, int availableDeployment) { if (availableDeployment == 0) { return; } movesSoFar.AddDeployOrder(GameOrderDeploy.Create(GameState.MyPlayerId, availableDeployment, biggestAttack.From, REASON)); var endAttack = biggestAttack; bool foundStep = true; while (foundStep) { foundStep = false; // probably endless loop possible as soon as we add transfer moves back to attacking territory var nextAttack = movesSoFar.AttackMoves.Where(a => a.From == endAttack.To).FirstOrDefault(); if (nextAttack != null) { endAttack = nextAttack; foundStep = true; } } movesSoFar.PumpArmies(endAttack.To, availableDeployment, REASON); }
public void AddAttack(TerritoryIDType from, TerritoryIDType to, AttackTransferEnum attackTransfer, int numArmies, bool attackTeammates, bool byPercent = false, bool bosses = false, bool commanders = false) { Assert.Fatal(Bot.Map.Territories[from].ConnectedTo.ContainsKey(to), from + " does not connect to " + to); var actualArmies = numArmies; var actualByPercent = byPercent; if (actualByPercent && Bot.Settings.AllowPercentageAttacks == false) { actualByPercent = false; actualArmies = 1000000; } var actualMode = attackTransfer; if (actualMode == AttackTransferEnum.Transfer && Bot.Settings.AllowTransferOnly == false) { actualMode = AttackTransferEnum.AttackTransfer; } if (actualMode == AttackTransferEnum.Attack && Bot.Settings.AllowAttackOnly == false) { actualMode = AttackTransferEnum.AttackTransfer; } IEnumerable <GameOrderAttackTransfer> attacks = Orders.OfType <GameOrderAttackTransfer>(); var existingFrom = attacks.Where(o => o.From == from).ToList(); var existingFromTo = existingFrom.Where(o => o.To == to).ToList(); if (existingFromTo.Any()) { var existing = existingFromTo.Single(); existing.ByPercent = actualByPercent; existing.AttackTransfer = actualMode; existing.NumArmies = existing.NumArmies.Add(new Armies(actualArmies)); if (actualByPercent && existing.NumArmies.NumArmies > 100) { existing.NumArmies = existing.NumArmies.Subtract(new Armies(existing.NumArmies.NumArmies - 100)); } } else { var specials = Bot.Standing.Territories[from].NumArmies.SpecialUnits; if (specials.Length > 0) { var used = existingFrom.SelectMany(o => o.NumArmies.SpecialUnits).Select(o => o.ID).ToHashSet(false); specials = specials.Where(o => used.Contains(o.ID) == false).ToArray(); if (bosses == false) { specials = specials.Where(o => o.IsBoss() == false).ToArray(); } if (commanders == false) { specials = specials.Where(o => !(o is Commander)).ToArray(); } } AddOrder(GameOrderAttackTransfer.Create(Bot.PlayerID, from, to, actualMode, actualByPercent, new Armies(actualArmies, specials), attackTeammates)); } }
private GameOrder Convert(BotOrderAttackTransfer o) { return(GameOrderAttackTransfer.Create(o.PlayerID, o.From.ID, o.To.ID, AttackTransferEnum.AttackTransfer, false, o.Armies, false)); }
public UtilizeSpareArmies(GameOrderAttackTransfer order, int available) { Order = order; Available = available; }
private static GameOrder Convert(BotOrderAttackTransfer o) { return(GameOrderAttackTransfer.Create(o.PlayerID, o.FromTerritory.ID, o.ToTerritory.ID, AttackTransferEnum.AttackTransfer, false, new Armies(o.Armies), false)); }