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 da2259042f..51209bf93b 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 @@ -56,10 +56,8 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetCard; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.io.File; +import java.util.*; import java.util.concurrent.*; /** @@ -81,11 +79,15 @@ public class ComputerPlayer6 extends ComputerPlayer implements protected int currentScore; protected SimulationNode2 root; + private static final String FILE_WITH_INSTRUCTIONS = "config/ai.please.cast.this.txt"; + private List suggested = new ArrayList(); + public ComputerPlayer6(String name, RangeOfInfluence range, int skill) { super(name, range); maxDepth = skill * 2; maxThink = skill * 3; maxNodes = Config2.maxNodes; + getSuggestedActions(); } public ComputerPlayer6(final ComputerPlayer6 player) { @@ -773,7 +775,7 @@ public class ComputerPlayer6 extends ComputerPlayer implements for (Player copyPlayer: sim.getState().getPlayers().values()) { Player origPlayer = game.getState().getPlayers().get(copyPlayer.getId()); - SimulatedPlayer2 newPlayer = new SimulatedPlayer2(copyPlayer.getId(), copyPlayer.getId().equals(playerId)); + SimulatedPlayer2 newPlayer = new SimulatedPlayer2(copyPlayer.getId(), copyPlayer.getId().equals(playerId), suggested); newPlayer.restore(origPlayer); sim.getState().getPlayers().put(copyPlayer.getId(), newPlayer); } @@ -795,4 +797,26 @@ public class ComputerPlayer6 extends ComputerPlayer implements } return false; } + + protected void getSuggestedActions() { + try { + File file = new File(FILE_WITH_INSTRUCTIONS); + if (file.exists()) { + Scanner scanner = new Scanner(file); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + if (line.startsWith("cast:") || line.startsWith("play:")) { + suggested.add(line.substring(5, line.length())); + } + } + System.out.println("suggested::"); + for (int i = 0; i < suggested.size(); i++) { + System.out.println(" " + suggested.get(i)); + } + } + } catch (Exception e) { + // swallow + e.printStackTrace(); + } + } } diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java index 52e107a148..0fe7657385 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java @@ -28,12 +28,8 @@ package mage.player.ai; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.io.File; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; @@ -43,6 +39,7 @@ import mage.abilities.costs.mana.ManaCost; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.mana.ManaOptions; +import mage.cards.Card; import mage.choices.Choice; import mage.filter.FilterAbility; import mage.game.Game; @@ -50,6 +47,7 @@ import mage.game.combat.Combat; import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.stack.StackAbility; +import mage.sets.innistrad.UnholyFiend; import mage.target.Target; import mage.util.Logging; import org.apache.log4j.Logger; @@ -66,10 +64,13 @@ public class SimulatedPlayer2 extends ComputerPlayer { private transient ConcurrentLinkedQueue allActions; private static PassAbility pass = new PassAbility(); - public SimulatedPlayer2(UUID id, boolean isSimulatedPlayer) { + private List suggested; + + public SimulatedPlayer2(UUID id, boolean isSimulatedPlayer, List suggested) { super(id); pass.setControllerId(playerId); this.isSimulatedPlayer = isSimulatedPlayer; + this.suggested = suggested; } public SimulatedPlayer2(final SimulatedPlayer2 player) { @@ -101,6 +102,7 @@ public class SimulatedPlayer2 extends ComputerPlayer { ManaOptions available = getManaAvailable(game); available.addMana(manaPool.getMana()); List playables = game.getPlayer(playerId).getPlayable(game, filter, available, isSimulatedPlayer); + playables = filterAbilities(game, playables, suggested); for (Ability ability: playables) { List options = game.getPlayer(playerId).getPlayableOptions(ability, game); if (options.size() == 0) { @@ -141,6 +143,29 @@ public class SimulatedPlayer2 extends ComputerPlayer { // } // } + protected List filterAbilities(Game game, List playables, List suggested) { + if (playables.isEmpty()) { + return playables; + } + if (suggested == null || suggested.isEmpty()) { + return playables; + } + List filtered = new ArrayList(); + for (Ability ability : playables) { + Card card = game.getCard(ability.getSourceId()); + for (String s : suggested) { + if (s.equals(card.getName())) { + System.out.println("matched: " + s); + filtered.add(ability); + } + } + } + if (!filtered.isEmpty()) { + return filtered; + } + return playables; + } + //add a generic mana cost for each amount possible protected void simulateVariableCosts(Ability ability, Game game) { int numAvailable = getAvailableManaProducers(game).size(); @@ -276,5 +301,4 @@ public class SimulatedPlayer2 extends ComputerPlayer { public void priority(Game game) { //should never get here } - } diff --git a/Mage.Server/config/ai.please.cast.this.txt.example b/Mage.Server/config/ai.please.cast.this.txt.example new file mode 100644 index 0000000000..646ec21a94 --- /dev/null +++ b/Mage.Server/config/ai.please.cast.this.txt.example @@ -0,0 +1,2 @@ +play:Swamp +cast:Duress \ No newline at end of file diff --git a/Mage.Server/plugins/mage-player-ai-ma.jar b/Mage.Server/plugins/mage-player-ai-ma.jar index 04b9b53e50..0e4bd9abc1 100644 Binary files a/Mage.Server/plugins/mage-player-ai-ma.jar and b/Mage.Server/plugins/mage-player-ai-ma.jar differ diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java index d988000541..fc6dfbcaaa 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java @@ -37,12 +37,15 @@ import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.condition.common.CastFromHandCondition; import mage.abilities.condition.common.HasCounterCondition; import mage.abilities.costs.common.RemoveCountersSourceCost; import mage.abilities.decorator.ConditionalContinousEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.continious.GainAbilitySourceEffect; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; import mage.cards.Card; import mage.cards.CardImpl; @@ -54,7 +57,6 @@ import mage.watchers.Watcher; import mage.watchers.common.CastFromHandWatcher; /** - * * @author Loki */ public class MyojinOfCleansingFire extends CardImpl { @@ -77,7 +79,7 @@ public class MyojinOfCleansingFire extends CardImpl { this.addWatcher(new CastFromHandWatcher()); // Myojin of Cleansing Fire enters the battlefield with a divinity counter on it if you cast it from your hand. - this.addAbility(new EntersBattlefieldAbility(new MyojinOfCleansingFireEntersBattlefieldEffect(), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); + this.addAbility(new EntersBattlefieldAbility(new ConditionalOneShotEffect(new AddCountersSourceEffect(CounterType.DIVINITY.createInstance()), new CastFromHandCondition(), ""), "{this} enters the battlefield with a divinity counter on it if you cast it from your hand")); // Myojin of Cleansing Fire is indestructible as long as it has a divinity counter on it. this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new ConditionalContinousEffect(new GainAbilitySourceEffect(IndestructibleAbility.getInstance(), Constants.Duration.WhileOnBattlefield), new HasCounterCondition(CounterType.DIVINITY), "{this} is indestructible as long as it has a divinity counter on it"))); @@ -94,33 +96,3 @@ public class MyojinOfCleansingFire extends CardImpl { return new MyojinOfCleansingFire(this); } } - -class MyojinOfCleansingFireEntersBattlefieldEffect extends OneShotEffect { - MyojinOfCleansingFireEntersBattlefieldEffect() { - super(Constants.Outcome.Benefit); - } - - MyojinOfCleansingFireEntersBattlefieldEffect(final MyojinOfCleansingFireEntersBattlefieldEffect effect) { - super(effect); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { - Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId()); - if (watcher != null && watcher.conditionMet()) { - p.addCounters(CounterType.DIVINITY.createInstance(), game); - } - } - return true; - } - - @Override - public MyojinOfCleansingFireEntersBattlefieldEffect copy() { - return new MyojinOfCleansingFireEntersBattlefieldEffect(this); - } -} - - - diff --git a/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java new file mode 100644 index 0000000000..42345c1f5b --- /dev/null +++ b/Mage/src/mage/abilities/condition/common/CastFromHandCondition.java @@ -0,0 +1,26 @@ +package mage.abilities.condition.common; + +import mage.abilities.Ability; +import mage.abilities.condition.Condition; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.watchers.Watcher; + +/** + * Warning: CastFromHandWatcher must be installed to card for proper working. + * + * @author Loki + */ +public class CastFromHandCondition implements Condition { + @Override + public boolean apply(Game game, Ability source) { + Permanent p = game.getPermanent(source.getSourceId()); + if (p != null) { + Watcher watcher = game.getState().getWatchers().get("CastFromHand", source.getSourceId()); + if (watcher != null && watcher.conditionMet()) { + return true; + } + } + return false; + } +}