diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index ab3c785ec1c..3ee909afa34 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -593,12 +593,14 @@ public class AiAttackController { int chanceToAttackToTrade = 0; boolean tradeIfTappedOut = false; int extraChanceIfOppHasMana = 0; + boolean tradeIfLowerLifePressure = false; if (ai.getController().isAI()) { AiController aic = ((PlayerControllerAi) ai.getController()).getAi(); playAggro = aic.getBooleanProperty(AiProps.PLAY_AGGRO); chanceToAttackToTrade = aic.getIntProperty(AiProps.CHANCE_TO_ATTACK_INTO_TRADE); tradeIfTappedOut = aic.getBooleanProperty(AiProps.ATTACK_INTO_TRADE_WHEN_TAPPED_OUT); extraChanceIfOppHasMana = aic.getIntProperty(AiProps.CHANCE_TO_ATKTRADE_WHEN_OPP_HAS_MANA); + tradeIfLowerLifePressure = aic.getBooleanProperty(AiProps.RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE); } final boolean bAssault = this.doAssault(ai); @@ -930,7 +932,9 @@ public class AiAttackController { && ai.getLife() > defendingOpponent.getLife() && !ComputerUtilCombat.lifeInDanger(ai, combat) && (ComputerUtilMana.getAvailableManaEstimate(ai) > 0) || tradeIfTappedOut - && (ComputerUtilMana.getAvailableManaEstimate(defendingOpponent) == 0) || MyRandom.percentTrue(extraChanceIfOppHasMana)) { + && (ComputerUtilMana.getAvailableManaEstimate(defendingOpponent) == 0) || MyRandom.percentTrue(extraChanceIfOppHasMana) + && (!tradeIfLowerLifePressure || (ai.getLifeLostLastTurn() + ai.getLifeLostThisTurn() < + defendingOpponent.getLifeLostThisTurn() + defendingOpponent.getLifeLostThisTurn()))) { this.aiAggression = 4; // random (chance-based) attack expecting to trade or damage player. } else if (ratioDiff >= 0 && this.attackers.size() > 1) { this.aiAggression = 3; // attack expecting to make good trades or damage player. diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index 474036a7161..b2ad46d8f5f 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -536,6 +536,7 @@ public class AiBlockController { boolean enableRandomTrades = false; boolean randomTradeIfBehindOnBoard = false; boolean randomTradeIfCreatInHand = false; + int chanceToTradeToSaveWalker = 0; int minRandomTradeChance = 0; int maxRandomTradeChance = 0; int maxCreatDiff = 0; @@ -551,13 +552,11 @@ public class AiBlockController { maxRandomTradeChance = aic.getIntProperty(AiProps.MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK); maxCreatDiff = aic.getIntProperty(AiProps.MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE); maxCreatDiffWithRepl = aic.getIntProperty(AiProps.MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL); + chanceToTradeToSaveWalker = aic.getIntProperty(AiProps.CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER); } if (enableRandomTrades) { aiCreatureCount = ComputerUtil.countUsefulCreatures(ai); - if (randomTradeIfBehindOnBoard) { - aiCreatureCount += maxCreatDiff; - } if (!attackersLeft.isEmpty()) { oppCreatureCount = ComputerUtil.countUsefulCreatures(attackersLeft.get(0).getController()); @@ -609,11 +608,14 @@ public class AiBlockController { boolean wantToTradeWithCreatInHand = randomTradeIfCreatInHand && !CardLists.filter(ai.getCardsIn(ZoneType.Hand), CardPredicates.Presets.CREATURES).isEmpty() && aiCreatureCount + maxCreatDiffWithRepl >= oppCreatureCount; + boolean wantToSavePlaneswalker = MyRandom.percentTrue(chanceToTradeToSaveWalker) + && combat.getDefenderByAttacker(attacker) instanceof Card + && ((Card) combat.getDefenderByAttacker(attacker)).isPlaneswalker(); if (evalBlk <= evalAtk + 1 // "1" accounts for tapped. Maybe increase to 3 or 5 for higher tolerance? && powerParityOrHigher && (creatureParityOrAllowedDiff || wantToTradeWithCreatInHand) - && MyRandom.percentTrue(chance)) { + && (MyRandom.percentTrue(chance) || wantToSavePlaneswalker)) { doTrade = true; } } diff --git a/forge-ai/src/main/java/forge/ai/AiProps.java b/forge-ai/src/main/java/forge/ai/AiProps.java index 37b59779670..bb748e6befa 100644 --- a/forge-ai/src/main/java/forge/ai/AiProps.java +++ b/forge-ai/src/main/java/forge/ai/AiProps.java @@ -37,6 +37,7 @@ public enum AiProps { /** */ RESERVE_MANA_FOR_MAIN2_CHANCE ("0"), /** */ PLAY_AGGRO ("false"), CHANCE_TO_ATTACK_INTO_TRADE ("40"), /** */ + RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE ("true"), /** */ ATTACK_INTO_TRADE_WHEN_TAPPED_OUT ("false"), /** */ CHANCE_TO_ATKTRADE_WHEN_OPP_HAS_MANA ("0"), /** */ TRY_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK ("false"), /** */ @@ -48,6 +49,7 @@ public enum AiProps { /** */ MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL ("1"), /** */ MIN_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK ("30"), /** */ MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK ("70"), /** */ + CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER ("70"), /** */ MIN_SPELL_CMC_TO_COUNTER ("0"), ALWAYS_COUNTER_OTHER_COUNTERSPELLS ("true"), /** */ ALWAYS_COUNTER_DAMAGE_SPELLS ("true"), /** */ diff --git a/forge-gui/res/ai/Cautious.ai b/forge-gui/res/ai/Cautious.ai index c6842b6d004..b8def769cc3 100644 --- a/forge-gui/res/ai/Cautious.ai +++ b/forge-gui/res/ai/Cautious.ai @@ -12,6 +12,8 @@ CHANCE_TO_ATTACK_INTO_TRADE=0 # is globally enabled). If disabled, the non-aggro AI will only attack into trades when it has mana open, thus having a chance # to "bluff" (or use, if available) combat tricks at the same time. ATTACK_INTO_TRADE_WHEN_TAPPED_OUT=false +# If enabled, the AI will only randomly attack into a trade if its life pressure is lower than the opponent's. +RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE=true # When above zero, the AI will attack into trading options when the opponent is not tapped out, thus risking getting an # unexpected combat trick or ability activation. Note that this chance is rolled separately after CHANCE_TO_ATTACK_INTO_TRADE # has already succeeded. @@ -23,7 +25,7 @@ USE_BERSERK_AGGRESSIVELY=false TRY_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=false # Chance to hold combat tricks until blockers are declared. If -1 is specified, this chance is not used, and the standard # evaluation for offensive pump buff is used instead. -CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=-1 +CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=75 # Trade blocking preferences (enabling these will make the AI trade more aggressively when considering blocks, # but only with creatures that are worse in abilities and have lower or the same power as the attacker). Note @@ -41,6 +43,8 @@ MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL=0 # Min and max chance to randomly aggressively trade when blocking (note that it will become 100 if the AI is in danger) MIN_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=40 MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=65 +# Chance to trade a creature in order to save a planeswalker +CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER=90 # Only works when AI cheating is enabled in preferences, otherwise does nothing CHEAT_WITH_MANA_ON_SHUFFLE=true diff --git a/forge-gui/res/ai/Default.ai b/forge-gui/res/ai/Default.ai index df3da957224..3bc094a0aee 100644 --- a/forge-gui/res/ai/Default.ai +++ b/forge-gui/res/ai/Default.ai @@ -12,10 +12,12 @@ CHANCE_TO_ATTACK_INTO_TRADE=0 # is globally enabled). If disabled, the non-aggro AI will only attack into trades when it has mana open, thus having a chance # to "bluff" (or use, if available) combat tricks at the same time. ATTACK_INTO_TRADE_WHEN_TAPPED_OUT=false +# If enabled, the AI will only randomly attack into a trade if its life pressure is lower than the opponent's. +RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE=true # When above zero, the AI will attack into trading options when the opponent is not tapped out, thus risking getting an # unexpected combat trick or ability activation. Note that this chance is rolled separately after CHANCE_TO_ATTACK_INTO_TRADE # has already succeeded. -CHANCE_TO_ATKTRADE_WHEN_OPP_HAS_MANA=85 +CHANCE_TO_ATKTRADE_WHEN_OPP_HAS_MANA=30 # When enabled, the AI will use Berserk on offense to try to severely damage the opponent at the expense of the creature USE_BERSERK_AGGRESSIVELY=false # Try to hold combat tricks until blockers are declared in an attempt to trick the opponent into blocking a weak creature @@ -23,7 +25,7 @@ USE_BERSERK_AGGRESSIVELY=false TRY_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=false # Chance to hold combat tricks until blockers are declared. If -1 is specified, this chance is not used, and the standard # evaluation for offensive pump buff is used instead. -CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=-1 +CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=65 # Trade blocking preferences (enabling these will make the AI trade more aggressively when considering blocks, # but only with creatures that are worse in abilities and have lower or the same power as the attacker). Note @@ -41,6 +43,8 @@ MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL=1 # Min and max chance to randomly aggressively trade when blocking (note that it will become 100 if the AI is in danger) MIN_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=30 MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=70 +# Chance to trade a creature in order to save a planeswalker +CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER=80 # Only works when AI cheating is enabled in preferences, otherwise does nothing CHEAT_WITH_MANA_ON_SHUFFLE=true diff --git a/forge-gui/res/ai/Experimental.ai b/forge-gui/res/ai/Experimental.ai index 55c6ef047ed..48b247b5c98 100644 --- a/forge-gui/res/ai/Experimental.ai +++ b/forge-gui/res/ai/Experimental.ai @@ -12,6 +12,8 @@ CHANCE_TO_ATTACK_INTO_TRADE=30 # is globally enabled). If disabled, the non-aggro AI will only attack into trades when it has mana open, thus having a chance # to "bluff" (or use, if available) combat tricks at the same time. ATTACK_INTO_TRADE_WHEN_TAPPED_OUT=false +# If enabled, the AI will only randomly attack into a trade if its life pressure is lower than the opponent's. +RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE=true # When above zero, the AI will attack into trading options when the opponent is not tapped out, thus risking getting an # unexpected combat trick or ability activation. Note that this chance is rolled separately after CHANCE_TO_ATTACK_INTO_TRADE # has already succeeded. @@ -23,7 +25,7 @@ USE_BERSERK_AGGRESSIVELY=true TRY_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=true # Chance to hold combat tricks until blockers are declared. If -1 is specified, this chance is not used, and the standard # evaluation for offensive pump buff is used instead. -CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=60 +CHANCE_TO_HOLD_COMBAT_TRICKS_UNTIL_BLOCK=65 # Trade blocking preferences (enabling these will make the AI trade more aggressively when considering blocks, # but only with creatures that are worse in abilities and have lower or the same power as the attacker). Note @@ -41,6 +43,8 @@ MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL=1 # Min and max chance to randomly aggressively trade when blocking (note that it will become 100 if the AI is in danger) MIN_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=30 MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=70 +# Chance to trade a creature in order to save a planeswalker +CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER=70 # Only works when AI cheating is enabled in preferences, otherwise does nothing CHEAT_WITH_MANA_ON_SHUFFLE=true diff --git a/forge-gui/res/ai/Reckless.ai b/forge-gui/res/ai/Reckless.ai index 598129e398a..c1851443eec 100644 --- a/forge-gui/res/ai/Reckless.ai +++ b/forge-gui/res/ai/Reckless.ai @@ -12,6 +12,8 @@ CHANCE_TO_ATTACK_INTO_TRADE=100 # is globally enabled). If disabled, the non-aggro AI will only attack into trades when it has mana open, thus having a chance # to "bluff" (or use, if available) combat tricks at the same time. ATTACK_INTO_TRADE_WHEN_TAPPED_OUT=true +# If enabled, the AI will only randomly attack into a trade if its life pressure is lower than the opponent's. +RANDOMLY_ATKTRADE_ONLY_ON_LOWER_LIFE_PRESSURE=false # When above zero, the AI will attack into trading options when the opponent is not tapped out, thus risking getting an # unexpected combat trick or ability activation. Note that this chance is rolled separately after CHANCE_TO_ATTACK_INTO_TRADE # has already succeeded. @@ -41,6 +43,8 @@ MAX_DIFF_IN_CREATURE_COUNT_TO_TRADE_WITH_REPL=1 # Min and max chance to randomly aggressively trade when blocking (note that it will become 100 if the AI is in danger) MIN_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=0 MAX_CHANCE_TO_RANDOMLY_TRADE_ON_BLOCK=50 +# Chance to trade a creature in order to save a planeswalker +CHANCE_TO_TRADE_TO_SAVE_PLANESWALKER=70 # Only works when AI cheating is enabled in preferences, otherwise does nothing CHEAT_WITH_MANA_ON_SHUFFLE=true