Package net.sf.colossus.ai
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 class
private static class
Stores the skill and power bonuses for a single terrain.protected class
Nested classes/interfaces inherited from class net.sf.colossus.ai.AbstractAI
AbstractAI.AbstractAIOracle, AbstractAI.CreatureValueConstants, AbstractAI.MoveInfo
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final int
private static final Logger
private static final int
private static final int
private final int
protected static final int
private int
private int
private static final Map<String,
SimpleAI.TerrainBonuses> Maps the terrain names to their matching bonuses.(package private) boolean
protected int
private static final int
private static final int
Fields inherited from class net.sf.colossus.ai.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.PowerSkill
calcBonus
(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) CreatureType
chooseRecruit
(LegionClientSide legion, MasterHex hex, boolean considerReservations) private List<CreatureType>
CMUsplit
(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex) Keep the gargoyles together.boolean
choose whether legion should concede to enemy(package private) List<CreatureType>
Return a list of exactly four creatures (including one lord) to split out.private boolean
private int
estimateBattleResults
(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex) private int
estimateBattleResults
(Legion attacker, boolean attackerSplitsBeforeBattle, Legion defender, MasterHex hex, CreatureType recruit) private int
estimateBattleResults
(Legion attacker, Legion defender, MasterHex hex) private int
evaluateCritterMove
(BattleCritter critter, Map<BattleHex, Integer> strikeMap, ValueRecorder value) strikeMap is optionalprivate void
evaluateCritterMove_Attacker
(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn) this compute for non-titan attacking critterprotected void
evaluateCritterMove_Defender
(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, LegionClientSide legion, int turn) this compute for non-titan defending critterprotected 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) 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) private void
evaluateCritterMove_Terrain
(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, int power, int skill) This compute the influence of terrainprotected void
evaluateCritterMove_Titan
(BattleCritter critter, ValueRecorder value, MasterBoardTerrain terrain, BattleHex hex, Legion legion, int turn) this compute the special case of the Titan critterprivate int
protected int
protected int
evaluateLegionBattleMoveAsAWhole
(LegionMove lm, Map<BattleHex, Integer> strikeMap, ValueRecorder value) private int
evaluateMove
(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 BattleCritter
findBestAttacker
(BattleCritter target) protected LegionMove
findBestLegionMove
(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 toboolean
choose whether legion should flee from enemyprivate CreatureType
getBestCreature
(List<CreatureType> creatures) Return the most important Creature in the list of Creatures.private static int
getCombatValue
(BattleCritter battleUnit, MasterBoardTerrain terrain) private int
getCombatValue
(Legion legion, MasterBoardTerrain terrain) private int
getCombatValue
(CreatureType creature, MasterBoardTerrain terrain) XXX Inaccurate for titans.protected int
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.protected SimpleAI.PowerSkill
getNativeValue
(CreatureType creature, MasterBoardTerrain terrain, boolean defender) private int
getTitanCombatValue
(int power) 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.private boolean
handleForcedSingleMove
(Player player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap) private boolean
handleForcedSplitMoves
(Player player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap) Return true if we moved something.(package private) boolean
handleMulligans
(Player player) Take a mulligan if roll is 2 or 5 in first turn, and can still take a mulligan.private boolean
handleVoluntaryMoves
(PlayerClientSide player, Map<Legion, List<AbstractAI.MoveInfo>> moveMap, Map<MasterHex, List<Legion>>[] enemyAttackMap) Return true if we moved something.boolean
Do a masterboard move (or consider taking mulligan, if feasible).private List<CreatureType>
MITsplit
(boolean favorTitan, CreatureType splitCreature, CreatureType nonsplitCreature, MasterHex hex) Split the gargoyles.void
muster()
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) double
void
pick one reinforcement for legionvoid
retryFailedBattleMoves
(List<CritterMove> bestMoveOrder) Try another move for creatures whose moves failed.(package private) Timer
boolean
split()
make splits for current player.boolean
splitCallback
(Legion parent, Legion child) Unused in this AI; just return true to indicate done.private void
splitOneLegion
(Player player, Legion legion) boolean
Simple one-ply group strike algorithm.summonAngel
(Legion summoner, List<Legion> donors) Return a SummonInfo object, containing the summoner, donor and unittype.private int
testMoveOrder
(List<CritterMove> order, List<CritterMove> newOrder) Try each of the moves in order.Methods inherited from class net.sf.colossus.ai.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 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
-
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:AI
pick a color of legion markers -
prepareMarkers
-
pickMarker
Description copied from interface:AI
pick a legion marker -
muster
public void muster()Description copied from interface:AI
make recruits for current player -
reinforce
Description copied from interface:AI
pick one reinforcement for legion -
chooseRecruit
-
split
public boolean split()Description copied from interface:AI
make splits for current player. Return true if done -
splitCallback
Unused in this AI; just return true to indicate done. -
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
Description copied from interface:AI
pick an entry side -
pickEngagement
Description copied from interface:AI
pick an engagement to resolve -
evaluateEngagement
-
flee
Description copied from interface:AI
choose whether legion should flee from enemy -
concede
Description copied from interface:AI
choose whether legion should concede to enemy -
acquireAngel
Description copied from interface:AI
choose 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
Apply carries first to the biggest creature that could be killed with them, then to the biggest creature. carryTargets are hexLabel description strings. -
pickStrikePenalty
Pick one of the list of String strike penalty options. -
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 <= 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
-