Class SimpleAI

java.lang.Object
net.sf.colossus.ai.AbstractAI
net.sf.colossus.ai.SimpleAI
All Implemented Interfaces:
AI
Direct Known Subclasses:
CowardSimpleAI, ExperimentalAI, RationalAI

public class SimpleAI extends AbstractAI
Simple implementation of a Titan AI TODO somehow we call client.getOwningPlayer() a lot -- there should probably be a better link between AI and player, after all the AI either IS_A player or PLAYS_FOR a player
Author:
Bruce Sherrod, David Ripton, Romain Dolbeau
  • Field Details

    • LOGGER

      private static final Logger LOGGER
    • TERRAIN_BONUSES

      private static final Map<String,SimpleAI.TerrainBonuses> TERRAIN_BONUSES
      Maps the terrain names to their matching bonuses. Only the terrains that have bonuses are in this map, so users have to expect to retrieve null values. Note that the terrain names include names for master board and hazard terrains, so it can be used for lookup up either type. TODO there seems to be some overlap with HazardTerrain.isNativeBonusTerrain() and HazardTerrain.isNonNativePenaltyTerrain(). This is a Map<String,TerrainBonuses>. TODO: this shouldn't be here, this is a property of the Variant player (well, not yet for Hazard, but it should be, someday). Actually, this doesn't make sense to me (RD). tower has bonus for both attacker & defender (because of walls, I assume), but is special- cased for attacker & defender. Brush and Jungle assumes Brushes, but Jungle has Tree, too. And the comments themselves makes clear that 'Sand' is actually 'Slope', but mixing up Attacker & Native and Defender & non-native. This and calcBonus should be reviewed thoroughly.
    • timeLimit

      protected int timeLimit
    • timeIsUp

      boolean timeIsUp
    • splitsDone

      private int splitsDone
    • splitsAcked

      private int splitsAcked
    • remainingMarkers

      private List<String> remainingMarkers
    • WIN_WITH_MINIMAL_LOSSES

      private static final int WIN_WITH_MINIMAL_LOSSES
      See Also:
    • WIN_WITH_HEAVY_LOSSES

      private static final int WIN_WITH_HEAVY_LOSSES
      See Also:
    • DRAW

      private static final int DRAW
      See Also:
    • LOSE_BUT_INFLICT_HEAVY_LOSSES

      private static final int LOSE_BUT_INFLICT_HEAVY_LOSSES
      See Also:
    • LOSE

      private static final int LOSE
      See Also:
    • MAX_LEGION_MOVES

      private final int MAX_LEGION_MOVES
      See Also:
    • MIN_ITERATIONS

      protected static final int MIN_ITERATIONS
      See Also:
  • Constructor Details

    • SimpleAI

      public SimpleAI(Client client)
  • Method Details

    • pickColor

      public PlayerColor pickColor(List<PlayerColor> colors, List<PlayerColor> favoriteColors)
      Description copied from interface: AI
      pick a color of legion markers
    • prepareMarkers

      private List<String> prepareMarkers(Set<String> markerIds, String preferredShortColor)
    • pickMarker

      public String pickMarker(Set<String> markerIds, String preferredShortColor)
      Description copied from interface: AI
      pick a legion marker
    • muster

      public void muster()
      Description copied from interface: AI
      make recruits for current player
    • reinforce

      public void reinforce(Legion legion)
      Description copied from interface: AI
      pick one reinforcement for legion
    • chooseRecruit

      CreatureType chooseRecruit(LegionClientSide legion, MasterHex hex, boolean considerReservations)
    • split

      public boolean split()
      Description copied from interface: AI
      make splits for current player. Return true if done
    • splitCallback

      public boolean splitCallback(Legion parent, Legion child)
      Unused in this AI; just return true to indicate done.
    • splitOneLegion

      private void splitOneLegion(Player player, Legion legion)
    • chooseCreaturesToSplitOut

      private List<CreatureType> chooseCreaturesToSplitOut(Legion legion)
      Decide how to split this legion, and return a list of Creatures to remove.
    • findWeakestTwoCritters

      List<CreatureType> findWeakestTwoCritters(LegionClientSide legion)
      Find the two weakest creatures in a legion according to
    • doInitialGameSplit

      List<CreatureType> doInitialGameSplit(MasterHex hex)
      Return a list of exactly four creatures (including one lord) to split out.
    • CMUsplit

      private List<CreatureType> CMUsplit(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex)
      Keep the gargoyles together.
    • MITsplit

      private List<CreatureType> MITsplit(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex)
      Split the gargoyles.
    • masterMove

      public boolean masterMove()
      Do a masterboard move (or consider taking mulligan, if feasible). Returns true if we need to run this method again after the server updates the client with the results of a move or mulligan.
    • handleMulligans

      boolean handleMulligans(Player player)
      Take a mulligan if roll is 2 or 5 in first turn, and can still take a mulligan. Returns true if AI took a mulligan, false otherwise.
    • handleVoluntaryMoves

      private boolean handleVoluntaryMoves(PlayerClientSide player, Map<Legion,List<AbstractAI.MoveInfo>> moveMap, Map<MasterHex,List<Legion>>[] enemyAttackMap)
      Return true if we moved something.
    • handleForcedSplitMoves

      private boolean handleForcedSplitMoves(Player player, Map<Legion,List<AbstractAI.MoveInfo>> moveMap)
      Return true if we moved something.
    • handleForcedSingleMove

      private boolean handleForcedSingleMove(Player player, Map<Legion,List<AbstractAI.MoveInfo>> moveMap)
    • doMove

      private boolean doMove(Legion legion, MasterHex hex)
    • evaluateMove

      private int evaluateMove(LegionClientSide legion, MasterHex hex, boolean moved, Map<MasterHex,List<Legion>>[] enemyAttackMap, ValueRecorder value)
      cheap, inaccurate evaluation function. Returns a value for moving this legion to this hex. The value defines a distance metric over the set of all possible moves. TODO: should be parameterized with weights TODO: the hex parameter is probably not needed anymore now that we pass the legion instead of just the marker [RD: actually, handleVoluntaryMove sees to call this one with several different hexes, so we probably can't remove it]
    • RATIO_WIN_MINIMAL_LOSS

      double RATIO_WIN_MINIMAL_LOSS()
    • RATIO_WIN_HEAVY_LOSS

      double RATIO_WIN_HEAVY_LOSS()
    • RATIO_DRAW

      double RATIO_DRAW()
    • RATIO_LOSE_HEAVY_LOSS

      double RATIO_LOSE_HEAVY_LOSS()
    • estimateBattleResults

      private int estimateBattleResults(Legion attacker, Legion defender, MasterHex hex)
    • estimateBattleResults

      private int estimateBattleResults(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex)
    • estimateBattleResults

      private int estimateBattleResults(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex, CreatureType recruit)
    • pickEntrySide

      public EntrySide pickEntrySide(MasterHex hex, Legion legion, Set<EntrySide> entrySides)
      Description copied from interface: AI
      pick an entry side
    • pickEngagement

      public MasterHex pickEngagement()
      Description copied from interface: AI
      pick an engagement to resolve
    • evaluateEngagement

      private int evaluateEngagement(MasterHex hex)
    • flee

      public boolean flee(Legion legion, Legion enemy)
      Description copied from interface: AI
      choose whether legion should flee from enemy
    • concede

      public boolean concede(Legion legion, Legion enemy)
      Description copied from interface: AI
      choose whether legion should concede to enemy
    • acquireAngel

      public CreatureType acquireAngel(Legion legion, List<CreatureType> angels)
      Description copied from interface: AI
      choose whether to acquire an angel or archangel
    • getBestCreature

      private CreatureType getBestCreature(List<CreatureType> creatures)
      Return the most important Creature in the list of Creatures.
    • summonAngel

      public SummonInfo summonAngel(Legion summoner, List<Legion> donors)
      Return a SummonInfo object, containing the summoner, donor and unittype.
    • findBestTarget

      private BattleCritter findBestTarget()
    • findBestAttacker

      private BattleCritter findBestAttacker(BattleCritter target)
    • handleCarries

      public void handleCarries(int carryDamage, Set<String> carryTargets)
      Apply carries first to the biggest creature that could be killed with them, then to the biggest creature. carryTargets are hexLabel description strings.
    • pickStrikePenalty

      public String pickStrikePenalty(List<String> choices)
      Pick one of the list of String strike penalty options.
    • strike

      public boolean strike(Legion legion)
      Simple one-ply group strike algorithm. Return false if there were no strike targets.
    • getCombatValue

      private static int getCombatValue(BattleCritter battleUnit, MasterBoardTerrain terrain)
    • getCombatValue

      private int getCombatValue(CreatureType creature, MasterBoardTerrain terrain)
      XXX Inaccurate for titans.
    • getTitanCombatValue

      private int getTitanCombatValue(int power)
    • getCombatValue

      private int getCombatValue(Legion legion, MasterBoardTerrain terrain)
    • calcBonus

      private SimpleAI.PowerSkill calcBonus(CreatureType creature, String terrain, boolean defender)
    • getNativeValue

      protected SimpleAI.PowerSkill getNativeValue(CreatureType creature, MasterBoardTerrain terrain, boolean defender)
    • battleMove

      public List<CritterMove> battleMove()
      Return a list of critter moves, in best move order.
    • retryFailedBattleMoves

      public void retryFailedBattleMoves(List<CritterMove> bestMoveOrder)
      Try another move for creatures whose moves failed.
    • findMoveOrder

      private List<CritterMove> findMoveOrder(LegionMove lm)
    • testMoveOrder

      private int testMoveOrder(List<CritterMove> order, List<CritterMove> newOrder)
      Try each of the moves in order. Return the number that succeed, scaled by the importance of each critter. In newOrder, if not null, place the moves that are valid.
    • getCreatureMoveLimit

      protected int getCreatureMoveLimit()
      Find the maximum number of moves per creature to test, such that numMobileCreaturesInLegion ^ N <= LEGION_MOVE_LIMIT, but we must have at least as many moves as mobile creatures to ensure that every creature has somewhere to go.
    • findBattleMoves

      private Collection<LegionMove> findBattleMoves()
    • findBattleMovesOneCritter

      private List<CritterMove> findBattleMovesOneCritter(BattleCritter critter)
    • setupTimer

      Timer setupTimer()
    • findBestLegionMove

      protected LegionMove findBestLegionMove(Collection<LegionMove> legionMoves)
      Evaluate all legion moves in the list, and return the best one. Break out early if the time limit is exceeded.
    • findLegionMoves

      Collection<LegionMove> findLegionMoves(List<List<CritterMove>> allCritterMoves)
      allCritterMoves is a List of sorted MoveLists. A MoveList is a sorted List of CritterMoves for one critter. Return a sorted List of LegionMoves. A LegionMove is a List of one CritterMove per mobile critter in the legion, where no two critters move to the same hex.
    • evaluateLegionBattleMoveAsAWhole

      protected int evaluateLegionBattleMoveAsAWhole(LegionMove lm, Map<BattleHex,Integer> strikeMap, ValueRecorder value)
    • evaluateCritterMove_Titan

      protected void evaluateCritterMove_Titan(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, Legion legion, int turn)
      this compute the special case of the Titan critter
    • evaluateCritterMove_Terrain

      private void evaluateCritterMove_Terrain(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill)
      This compute the influence of terrain
    • evaluateCritterMove_Attacker

      private void evaluateCritterMove_Attacker(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn)
      this compute for non-titan attacking critter
    • evaluateCritterMove_Defender

      protected void evaluateCritterMove_Defender(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn)
      this compute for non-titan defending critter
    • evaluateCritterMove_Rangestrike

      protected void evaluateCritterMove_Rangestrike(BattleCritter critter, Map<BattleHex,Integer> strikeMap, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill, LegionClientSide legion, int turn, Set<BattleHex> targetHexes)
    • evaluateCritterMove_Strike

      protected void evaluateCritterMove_Strike(BattleCritter critter, Map<BattleHex,Integer> strikeMap, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill, LegionClientSide legion, int turn, Set<BattleHex> targetHexes)
    • evaluateCritterMove

      private int evaluateCritterMove(BattleCritter critter, Map<BattleHex,Integer> strikeMap, ValueRecorder value)
      strikeMap is optional
    • evaluateLegionBattleMove

      protected int evaluateLegionBattleMove(LegionMove lm)