protected void AddArmyAttackVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, int restUnits) { List<IslandCM> enemyNeibourIslands = Library.Map.GetEnemyNeibourIslands(context.map, player.ID, true); float maxAttackVP = 0; IslandCM maxVPenemyIsland = null; for (int i = 0; i < enemyNeibourIslands.Count; ++i) { IslandCM enemyIsland = enemyNeibourIslands[i]; float vp = Library.Map.GetIslandPriceVP(context.map, enemyIsland.ID, player.ID, options); if (vp > maxAttackVP) { maxAttackVP = vp; maxVPenemyIsland = enemyIsland; } } if (maxAttackVP > 0) { int needForce = Library.Map.GetForceNeedToCapture(context.map, maxVPenemyIsland.ID, options.coefficients.MinProbToAttackIsland); int needGold = Library.Common.CostOfArmy(needForce, context.turn.TurnActionCounter) + Constants.moveArmyCost; if (needForce <= restUnits && needGold <= player.Gold) { List<IslandCM> ourIslands = context.map.GetBridgetIslands(maxVPenemyIsland.ID, player.ID); int islandFromID = ourIslands.First().ID; AIArmyAttackVariant attackVariant = new AIArmyAttackVariant(islandFromID, maxVPenemyIsland.ID, needForce, needForce); attackVariant.offer = new VariantOffer(needGold, maxAttackVP); variants.AddVariant(attackVariant); } } }
private static VariantOffer CheckBuildAndMoveNavy(Context context, PlayerInfoCM player, AIOptions options, int restOfGold) { VariantOfferPackage package = new VariantOfferPackage(); int restUnits = Math.Min(Constants.maxArmyCount - context.map.Navy.Where(e => e.OwnerID == player.ID).Count(), Constants.armyPrices.Count); if (restUnits < 1) return null; List<IslandCM> enemyNeibourIslands = Library.Map.GetEnemyNeibourIslands(context.map, player.ID, false); float maxNeedBridgeVP = 0; for (int i = 0; i < enemyNeibourIslands.Count; ++i) { IslandCM enemyIsland = enemyNeibourIslands[i]; float vp = Library.Map.GetIslandPriceVP(context.map, enemyIsland.ID, player.ID, options) * options.coefficients.BridgeToIslandPriceCoeff; if (vp > maxNeedBridgeVP) maxNeedBridgeVP = vp; } if (maxNeedBridgeVP > 0) package.Add(new VariantOffer(0, maxNeedBridgeVP)); if (Library.Map.GetAccessibleSeaHorns(context.map, player.ID, false, false).Count > 0) package.Add(new VariantOffer(Constants.moveNavyCost + Constants.navyPrices[1], options.coefficients.HornVPT * options.turnsToEnd)); return package.GetSum(); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { AIVariant variant = new AIVariant(); AddPlaceHornTurn(variant, context, playerID); AddEndPlayerTurn(variant, context, playerID); return new AIVariantPackage(variant); }
protected void AddArmyVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options) { int restUnits = Math.Min(Constants.maxArmyCount - context.map.Army.Where(e => e.OwnerID == player.ID).Count(), Constants.armyPrices.Count - context.turn.TurnActionCounter); if (restUnits < 1) return; AddArmyAttackVariant(variants, context, player, options, restUnits); AddArmyDefenceVariant(variants, context, player, options, restUnits); }
private static VariantOffer CheckNeedBuild(Context context, PlayerInfoCM player, AIOptions options, int restOfGold) { VariantOfferPackage package = new VariantOfferPackage(); package.Add(AuctionCommon.CheckNeedBuild(context, player, options, Build.Poseidon, restOfGold)); package.CheckAll(options); return package.GetAvg(); }
public virtual AIVariant GetTheBestVariant(IChooseStrategy strategy, AIOptions options) { if (variants.Count == 0) throw new Exception("AI: no variants"); if (variants.Count == 1) return variants[0]; return strategy.Choose(variants, options); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { PlayerRule turn; if (context.armyFight != null) turn = new ArmyFight(); else turn = new NavyFight(); return new AIVariantPackage(new AIVariant(turn)); }
public static VariantOffer CheckNeedBuild(Context context, PlayerInfoCM player, AIOptions options, Build build, int restOfGold) { if (restOfGold < Cyclades.Constants.buildingCost) return null; if (!Library.Map.HasPlayerPlaceForBuilding(context.map, player.ID)) return null; bool isNeed = Library.Map.IsNeedBuild(context.map, player.ID, build); return new VariantOffer(Cyclades.Constants.buildingCost, (isNeed ? options.coefficients.NeedBuildVP : options.coefficients.NotNeedBuildVP)); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { AIVariantPackage variants = new AIVariantPackage(); PlayerInfoCM player = context.players.GetPlayer(playerID); AddBuyBuildVariant(variants, context, player, options); AddArmyVariant(variants, context, player, options); AddEndPlayerTurnVariant(variants); return variants; }
private static VariantOffer CheckNeedBuild(Context context, PlayerInfoCM player, AIOptions options, int restOfGold) { VariantOfferPackage package = new VariantOfferPackage(); package.Add(AuctionCommon.CheckNeedBuild(context, player, options, Build.Zeus, restOfGold)); if (restOfGold >= Cyclades.Constants.buildingCost) package.Add(new VariantOffer(Cyclades.Constants.buildingCost, options.coefficients.TempleVPT * options.turnsToEnd)); package.CheckAll(options); return package.GetAvg(); }
protected void AddNavyAttackIslandVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, int restUnits) { List<IslandCM> enemyNeibourIslands = Library.Map.GetEnemyNeibourIslands(context.map, player.ID, false); float maxAttackVP = 0; IslandCM maxVPenemyIsland = null; for (int i = 0; i < enemyNeibourIslands.Count; ++i) { IslandCM enemyIsland = enemyNeibourIslands[i]; float vp = Library.Map.GetIslandPriceVP(context.map, enemyIsland.ID, player.ID, options) * options.coefficients.BridgeToIslandPriceCoeff; if (vp > maxAttackVP) { maxAttackVP = vp; maxVPenemyIsland = enemyIsland; } } if (maxAttackVP > 0) { int needForce = 1; int needGold = Library.Common.CostOfNavy(needForce, context.turn.TurnActionCounter); if (needForce <= restUnits && needGold <= player.Gold) { List<IslandCM> neibourIslands = Library.Map.GetNeibourIslands(context.map, maxVPenemyIsland.ID); List<Hex> seas = context.map.GetSeasNearIsland(maxVPenemyIsland.ID); Hex h = null; for (int i = 0; i < neibourIslands.Count && h == null; ++i) { IslandCM island = neibourIslands[i]; if (island.OwnerID != player.ID) continue; List<Hex> ourSeas = context.map.GetSeasNearIsland(island.ID); List<Hex> cells = seas.Intersect(ourSeas).ToList(); for(int t = 0; t < cells.Count; ++t) { if (context.map.GetNavyCountByCell(cells[t]) == 0) { h = cells[t]; break; } } } if (h != null) { AIBuyNavyVariant attackVariant = new AIBuyNavyVariant(h); attackVariant.offer = new VariantOffer(needGold, maxAttackVP); variants.AddVariant(attackVariant); } } } }
public static void AddVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options) { AuctionCM.Bet maxBet = context.auction.GetMaxBetForGod(God.Appolon); int bet = (maxBet == null ? 1 : maxBet.bet + 1); AIAuctionVariant variant = new AIAuctionVariant(God.Appolon, bet); float vp = 0f; vp += options.coefficients.GoldVP * (context.map.GetIslandsByOwner(player.ID).Count > 1 ? Constants.apolloSmallIncome : Constants.apolloBigIncome); if (bet == 1) vp += options.coefficients.HornVPT * options.turnsToEnd; variant.offer = new VariantOffer(0, vp); variants.AddVariant(variant); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { if (context.turn.TurnActionCounter == 0) return new AIVariantPackage(new AIVariant(new Cyclades.BuyPriest())); AIVariantPackage variants = new AIVariantPackage(); PlayerInfoCM player = context.players.GetPlayer(playerID); AddBuyBuildVariant(variants, context, player, options); AddBuyPriestVariant(variants, context, player, options); AddEndPlayerTurnVariant(variants); return variants; }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { PlayerRule turn; if (forBuilds) { IslandCM island = AI.Library.Map.GetTheBestIslandForBuild(context.map, playerID, metro: true); turn = new PlaceMetro4Buildings(island.ID, new List<SlotAddr>()); } else { IslandCM island = AI.Library.Map.GetTheBestIslandForBuild(context.map, playerID, metro: true); turn = new PlaceMetro4Philosopher(island.ID); } return new AIVariantPackage(new AIVariant(turn)); }
public AIVariant Choose(List<AIVariant> variants, AIOptions options) { VariantOfferPackage packadge = new VariantOfferPackage(); for (int i = 0; i < variants.Count; ++i) { if (variants[i] != null && variants[i].offer != null) packadge.Add(variants[i].offer); } packadge.CheckAll(options); VariantOffer theBestOffer = packadge.GetTheBestOne(options); if (theBestOffer == null) throw new Exception("AI: No variants to choose"); return variants.Where(e => e.offer == theBestOffer).First(); }
protected void AddBuyPriestVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options) { if (context.turn.TurnActionCounter >= Constants.priestPrices.Count) return; int cost = Constants.priestPrices[context.turn.TurnActionCounter]; if (cost > player.Gold) return; AIVariant variant = new AIVariant(new Cyclades.BuyPriest()); VariantOffer offer = new VariantOffer(cost, options.coefficients.PriestVPT * options.turnsToEnd); variant.offer = offer; variants.AddVariant(variant); }
protected bool CheckGodVariant(God god, AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, out int minBetGold) { minBetGold = 0; if (!context.auction.GodsOrder.Contains(god)) return false; if (!context.auction.GodPossibleToBet(player.ID, god)) return false; AuctionCM.Bet maxBet = context.auction.GetMaxBetForGod(god); minBetGold = AuctionCM.GoldForBet(player, (maxBet == null ? 1 : maxBet.bet + 1)); if (minBetGold > player.Gold) return false; return true; }
public static void AddVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, int minBetGold) { AIAuctionVariant variant = new AIAuctionVariant(God.Poseidon, minBetGold + player.Priests); int restOfGold = player.Gold - minBetGold; VariantOfferPackage offers = new VariantOfferPackage(); offers.Add(CheckNeedBuild(context, player, options, restOfGold)); offers.Add(CheckBuildAndMoveNavy(context, player, options, restOfGold)); offers.CheckAll(options); VariantOffer offer = offers.GetTheBestSumWithCostLimit(restOfGold); offer.cost += minBetGold; variant.offer = offer; variants.AddVariant(variant); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { AIVariantPackage variants = new AIVariantPackage(); PlayerInfoCM player = context.players.GetPlayer(playerID); if (context.State == "MoveNavy") { AddMoveNavyVariant(variants, context, player, options); } else { AddBuyBuildVariant(variants, context, player, options); AddNavyVariant(variants, context, player, options); AddEndPlayerTurnVariant(variants); } return variants; }
private static VariantOffer CheckPhilosopher(Context context, PlayerInfoCM player, AIOptions options, int restOfGold) { VariantOfferPackage package = new VariantOfferPackage(); for (int i = 0; i < Cyclades.Constants.philosopherPrices.Count; ++i) { int cost = Cyclades.Constants.philosopherPrices[i]; if (cost > restOfGold) break; package.Add(new VariantOffer(cost, options.coefficients.PhilosopherVP)); restOfGold -= cost; } package.CheckAll(options); return package.GetSum(); }
public override AIVariantPackage GetVariants(Context context, int playerID, AIOptions options) { AIVariantPackage variants = new AIVariantPackage(); PlayerInfoCM player = context.players.GetPlayer(playerID); int minBetGold; if (CheckGodVariant(God.Zeus, variants, context, player, options, out minBetGold)) AuctionZeus.AddVariant(variants, context, player, options, minBetGold); if (CheckGodVariant(God.Sophia, variants, context, player, options, out minBetGold)) AuctionSophia.AddVariant(variants, context, player, options, minBetGold); if (CheckGodVariant(God.Poseidon, variants, context, player, options, out minBetGold)) AuctionPoseidon.AddVariant(variants, context, player, options, minBetGold); if (CheckGodVariant(God.Mars, variants, context, player, options, out minBetGold)) AuctionMars.AddVariant(variants, context, player, options, minBetGold); AuctionApollo.AddVariant(variants, context, player, options); return variants; }
protected IChooseStrategy GetAIChooseStrategy(Context context, AIOptions options) { return new AIChooseStrategy(); }
protected void AddMoveNavyVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options) { variants.AddVariant(new AIVariant(new StopMoveNavy())); }
protected void AddArmyDefenceVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, int restUnits) { }
public bool CheckOffer(AIOptions options) { return cost * options.coefficients.GoldVP <= vp; }
abstract public AIVariantPackage GetVariants(Context context, int playerID, AIOptions options);
public VariantOffer GetTheBestOne(AIOptions options) { return offers.OrderByDescending(e => e.vp - e.cost * options.coefficients.GoldVP).FirstOrDefault(); }
public void CheckAll(AIOptions options) { offers.RemoveAll(e => e == null || !e.CheckOffer(options)); }
protected void AddNavyAttackHornVariant(AIVariantPackage variants, Context context, PlayerInfoCM player, AIOptions options, int restUnits) { Hex horn = Library.Map.GetAccessibleSeaHorns(context.map, player.ID, false, false).FirstOrDefault(); if (horn == null) return; int needForce = 1; int needGold = Library.Common.CostOfArmy(needForce, context.turn.TurnActionCounter) + Constants.moveNavyCost; float vp = options.coefficients.HornVPT * options.turnsToEnd; if (needForce <= restUnits && needGold <= restUnits) { List<Hex> ourCoasts = context.map.GetAllPlayerCoast(player.ID); List<Hex> path = Library.Map.GetSeaPathToAnyPoint(context.map, player.ID, horn, ourCoasts); if (path != null && path.Count > 0) { AINavyAttackVariant attackVariant = new AINavyAttackVariant(path, needForce, needForce); attackVariant.offer = new VariantOffer(needGold, vp); variants.AddVariant(attackVariant); } } }