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 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); }
// TODO returns no results private Dictionary <BonusIDType, BonusDetails> GetApplicableBonuses(MultiMoves presentMoves) { var territoryStandings = presentMoves.GetTerritoryStandingsAfterAllMoves(); Dictionary <BonusIDType, BonusDetails> allBonuses = GameState.Map.Bonuses; Dictionary <BonusIDType, BonusDetails> applicableBonuses = new Dictionary <BonusIDType, BonusDetails>(); Dictionary <BonusIDType, BonusDetails> ownedBonuses = MapInformer.GetOwnedBonuses(territoryStandings, GameState.MyPlayerId); foreach (BonusDetails bonus in allBonuses.Values) { if (ownedBonuses.Keys.Contains(bonus.ID)) { continue; } List <TerritoryIDType> bonusTerritoriesAndNeighbors = MapInformer.GetBonusTerritoriesAndNeighbors(bonus); foreach (var territoryId in bonusTerritoriesAndNeighbors) { if (territoryStandings[territoryId].OwnerPlayerID == GameState.MyPlayerId) { applicableBonuses.Add(bonus.ID, bonus); break; } } } return(applicableBonuses); }
private TerritoryIDType GetBestAttackingTerritory(List <TerritoryIDType> takeTargets, MultiMoves presentMoves) { var currentGameStandings = presentMoves.GetTerritoryStandingsAfterAllMoves(); var ownedTerritories = MapInformer.GetOwnedTerritories(currentGameStandings.Values.ToList(), GameState.MyPlayerId); var possibleStartTerritories = new List <TerritoryStanding>(); foreach (var ownedTerritory in ownedTerritories) { List <TerritoryIDType> neighbors = MapInformer.GetNeighborTerritories(ownedTerritory.ID); var matchingNeighbors = neighbors.Where(n => takeTargets.Contains(n)).ToList(); if (matchingNeighbors.Count > 0) { possibleStartTerritories.Add(ownedTerritory); } } var bestStartTerritory = possibleStartTerritories.First(); var beginTurnStandings = GameState.CurrentTurn().LatestTurnStanding.Territories; foreach (var testTerritory in possibleStartTerritories) { bool bestTerritoryOwnedByMyself = beginTurnStandings[bestStartTerritory.ID].OwnerPlayerID == GameState.MyPlayerId; bool testTerritoryOwnedByMyself = beginTurnStandings[testTerritory.ID].OwnerPlayerID == GameState.MyPlayerId; // if one of them has no neighbors to take prefer the other one bool bestTerritoryCanContinue = MapInformer.GetNeighborTerritories(bestStartTerritory.ID).Where(n => takeTargets.Contains(n)).Count() > 0; bool testTerritoryCanContinue = MapInformer.GetNeighborTerritories(testTerritory.ID).Where(n => takeTargets.Contains(n)).Count() > 0; if (testTerritoryCanContinue && !bestTerritoryCanContinue) { bestStartTerritory = testTerritory; } // if both are already owned by myself at the beginning of the round prefer the one with more armies on it else if (bestTerritoryOwnedByMyself && testTerritoryOwnedByMyself) { if (testTerritory.NumArmies.ArmiesOrZero > bestStartTerritory.NumArmies.ArmiesOrZero) { bestStartTerritory = testTerritory; } } // if only one of them is owned by myself at the beginning of the round prefer the one not owned else if (bestTerritoryOwnedByMyself && !testTerritoryOwnedByMyself) { bestStartTerritory = testTerritory; } // if both aren't owned by myself at the beginning of the round prefer the one with the longer attack path else if (!bestTerritoryOwnedByMyself && !testTerritoryOwnedByMyself) { var bestPathCount = presentMoves.GetMovePath(bestStartTerritory.ID).Count(); var testPathCount = presentMoves.GetMovePath(testTerritory.ID).Count(); if (testPathCount > bestPathCount) { bestStartTerritory = testTerritory; } } } return(bestStartTerritory.ID); }
private List <TerritoryIDType> GetMissingBonusTerritories(BonusDetails bonus, MultiMoves presentMoves) { var bonusTerritories = bonus.Territories; var currentStatus = presentMoves.GetTerritoryStandingsAfterAllMoves(); List <TerritoryIDType> territories = new List <TerritoryIDType>(); foreach (var bonusTerritory in bonusTerritories) { if (currentStatus[bonusTerritory].OwnerPlayerID != GameState.MyPlayerId) { territories.Add(bonusTerritory); } } return(territories); }
public List <MultiMoves> CalculateBreakBonusMultiTask(MultiMoves presentMoves) { List <MultiMoves> resultMoves = new List <MultiMoves>(); var opponentBonuses = MapInformer.GetOwnedBonuses(presentMoves.GetTerritoryStandingsAfterAllMoves(), GameState.OpponentPlayerId); foreach (var opponentBonus in opponentBonuses) { MultiMoves breakBonusMoves = GetBreakBonusMoves(opponentBonus.Key, presentMoves); if (breakBonusMoves != null) { resultMoves.Add(breakBonusMoves); } } return(resultMoves); }
private List <TerritoryIDType> GetNonOwnedBonusTerritoriesToTake(MultiMoves multiMoves) { // Choose an arbitrary territory with a non owned neighbor TerritoryIDType nonOwnedTerritory = new TerritoryIDType(); foreach (var territory in multiMoves.GetTerritoryStandingsAfterAllMoves().Values.Where(t => t.OwnerPlayerID == GameState.MyPlayerId)) { var nonOwnedNeighbors = MapInformer.GetNonOwnedNeighborTerritories(territory.ID, multiMoves.GetTerritoryStandingsAfterAllMoves()); if (nonOwnedNeighbors.Count > 0) { nonOwnedTerritory = nonOwnedNeighbors.First().Key; break; } } var bonus = MapInformer.GetBonus(nonOwnedTerritory); AILog.Log("Debug", "Attempting to take bonus: " + bonus.Name); var nonOwnedBonusTerritories = MapInformer.GetNonOwnedBonusTerritories(bonus, multiMoves.GetTerritoryStandingsAfterAllMoves()); return(nonOwnedBonusTerritories); }
private TerritoryIDType GetBestOwnTerritoryToMakeAttack(Dictionary <TerritoryIDType, TerritoryStanding> ownedNeighbors, TerritoryIDType territoryToTake, MultiMoves currentMoves) { TerritoryIDType bestNeighbor = ownedNeighbors.First().Key; foreach (TerritoryIDType territoryId in ownedNeighbors.Keys) { var attackMoves = currentMoves.AttackMoves.Where(o => o.From == bestNeighbor && o.To == territoryId).ToList(); if (attackMoves.Count > 0) { bestNeighbor = attackMoves.First().To; } } // if we have all neighbors already choose the one with the max armies var ownedTerritories = MapInformer.GetOwnedTerritories(GameState.CurrentTurn().LatestTurnStanding.Territories.Values.ToList(), GameState.MyPlayerId); bool allNeighborsOwnedAtStart = true; foreach (TerritoryIDType ownedNeighbor in ownedNeighbors.Keys) { if (ownedTerritories.Where(o => o.ID == ownedNeighbor).Count() == 0) { allNeighborsOwnedAtStart = false; break; } } if (allNeighborsOwnedAtStart) { var territoryStandings = currentMoves.GetTerritoryStandingsAfterAllMoves(); foreach (TerritoryIDType ownedNeighbor in ownedNeighbors.Keys) { if (territoryStandings[ownedNeighbor].NumArmies.ArmiesOrZero > territoryStandings[bestNeighbor].NumArmies.ArmiesOrZero) { bestNeighbor = ownedNeighbor; } } } return(bestNeighbor); }
private TerritoryIDType GetBestAttackTerritory(List <TerritoryIDType> immediateTakeTargets, List <TerritoryIDType> allTakeTargets, TerritoryIDType attackingTerritory, MultiMoves presentMoves) { List <TerritoryIDType> borderingTargets = immediateTakeTargets.Where(t => MapInformer.GetNeighborTerritories(t).Contains(attackingTerritory)).ToList(); // We prefer territories with a as little neighboring territories in the takeTargets as possible var bestAttackTerritory = borderingTargets.First(); foreach (var testAttackTerritory in borderingTargets) { var bestAttackTerritoryNeighborCount = MapInformer.GetNeighborTerritories(bestAttackTerritory).Where(t => allTakeTargets.Contains(t)).Count(); var testAttackTerritoryNeighborCount = MapInformer.GetNeighborTerritories(testAttackTerritory).Where(t => allTakeTargets.Contains(t)).Count(); if (testAttackTerritoryNeighborCount < bestAttackTerritoryNeighborCount) { bestAttackTerritory = testAttackTerritory; } else if (testAttackTerritoryNeighborCount == bestAttackTerritoryNeighborCount) { // If both have the same amount we prefer territories with as little unowned neighbors as possible var bestUnownedNeighborCount = MapInformer.GetNonOwnedNeighborTerritories(bestAttackTerritory, presentMoves.GetTerritoryStandingsAfterAllMoves()).Count(); var testUnownedNeighborCount = MapInformer.GetNonOwnedNeighborTerritories(testAttackTerritory, presentMoves.GetTerritoryStandingsAfterAllMoves()).Count(); if (testUnownedNeighborCount < bestUnownedNeighborCount) { bestAttackTerritory = testAttackTerritory; } } } return(bestAttackTerritory); }
private List <TerritoryIDType> FilterNonBorderingTerritories(List <TerritoryIDType> territoriesToTake, MultiMoves presentMoves) { var standings = presentMoves.GetTerritoryStandingsAfterAllMoves(); return(territoriesToTake.Where(t => MapInformer.GetOwnedNeighborTerritories(t, standings).Count > 0).ToList()); }
private MultiMoves GetBreakBonusMoves(BonusIDType opponentBonus, MultiMoves presentMoves) { var bonusTerritories = GameState.Map.Bonuses[opponentBonus].Territories; var distances = MapInformer.GetDistancesFromTerritories(bonusTerritories); var ownedBorderTerritories = MapInformer.GetOwnedBorderTerritories(presentMoves.GetTerritoryStandingsAfterAllMoves(), GameState.MyPlayerId); int minDistance = ownedBorderTerritories.Min(o => distances[o.ID]); var bestStartTerritory = ownedBorderTerritories.Where(o => distances[o.ID] == minDistance).First(); int currentDistance = minDistance; var currentTerritoryInAttackPath = bestStartTerritory.ID; List <TerritoryIDType> territoriesToTake = new List <TerritoryIDType>(); while (currentDistance != 0) { var neighbors = MapInformer.GetNeighborTerritories(currentTerritoryInAttackPath); var possibleAttackNeighbors = neighbors.Where(n => distances[n] == currentDistance - 1).ToList(); var bestNeighborToAttack = GetBestNeighborToAttack(possibleAttackNeighbors); territoriesToTake.Add(bestNeighborToAttack); currentTerritoryInAttackPath = bestNeighborToAttack; currentDistance--; } TakeTerritoriesTask takeTerritoriesTask = new TakeTerritoriesTask(REASON); MultiMoves resultMoves = takeTerritoriesTask.CalculateTakeTerritoriesMoves(territoriesToTake, presentMoves); return(resultMoves); }
private void AddBorderTerritoryDeployment(MultiMoves movesSoFar, int availableDeployment) { TerritoryStanding territoryToDeployTo = MapInformer.GetOwnedBorderTerritories(movesSoFar.GetTerritoryStandingsAfterAllMoves(), GameState.MyPlayerId).FirstOrDefault(); if (territoryToDeployTo == null) { territoryToDeployTo = MapInformer.GetOwnedTerritories(GameState.CurrentTurn().LatestTurnStanding.Territories.Values.ToList(), GameState.MyPlayerId).First(); } movesSoFar.AddDeployOrder(GameOrderDeploy.Create(GameState.MyPlayerId, availableDeployment, territoryToDeployTo.ID, REASON)); }