Class 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 Detail

      • LOGGER

        private static final java.util.logging.Logger LOGGER
      • TERRAIN_BONUSES

        private static final java.util.Map<java.lang.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. 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 java.util.List<java.lang.String> remainingMarkers
      • WIN_WITH_MINIMAL_LOSSES

        private static final int WIN_WITH_MINIMAL_LOSSES
        See Also:
        Constant Field Values
      • LOSE_BUT_INFLICT_HEAVY_LOSSES

        private static final int LOSE_BUT_INFLICT_HEAVY_LOSSES
        See Also:
        Constant Field Values
    • Constructor Detail

      • SimpleAI

        public SimpleAI​(Client client)
    • Method Detail

      • pickColor

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

        private java.util.List<java.lang.String> prepareMarkers​(java.util.Set<java.lang.String> markerIds,
                                                                java.lang.String preferredShortColor)
      • pickMarker

        public java.lang.String pickMarker​(java.util.Set<java.lang.String> markerIds,
                                           java.lang.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
      • 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 java.util.List<CreatureType> chooseCreaturesToSplitOut​(Legion legion)
        Decide how to split this legion, and return a list of Creatures to remove.
      • findWeakestTwoCritters

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

        java.util.List<CreatureType> doInitialGameSplit​(MasterHex hex)
        Return a list of exactly four creatures (including one lord) to split out.
      • 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.
      • handleForcedSplitMoves

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

        private boolean handleForcedSingleMove​(Player player,
                                               java.util.Map<Legion,​java.util.List<AbstractAI.MoveInfo>> moveMap)
      • evaluateMove

        private int evaluateMove​(LegionClientSide legion,
                                 MasterHex hex,
                                 boolean moved,
                                 java.util.Map<MasterHex,​java.util.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,
                                       java.util.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,
                                         java.util.List<CreatureType> angels)
        Description copied from interface: AI
        choose whether to acquire an angel or archangel
      • getBestCreature

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

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

        public void handleCarries​(int carryDamage,
                                  java.util.Set<java.lang.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 java.lang.String pickStrikePenalty​(java.util.List<java.lang.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.
      • getTitanCombatValue

        private int getTitanCombatValue​(int power)
      • battleMove

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

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

        private int testMoveOrder​(java.util.List<CritterMove> order,
                                  java.util.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 java.util.Collection<LegionMove> findBattleMoves()
      • setupTimer

        java.util.Timer setupTimer()
      • findBestLegionMove

        protected LegionMove findBestLegionMove​(java.util.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

        java.util.Collection<LegionMove> findLegionMoves​(java.util.List<java.util.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,
                                                       java.util.Map<BattleHex,​java.lang.Integer> strikeMap,
                                                       ValueRecorder value)
      • evaluateCritterMove

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

        protected int evaluateLegionBattleMove​(LegionMove lm)