update simulators

This commit is contained in:
htrajan 2020-04-16 20:14:43 -07:00
parent 5a1b40a42f
commit 51dcaa1725
4 changed files with 31 additions and 20 deletions

View file

@ -2434,7 +2434,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
simulations = new TreeNode<>(combat); simulations = new TreeNode<>(combat);
addBlockSimulations(blockers, simulations, game); addBlockSimulations(blockers, simulations, game);
combat.simulate(); combat.simulate(game);
return getWorstSimulation(simulations); return getWorstSimulation(simulations);
@ -2452,7 +2452,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
TreeNode<CombatSimulator> child = new TreeNode<>(combat); TreeNode<CombatSimulator> child = new TreeNode<>(combat);
node.addChild(child); node.addChild(child);
addBlockSimulations(subList, child, game); addBlockSimulations(subList, child, game);
combat.simulate(); combat.simulate(game);
} }
} }
} }

View file

@ -1,5 +1,3 @@
package mage.player.ai.simulators; package mage.player.ai.simulators;
import mage.game.Game; import mage.game.Game;
@ -52,15 +50,15 @@ public class CombatGroupSimulator implements Serializable {
return blocker.canBlock(attacker.id, game); return blocker.canBlock(attacker.id, game);
} }
public void simulateCombat() { public void simulateCombat(Game game) {
unblockedDamage = 0; unblockedDamage = 0;
if (hasFirstOrDoubleStrike()) if (hasFirstOrDoubleStrike())
assignDamage(true); assignDamage(true, game);
assignDamage(false); assignDamage(false, game);
} }
private void assignDamage(boolean first) { private void assignDamage(boolean first, Game game) {
if (blockers.isEmpty()) { if (blockers.isEmpty()) {
if (canDamage(attacker, first)) if (canDamage(attacker, first))
unblockedDamage += attacker.power; unblockedDamage += attacker.power;
@ -69,7 +67,7 @@ public class CombatGroupSimulator implements Serializable {
CreatureSimulator blocker = blockers.get(0); CreatureSimulator blocker = blockers.get(0);
if (canDamage(attacker, first)) { if (canDamage(attacker, first)) {
if (attacker.hasTrample) { if (attacker.hasTrample) {
int lethalDamage = blocker.getLethalDamage(); int lethalDamage = blocker.getLethalDamage(game);
if (attacker.power > lethalDamage) { if (attacker.power > lethalDamage) {
blocker.damage += lethalDamage; blocker.damage += lethalDamage;
unblockedDamage += attacker.power - lethalDamage; unblockedDamage += attacker.power - lethalDamage;
@ -87,7 +85,7 @@ public class CombatGroupSimulator implements Serializable {
int damage = attacker.power; int damage = attacker.power;
for (CreatureSimulator blocker: blockers) { for (CreatureSimulator blocker: blockers) {
if (damage > 0 && canDamage(attacker, first)) { if (damage > 0 && canDamage(attacker, first)) {
int lethalDamage = blocker.getLethalDamage(); int lethalDamage = blocker.getLethalDamage(game);
if (damage > lethalDamage) { if (damage > lethalDamage) {
blocker.damage += lethalDamage; blocker.damage += lethalDamage;
damage -= lethalDamage; damage -= lethalDamage;

View file

@ -1,5 +1,3 @@
package mage.player.ai.simulators; package mage.player.ai.simulators;
import mage.counters.CounterType; import mage.counters.CounterType;
@ -52,9 +50,9 @@ public class CombatSimulator implements Serializable {
attackerId = null; attackerId = null;
} }
public void simulate() { public void simulate(Game game) {
for (CombatGroupSimulator group: groups) { for (CombatGroupSimulator group: groups) {
group.simulateCombat(); group.simulateCombat(game);
} }
} }

View file

@ -1,14 +1,16 @@
package mage.player.ai.simulators; package mage.player.ai.simulators;
import java.io.Serializable;
import java.util.UUID;
import mage.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.io.Serializable;
import java.util.List;
import java.util.UUID;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -21,6 +23,7 @@ public class CreatureSimulator implements Serializable {
public boolean hasFirstStrike; public boolean hasFirstStrike;
public boolean hasDoubleStrike; public boolean hasDoubleStrike;
public boolean hasTrample; public boolean hasTrample;
public Permanent permanent;
public CreatureSimulator(Permanent permanent) { public CreatureSimulator(Permanent permanent) {
this.id = permanent.getId(); this.id = permanent.getId();
@ -30,13 +33,25 @@ public class CreatureSimulator implements Serializable {
this.hasDoubleStrike = permanent.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()); this.hasDoubleStrike = permanent.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId());
this.hasFirstStrike = permanent.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()); this.hasFirstStrike = permanent.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId());
this.hasTrample = permanent.getAbilities().containsKey(TrampleAbility.getInstance().getId()); this.hasTrample = permanent.getAbilities().containsKey(TrampleAbility.getInstance().getId());
this.permanent = permanent;
} }
public boolean isDead() { public boolean isDead() {
return damage >= toughness; return damage >= toughness;
} }
public int getLethalDamage() { public int getLethalDamage(Game game) {
return toughness - damage; List<FilterCreaturePermanent> usePowerInsteadOfToughnessForDamageLethalityFilters = game.getState().getActivePowerInsteadOfToughnessForDamageLethalityFilters();
/*
* for handling Zilortha, Strength Incarnate:
* 2020-04-17
* Any time the game is checking whether damage is lethal or if a creature should be destroyed for having lethal damage marked on it, use the power of your creatures rather than their toughness to check the damage against. This includes being assigned trample damage, damage from Flame Spill, and so on.
*/
boolean usePowerInsteadOfToughnessForDamageLethality = usePowerInsteadOfToughnessForDamageLethalityFilters.stream()
.anyMatch(filter -> filter.match(permanent, game));
int lethalDamageThreshold = usePowerInsteadOfToughnessForDamageLethality ?
// Zilortha, Strength Incarnate, 2020-04-17: A creature with 0 power isnt destroyed unless it has at least 1 damage marked on it.
Math.max(power, 1) : toughness;
return Math.max(lethalDamageThreshold - damage, 0);
} }
} }