From af05af7050813b0e4ee2952b10bad1ff82ea4531 Mon Sep 17 00:00:00 2001 From: magenoxx Date: Sun, 11 Dec 2011 15:53:34 +0400 Subject: [PATCH] Fixed Issue 441. --- .../src/mage/player/ai/ComputerPlayer6.java | 41 ++- .../player/ai/ma/ArtificialScoringSystem.java | 10 +- Mage.Server/plugins/mage-player-ai-ma.jar | Bin 45215 -> 45465 bytes Mage/src/mage/cards/LevelerCard.java | 15 +- .../mage/game/permanent/PermanentCard.java | 317 +++++++++--------- 5 files changed, 220 insertions(+), 163 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java index 5248d95f1ed..34fdf84590c 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java @@ -40,14 +40,17 @@ import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.effects.Effect; import mage.abilities.effects.SearchEffect; +import mage.abilities.keyword.LevelUpAbility; import mage.cards.Card; import mage.cards.Cards; import mage.choices.Choice; +import mage.counters.CounterType; import mage.game.Game; import mage.game.combat.Combat; import mage.game.combat.CombatGroup; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; +import mage.game.permanent.PermanentCard; import mage.game.stack.StackAbility; import mage.game.stack.StackObject; import mage.game.turn.*; @@ -472,6 +475,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements //logger.info("simulating -- player " + currentPlayer.getName()); SimulationNode2 bestNode = null; List allActions = currentPlayer.simulatePriority(game); + optimize(game, allActions); logger.debug("simulating -- adding " + allActions.size() + " children:" + allActions); for (Ability action: allActions) { if (Thread.interrupted()) { @@ -482,8 +486,8 @@ public class ComputerPlayer6 extends ComputerPlayer implements Game sim = game.copy(); if (sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) { sim.applyEffects(); - if (checkForRepeatedAction(sim, node, action, currentPlayer.getId())) - continue; + //if (checkForRepeatedAction(sim, node, action, currentPlayer.getId())) + //continue; if (!sim.isGameOver() && action.isUsesStack()) { // only pass if the last action uses the stack sim.getPlayer(currentPlayer.getId()).pass(); @@ -567,6 +571,35 @@ public class ComputerPlayer6 extends ComputerPlayer implements } } + /** + * Various AI optimizations for actions. + * + * @param allActions + */ + protected void optimize(Game game, List allActions) { + List toRemove = null; + for (Ability ability : allActions) { + if (ability instanceof LevelUpAbility) { + Permanent permanent = game.getPermanent(ability.getSourceId()); + if (permanent != null && permanent instanceof PermanentCard) { + PermanentCard leveler = (PermanentCard) permanent; + // check already existing Level counters and compare to maximum that make sense + if (permanent.getCounters().getCount(CounterType.LEVEL) >= leveler.getMaxLevelCounters()) { + if (toRemove == null) { + toRemove = new ArrayList(); + } + toRemove.add(ability); + } + } + } + } + if (toRemove != null) { + for (Ability r : toRemove) { + allActions.remove(r); + } + } + } + protected boolean allPassed(Game game) { for (Player player: game.getPlayers().values()) { if (!player.isPassed() && !player.hasLost() && !player.hasLeft()) @@ -806,7 +839,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements return sim; } - private boolean checkForRepeatedAction(Game sim, SimulationNode2 node, Ability action, UUID playerId) { + /*private boolean checkForRepeatedAction(Game sim, SimulationNode2 node, Ability action, UUID playerId) { if (action instanceof PassAbility) return false; int val = GameStateEvaluator2.evaluate(playerId, sim); @@ -820,7 +853,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements } } return false; - } + }*/ protected void getSuggestedActions() { try { diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java index f0db2eed657..de0a95122d9 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ma/ArtificialScoringSystem.java @@ -1,7 +1,6 @@ package mage.player.ai.ma; import mage.Constants; -import mage.Mana; import mage.abilities.Ability; import mage.abilities.keyword.HasteAbility; import mage.cards.Card; @@ -65,6 +64,7 @@ public class ArtificialScoringSystem { public static int getVariablePermanentScore(final Game game, final Permanent permanent) { int score = permanent.getCounters().getCount(CounterType.CHARGE) * 30; + score += permanent.getCounters().getCount(CounterType.LEVEL) * 30; score -= permanent.getDamage() * 2; if (!canTap(permanent)) { score += getTappedScore(permanent); @@ -108,7 +108,13 @@ public class ArtificialScoringSystem { } public static int getTappedScore(final Permanent permanent) { - return permanent.getCardType().contains(Constants.CardType.CREATURE) ? -100 : -50; + if (permanent.getCardType().contains(Constants.CardType.CREATURE)) { + return -100; + } else if (permanent.getCardType().contains(Constants.CardType.LAND)) { + return -10; + } else { + return -50; + } } public static int getLifeScore(final int life) { diff --git a/Mage.Server/plugins/mage-player-ai-ma.jar b/Mage.Server/plugins/mage-player-ai-ma.jar index 06fe71dda0c7ca36015baf42975052f49651563f..083c03e4e5914c3ac5a47b48fa7c57f4c2473eb3 100644 GIT binary patch delta 18821 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 delta 18514 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 extends CardImpl return null; } + public int getMaxLevelCounters() { + for (LevelAbility levelerLevel: levels) { + if (levelerLevel.getLevel2() == -1) + return levelerLevel.getLevel1(); + } + return 0; + } + @Override public List getRules() { List rules = new ArrayList(); diff --git a/Mage/src/mage/game/permanent/PermanentCard.java b/Mage/src/mage/game/permanent/PermanentCard.java index bc879b207a7..8265fbd3e39 100644 --- a/Mage/src/mage/game/permanent/PermanentCard.java +++ b/Mage/src/mage/game/permanent/PermanentCard.java @@ -28,9 +28,6 @@ package mage.game.permanent; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; @@ -43,192 +40,204 @@ import mage.game.Game; import mage.game.events.ZoneChangeEvent; import mage.players.Player; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class PermanentCard extends PermanentImpl { - protected List levelerRules; + protected List levelerRules; + protected int maxLevelCounters; protected Card card; - public PermanentCard(Card card, UUID controllerId) { - super(card.getId(), card.getOwnerId(), controllerId, card.getName()); + public PermanentCard(Card card, UUID controllerId) { + super(card.getId(), card.getOwnerId(), controllerId, card.getName()); this.card = card.copy(); - init(card); - } + init(card); + } - protected PermanentCard(UUID id, Card card, UUID controllerId) { - super(card.getId(), card.getOwnerId(), controllerId, card.getName()); + protected PermanentCard(UUID id, Card card, UUID controllerId) { + super(card.getId(), card.getOwnerId(), controllerId, card.getName()); this.card = card.copy(); - init(card); - } + init(card); + } - protected void init(Card card) { - copyFromCard(card); - /*if (card.getCardType().contains(CardType.PLANESWALKER)) { - this.loyalty = new MageInt(card.getLoyalty().getValue()); - }*/ - if (card instanceof LevelerCard) { - levelerRules = ((LevelerCard)card).getRules(); - } - } + protected void init(Card card) { + copyFromCard(card); + /*if (card.getCardType().contains(CardType.PLANESWALKER)) { + this.loyalty = new MageInt(card.getLoyalty().getValue()); + }*/ + if (card instanceof LevelerCard) { + levelerRules = ((LevelerCard) card).getRules(); + maxLevelCounters = ((LevelerCard) card).getMaxLevelCounters(); + } + } - public PermanentCard(final PermanentCard permanent) { - super(permanent); + public PermanentCard(final PermanentCard permanent) { + super(permanent); this.card = permanent.card; - } + this.maxLevelCounters = permanent.maxLevelCounters; + } - @Override - public void reset(Game game) { - // when the permanent is reset copy all original values from the card - // must copy card each reset so that the original values don't get modified - copyFromCard(card); - super.reset(game); - } + @Override + public void reset(Game game) { + // when the permanent is reset copy all original values from the card + // must copy card each reset so that the original values don't get modified + copyFromCard(card); + super.reset(game); + } - protected void copyFromCard(Card card) { - this.name = card.getName(); + protected void copyFromCard(Card card) { + this.name = card.getName(); this.abilities.clear(); - this.abilities.addAll(card.getAbilities()); - this.abilities.setControllerId(this.controllerId); + this.abilities.addAll(card.getAbilities()); + this.abilities.setControllerId(this.controllerId); this.cardType.clear(); - this.cardType.addAll(card.getCardType()); - this.color = card.getColor().copy(); - this.manaCost = card.getManaCost().copy(); - this.power = card.getPower().copy(); - this.toughness = card.getToughness().copy(); - if (card instanceof LevelerCard) { - LevelAbility level = ((LevelerCard)card).getLevel(this.getCounters().getCount(CounterType.LEVEL)); - if (level != null) { - this.power.setValue(level.getPower()); - this.toughness.setValue(level.getToughness()); - for (Ability ability: level.getAbilities()) { - this.addAbility(ability); - } - } - } + this.cardType.addAll(card.getCardType()); + this.color = card.getColor().copy(); + this.manaCost = card.getManaCost().copy(); + this.power = card.getPower().copy(); + this.toughness = card.getToughness().copy(); + if (card instanceof LevelerCard) { + LevelAbility level = ((LevelerCard) card).getLevel(this.getCounters().getCount(CounterType.LEVEL)); + if (level != null) { + this.power.setValue(level.getPower()); + this.toughness.setValue(level.getToughness()); + for (Ability ability : level.getAbilities()) { + this.addAbility(ability); + } + } + } + if (card instanceof PermanentCard) { + this.maxLevelCounters = ((PermanentCard) card).maxLevelCounters; + } this.subtype.clear(); - this.subtype.addAll(card.getSubtype()); + this.subtype.addAll(card.getSubtype()); this.supertype.clear(); - this.supertype.addAll(card.getSupertype()); - this.expansionSetCode = card.getExpansionSetCode(); - this.rarity = card.getRarity(); - this.cardNumber = card.getCardNumber(); + this.supertype.addAll(card.getSupertype()); + this.expansionSetCode = card.getExpansionSetCode(); + this.rarity = card.getRarity(); + this.cardNumber = card.getCardNumber(); canTransform = card.canTransform(); if (canTransform) { secondSideCard = card.getSecondCardFace(); nightCard = card.isNightCard(); } - } + } - public void checkPermanentOnlyTriggers(ZoneChangeEvent event, Game game) { - // we only want to trigger abilities that are not on the underlying card ie. have been added by another effect - // or we want to trigger abilities that only trigger on leaving the battlefield - // card abilities will get triggered later when the card hits the new zone + public void checkPermanentOnlyTriggers(ZoneChangeEvent event, Game game) { + // we only want to trigger abilities that are not on the underlying card ie. have been added by another effect + // or we want to trigger abilities that only trigger on leaving the battlefield + // card abilities will get triggered later when the card hits the new zone List triggered = new ArrayList(); - for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getFromZone())) { - if (!card.getAbilities().containsKey(ability.getId())) { - if (ability.checkTrigger(event, game)) { + for (TriggeredAbility ability : abilities.getTriggeredAbilities(event.getFromZone())) { + if (!card.getAbilities().containsKey(ability.getId())) { + if (ability.checkTrigger(event, game)) { triggered.add(ability.getId()); - ability.trigger(game, controllerId); - } - } else if (ability instanceof ZoneChangeTriggeredAbility && event.getFromZone() == Zone.BATTLEFIELD) { - ZoneChangeTriggeredAbility zcAbility = (ZoneChangeTriggeredAbility)ability; - if (zcAbility.getToZone() == null) { - if (ability.checkTrigger(event, game)) { + ability.trigger(game, controllerId); + } + } else if (ability instanceof ZoneChangeTriggeredAbility && event.getFromZone() == Zone.BATTLEFIELD) { + ZoneChangeTriggeredAbility zcAbility = (ZoneChangeTriggeredAbility) ability; + if (zcAbility.getToZone() == null) { + if (ability.checkTrigger(event, game)) { triggered.add(ability.getId()); - ability.trigger(game, controllerId); - } - } - } - } - for (TriggeredAbility ability: abilities.getTriggeredAbilities(event.getToZone())) { - if (!card.getAbilities().containsKey(ability.getId())) { - if (!triggered.contains(ability.getId()) && ability.checkTrigger(event, game)) { - ability.trigger(game, controllerId); - } - } - } - } + ability.trigger(game, controllerId); + } + } + } + } + for (TriggeredAbility ability : abilities.getTriggeredAbilities(event.getToZone())) { + if (!card.getAbilities().containsKey(ability.getId())) { + if (!triggered.contains(ability.getId()) && ability.checkTrigger(event, game)) { + ability.trigger(game, controllerId); + } + } + } + } - @Override - public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) { - Zone fromZone = game.getState().getZone(objectId); - Player controller = game.getPlayer(controllerId); - if (controller != null && controller.removeFromBattlefield(this, game)) { - ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone); - if (!game.replaceEvent(event)) { - Player owner = game.getPlayer(ownerId); - game.rememberLKI(objectId, Zone.BATTLEFIELD, this); - if (owner != null) { - switch (event.getToZone()) { - case GRAVEYARD: - owner.putInGraveyard(card, game, !flag); - break; - case HAND: - owner.getHand().add(card); - break; - case EXILED: - game.getExile().getPermanentExile().add(card); - break; - case LIBRARY: - if (flag) - owner.getLibrary().putOnTop(card, game); - else - owner.getLibrary().putOnBottom(card, game); - break; - case BATTLEFIELD: - //should never happen - break; - } - game.setZone(objectId, event.getToZone()); - game.fireEvent(event); - return game.getState().getZone(objectId) == toZone; - } - } - } - return false; - } + @Override + public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag) { + Zone fromZone = game.getState().getZone(objectId); + Player controller = game.getPlayer(controllerId); + if (controller != null && controller.removeFromBattlefield(this, game)) { + ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, controllerId, fromZone, toZone); + if (!game.replaceEvent(event)) { + Player owner = game.getPlayer(ownerId); + game.rememberLKI(objectId, Zone.BATTLEFIELD, this); + if (owner != null) { + switch (event.getToZone()) { + case GRAVEYARD: + owner.putInGraveyard(card, game, !flag); + break; + case HAND: + owner.getHand().add(card); + break; + case EXILED: + game.getExile().getPermanentExile().add(card); + break; + case LIBRARY: + if (flag) + owner.getLibrary().putOnTop(card, game); + else + owner.getLibrary().putOnBottom(card, game); + break; + case BATTLEFIELD: + //should never happen + break; + } + game.setZone(objectId, event.getToZone()); + game.fireEvent(event); + return game.getState().getZone(objectId) == toZone; + } + } + } + return false; + } - @Override - public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game) { - Zone fromZone = game.getState().getZone(objectId); - Player controller = game.getPlayer(controllerId); - if (controller != null && controller.removeFromBattlefield(this, game)) { - ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED); - if (!game.replaceEvent(event)) { - if (exileId == null) { - game.getExile().getPermanentExile().add(card); - } - else { - game.getExile().createZone(exileId, name).add(card); - } - game.setZone(objectId, event.getToZone()); - game.fireEvent(event); - return true; - } - } - return false; - } + @Override + public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game) { + Zone fromZone = game.getState().getZone(objectId); + Player controller = game.getPlayer(controllerId); + if (controller != null && controller.removeFromBattlefield(this, game)) { + ZoneChangeEvent event = new ZoneChangeEvent(this, sourceId, ownerId, fromZone, Zone.EXILED); + if (!game.replaceEvent(event)) { + if (exileId == null) { + game.getExile().getPermanentExile().add(card); + } else { + game.getExile().createZone(exileId, name).add(card); + } + game.setZone(objectId, event.getToZone()); + game.fireEvent(event); + return true; + } + } + return false; + } - @Override - public PermanentCard copy() { - return new PermanentCard(this); - } + @Override + public PermanentCard copy() { + return new PermanentCard(this); + } - @Override - public List getRules() { - if (levelerRules == null) - return super.getRules(); - List rules = new ArrayList(); - rules.addAll(super.getRules()); - rules.addAll(levelerRules); - return rules; - } + public int getMaxLevelCounters() { + return this.maxLevelCounters; + } + + @Override + public List getRules() { + if (levelerRules == null) + return super.getRules(); + List rules = new ArrayList(); + rules.addAll(super.getRules()); + rules.addAll(levelerRules); + return rules; + } }