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
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
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected classprivate static classStores the skill and power bonuses for a single terrain.protected classNested classes/interfaces inherited from class AbstractAI
AbstractAI.AbstractAIOracle, AbstractAI.CreatureValueConstants, AbstractAI.MoveInfo -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final intprivate static final Loggerprivate static final intprivate static final intprivate final intprotected static final intprivate intprivate intprivate static final Map<String, SimpleAI.TerrainBonuses> Maps the terrain names to their matching bonuses.(package private) booleanprotected intprivate static final intprivate static final intFields inherited from class AbstractAI
bec, client, cvc, hintSectionUsed, random, variant -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionacquireAngel(Legion legion, List<CreatureType> angels) choose whether to acquire an angel or archangelReturn a list of critter moves, in best move order.private SimpleAI.PowerSkillcalcBonus(CreatureType creature, String terrain, boolean defender) private List<CreatureType> chooseCreaturesToSplitOut(Legion legion) Decide how to split this legion, and return a list of Creatures to remove.(package private) CreatureTypechooseRecruit(LegionClientSide legion, MasterHex hex, boolean considerReservations) private List<CreatureType> CMUsplit(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex) Keep the gargoyles together.booleanchoose whether legion should concede to enemy(package private) List<CreatureType> Return a list of exactly four creatures (including one lord) to split out.private booleanprivate intestimateBattleResults(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex) private intestimateBattleResults(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex, CreatureType recruit) private intestimateBattleResults(Legion attacker, Legion defender, MasterHex hex) private intevaluateCritterMove(BattleCritter critter, Map<BattleHex, Integer> strikeMap, ValueRecorder value) strikeMap is optionalprivate voidevaluateCritterMove_Attacker(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn) this compute for non-titan attacking critterprotected voidevaluateCritterMove_Defender(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn) this compute for non-titan defending critterprotected voidevaluateCritterMove_Rangestrike(BattleCritter critter, Map<BattleHex, Integer> strikeMap, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill, LegionClientSide legion, int turn, Set<BattleHex> targetHexes) protected voidevaluateCritterMove_Strike(BattleCritter critter, Map<BattleHex, Integer> strikeMap, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill, LegionClientSide legion, int turn, Set<BattleHex> targetHexes) private voidevaluateCritterMove_Terrain(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill) This compute the influence of terrainprotected voidevaluateCritterMove_Titan(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, Legion legion, int turn) this compute the special case of the Titan critterprivate intprotected intprotected intevaluateLegionBattleMoveAsAWhole(LegionMove lm, Map<BattleHex, Integer> strikeMap, ValueRecorder value) private intevaluateMove(LegionClientSide legion, MasterHex hex, boolean moved, Map<MasterHex, List<Legion>>[] enemyAttackMap, ValueRecorder value) cheap, inaccurate evaluation function.private Collection<LegionMove> private List<CritterMove> findBattleMovesOneCritter(BattleCritter critter) private BattleCritterfindBestAttacker(BattleCritter target) protected LegionMovefindBestLegionMove(Collection<LegionMove> legionMoves) Evaluate all legion moves in the list, and return the best one.private BattleCritter(package private) Collection<LegionMove> findLegionMoves(List<List<CritterMove>> allCritterMoves) allCritterMoves is a List of sorted MoveLists.private List<CritterMove> (package private) List<CreatureType> Find the two weakest creatures in a legion according tobooleanchoose whether legion should flee from enemyprivate CreatureTypegetBestCreature(List<CreatureType> creatures) Return the most important Creature in the list of Creatures.private static intgetCombatValue(BattleCritter battleUnit, MasterBoardTerrain terrain) private intgetCombatValue(Legion legion, MasterBoardTerrain terrain) private intgetCombatValue(CreatureType creature, MasterBoardTerrain terrain) XXX Inaccurate for titans.protected intFind the maximum number of moves per creature to test, such that numMobileCreaturesInLegion ^ N invalid input: '<'= LEGION_MOVE_LIMIT, but we must have at least as many moves as mobile creatures to ensure that every creature has somewhere to go.protected SimpleAI.PowerSkillgetNativeValue(CreatureType creature, MasterBoardTerrain terrain, boolean defender) private intgetTitanCombatValue(int power) voidhandleCarries(int carryDamage, Set<String> carryTargets) Apply carries first to the biggest creature that could be killed with them, then to the biggest creature.private booleanhandleForcedSingleMove(Player player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap) private booleanhandleForcedSplitMoves(Player player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap) Return true if we moved something.(package private) booleanhandleMulligans(Player player) Take a mulligan if roll is 2 or 5 in first turn, and can still take a mulligan.private booleanhandleVoluntaryMoves(PlayerClientSide player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap, Map<MasterHex, List<Legion>>[] enemyAttackMap) Return true if we moved something.booleanDo a masterboard move (or consider taking mulligan, if feasible).private List<CreatureType> MITsplit(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex) Split the gargoyles.voidmuster()make recruits for current playerpickColor(List<PlayerColor> colors, List<PlayerColor> favoriteColors) pick a color of legion markerspick an engagement to resolvepickEntrySide(MasterHex hex, Legion legion, Set<EntrySide> entrySides) pick an entry sidepickMarker(Set<String> markerIds, String preferredShortColor) pick a legion markerpickStrikePenalty(List<String> choices) Pick one of the list of String strike penalty options.prepareMarkers(Set<String> markerIds, String preferredShortColor) (package private) double(package private) double(package private) double(package private) doublevoidpick one reinforcement for legionvoidretryFailedBattleMoves(List<CritterMove> bestMoveOrder) Try another move for creatures whose moves failed.(package private) Timerbooleansplit()make splits for current player.booleansplitCallback(Legion parent, Legion child) Unused in this AI; just return true to indicate done.private voidsplitOneLegion(Player player, Legion legion) booleanSimple one-ply group strike algorithm.summonAngel(Legion summoner, List<Legion> donors) Return a SummonInfo object, containing the summoner, donor and unittype.private inttestMoveOrder(List<CritterMove> order, List<CritterMove> newOrder) Try each of the moves in order.Methods inherited from class AbstractAI
buildEnemyAttackMap, cleanupBattle, couldRecruitUp, countCreatureAccrossAllLegionFromPlayer, findStrikeMap, generateDamageMap, generateLegionMoves, getAcqStepValue, getBattleStrike, getBattleUnit, getCaretaker, getHintedRecruitmentValue, getHintedRecruitmentValueNonTitan, getHintedRecruitmentValueNonTitan, getInitialSplitHint, getKillValue, getKillValue, getNumberOfWaysToTerrain, getVariantRecruitHint, hasOpponentNativeCreature, initBattle, isHumanLegion, makeLegionMove, rangeToClosestOpponent, setVariant
-
Field Details
-
LOGGER
-
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 withHazardTerrain.isNativeBonusTerrain()andHazardTerrain.isNonNativePenaltyTerrain(). This is a Mapinvalid input: '<'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 invalid input: '&' defender (because of walls, I assume), but is special- cased for attacker invalid input: '&' 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 invalid input: '&' Native and Defender invalid input: '&' 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
-
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
-
-
Method Details
-
pickColor
Description copied from interface:AIpick a color of legion markers -
prepareMarkers
-
pickMarker
-
muster
-
reinforce
-
chooseRecruit
-
split
public boolean split()Description copied from interface:AImake splits for current player. Return true if done -
splitCallback
-
splitOneLegion
-
chooseCreaturesToSplitOut
Decide how to split this legion, and return a list of Creatures to remove. -
findWeakestTwoCritters
Find the two weakest creatures in a legion according to -
doInitialGameSplit
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
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
-
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
-
estimateBattleResults
-
estimateBattleResults
private int estimateBattleResults(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex, CreatureType recruit) -
pickEntrySide
-
pickEngagement
-
evaluateEngagement
-
flee
-
concede
-
acquireAngel
Description copied from interface:AIchoose whether to acquire an angel or archangel -
getBestCreature
Return the most important Creature in the list of Creatures. -
summonAngel
Return a SummonInfo object, containing the summoner, donor and unittype. -
findBestTarget
-
findBestAttacker
-
handleCarries
-
pickStrikePenalty
-
strike
Simple one-ply group strike algorithm. Return false if there were no strike targets. -
getCombatValue
-
getCombatValue
XXX Inaccurate for titans. -
getTitanCombatValue
private int getTitanCombatValue(int power) -
getCombatValue
-
calcBonus
-
getNativeValue
protected SimpleAI.PowerSkill getNativeValue(CreatureType creature, MasterBoardTerrain terrain, boolean defender) -
battleMove
Return a list of critter moves, in best move order. -
retryFailedBattleMoves
Try another move for creatures whose moves failed. -
findMoveOrder
-
testMoveOrder
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 invalid input: '<'= 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
-
findBattleMovesOneCritter
-
setupTimer
Timer setupTimer() -
findBestLegionMove
Evaluate all legion moves in the list, and return the best one. Break out early if the time limit is exceeded. -
findLegionMoves
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
-