diff --git a/src/main/java/forge/card/ability/effects/ClashEffect.java b/src/main/java/forge/card/ability/effects/ClashEffect.java index 9bd8d3ad195..965ba615da7 100644 --- a/src/main/java/forge/card/ability/effects/ClashEffect.java +++ b/src/main/java/forge/card/ability/effects/ClashEffect.java @@ -2,6 +2,9 @@ package forge.card.ability.effects; import java.util.HashMap; +import javax.swing.JOptionPane; + +import forge.Card; import forge.Singletons; import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityUtils; @@ -9,6 +12,10 @@ import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.AbilitySub; import forge.card.spellability.SpellAbility; import forge.card.trigger.TriggerType; +import forge.game.GameAction; +import forge.game.player.Player; +import forge.game.zone.PlayerZone; +import forge.game.zone.ZoneType; public class ClashEffect extends SpellAbilityEffect { @@ -25,7 +32,7 @@ public class ClashEffect extends SpellAbilityEffect { */ @Override public void resolve(SpellAbility sa) { - final boolean victory = sa.getSourceCard().getController().clashWithOpponent(sa.getSourceCard()); + final boolean victory = clashWithOpponent(sa.getSourceCard()); // Run triggers final HashMap runParams = new HashMap(); @@ -56,4 +63,85 @@ public class ClashEffect extends SpellAbilityEffect { Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Clashed, runParams, false); } + /** + *

+ * clashWithOpponent. + *

+ * + * @param source + * a {@link forge.Card} object. + * @return a boolean. + */ + public final boolean clashWithOpponent(final Card source) { + /* + * Each clashing player reveals the top card of his or her library, then + * puts that card on the top or bottom. A player wins if his or her card + * had a higher mana cost. + * + * Clash you win or win you don't. There is no tie. + */ + final Player player = source.getController(); + final Player opponent = player.getOpponent(); + final ZoneType lib = ZoneType.Library; + + final PlayerZone pLib = player.getZone(lib); + final PlayerZone oLib = opponent.getZone(lib); + + final StringBuilder reveal = new StringBuilder(); + + Card pCard = null; + Card oCard = null; + + if (pLib.size() > 0) { + pCard = pLib.get(0); + } + if (oLib.size() > 0) { + oCard = oLib.get(0); + } + + if ((pLib.size() == 0) && (oLib.size() == 0)) { + return false; + } else if (pLib.isEmpty()) { + clashMoveToTopOrBottom(opponent, oCard); + return false; + } else if (oLib.isEmpty()) { + clashMoveToTopOrBottom(player, pCard); + return true; + } else { + final int pCMC = pCard.getCMC(); + final int oCMC = oCard.getCMC(); + + // TODO: Split cards will return two CMC values, so both players may become winners of clash + + reveal.append(player).append(" reveals: ").append(pCard.getName()).append(". CMC = ").append(pCMC); + reveal.append("\r\n"); + reveal.append(opponent).append(" reveals: ").append(oCard.getName()).append(". CMC = ").append(oCMC); + reveal.append("\r\n\r\n"); + if (pCMC > oCMC) { + reveal.append(player).append(" wins clash."); + } else { + reveal.append(player).append(" loses clash."); + } + JOptionPane.showMessageDialog(null, reveal.toString(), source.getName(), JOptionPane.PLAIN_MESSAGE); + clashMoveToTopOrBottom(player, pCard); + clashMoveToTopOrBottom(opponent, oCard); + // JOptionPane.showMessageDialog(null, reveal.toString(), + // source.getName(), JOptionPane.PLAIN_MESSAGE); + return pCMC > oCMC; + } + } + + public final void clashMoveToTopOrBottom(final Player p, final Card c) { + GameAction action = p.getGame().getAction(); + boolean putOnTop = p.getController().willPutCardOnTop(c); + if ( putOnTop ) + action.moveToLibrary(c); + else + action.moveToBottomOfLibrary(c); + + // computer just puts the card back until such time it can make a smarter decision + + } + + } diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index fd928405cc8..41271b4b875 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -144,14 +144,6 @@ public class AIPlayer extends Player { } } - /** {@inheritDoc} */ - @Override - protected final void clashMoveToTopOrBottom(final Card c) { - // computer just puts the card back until such time it can make a - // smarter decision - game.getAction().moveToLibrary(c); - } - /* * (non-Javadoc) * diff --git a/src/main/java/forge/game/player/HumanPlayer.java b/src/main/java/forge/game/player/HumanPlayer.java index 6fc76bb1463..dba11169373 100644 --- a/src/main/java/forge/game/player/HumanPlayer.java +++ b/src/main/java/forge/game/player/HumanPlayer.java @@ -29,7 +29,6 @@ import forge.game.GameState; import forge.game.zone.ZoneType; import forge.gui.GuiChoose; import forge.gui.GuiDialog; -import forge.gui.match.CMatchUI; import forge.quest.QuestController; import forge.quest.bazaar.QuestItemType; @@ -124,21 +123,6 @@ public class HumanPlayer extends Player { Singletons.getModel().getMatch().getInput().setInput(in); } - /** {@inheritDoc} */ - @Override - protected final void clashMoveToTopOrBottom(final Card c) { - String choice = ""; - final String[] choices = { "top", "bottom" }; - CMatchUI.SINGLETON_INSTANCE.setCard(c); - choice = GuiChoose.one(c.getName() + " - Top or bottom of Library", choices); - - if (choice.equals("bottom")) { - game.getAction().moveToBottomOfLibrary(c); - } else { - game.getAction().moveToLibrary(c); - } - } - /* (non-Javadoc) * @see forge.game.player.Player#getType() */ diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index b6098f654bb..dd0698f0376 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.Map; import java.util.Random; -import javax.swing.JOptionPane; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -2673,87 +2672,6 @@ public abstract class Player extends GameEntity implements Comparable { this.lifeLostThisTurn = n; } - // ////////////////////////////// - // - // Clash - // - // /////////////////////////////// - - /** - *

- * clashWithOpponent. - *

- * - * @param source - * a {@link forge.Card} object. - * @return a boolean. - */ - public final boolean clashWithOpponent(final Card source) { - /* - * Each clashing player reveals the top card of his or her library, then - * puts that card on the top or bottom. A player wins if his or her card - * had a higher mana cost. - * - * Clash you win or win you don't. There is no tie. - */ - final Player player = source.getController(); - final Player opponent = player.getOpponent(); - final ZoneType lib = ZoneType.Library; - - final PlayerZone pLib = player.getZone(lib); - final PlayerZone oLib = opponent.getZone(lib); - - final StringBuilder reveal = new StringBuilder(); - - Card pCard = null; - Card oCard = null; - - if (pLib.size() > 0) { - pCard = pLib.get(0); - } - if (oLib.size() > 0) { - oCard = oLib.get(0); - } - - if ((pLib.size() == 0) && (oLib.size() == 0)) { - return false; - } else if (pLib.size() == 0) { - opponent.clashMoveToTopOrBottom(oCard); - return false; - } else if (oLib.size() == 0) { - player.clashMoveToTopOrBottom(pCard); - return true; - } else { - final int pCMC = pCard.getCMC(); - final int oCMC = oCard.getCMC(); - reveal.append(player).append(" reveals: ").append(pCard.getName()).append(". CMC = ").append(pCMC); - reveal.append("\r\n"); - reveal.append(opponent).append(" reveals: ").append(oCard.getName()).append(". CMC = ").append(oCMC); - reveal.append("\r\n\r\n"); - if (pCMC > oCMC) { - reveal.append(player).append(" wins clash."); - } else { - reveal.append(player).append(" loses clash."); - } - JOptionPane.showMessageDialog(null, reveal.toString(), source.getName(), JOptionPane.PLAIN_MESSAGE); - player.clashMoveToTopOrBottom(pCard); - opponent.clashMoveToTopOrBottom(oCard); - // JOptionPane.showMessageDialog(null, reveal.toString(), - // source.getName(), JOptionPane.PLAIN_MESSAGE); - return pCMC > oCMC; - } - } - - /** - *

- * clashMoveToTopOrBottom. - *

- * - * @param c - * a {@link forge.Card} object. - */ - protected abstract void clashMoveToTopOrBottom(Card c); - /** * a Player or Planeswalker that this Player must attack if able in an * upcoming combat. This is cleared at the end of each combat. diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index 4a5352cf301..49500052dc2 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -107,4 +107,5 @@ public abstract class PlayerController { /** Shows the card to this player*/ public abstract void reveal(String string, List cards, ZoneType zone, Player owner); public abstract ImmutablePair, List> arrangeForScry(List topN); + public abstract boolean willPutCardOnTop(Card c); } diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index c179c49a099..d6814d8076e 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -249,4 +249,10 @@ public class PlayerControllerAi extends PlayerController { return ImmutablePair.of(toTop, toBottom); } + + @Override + public boolean willPutCardOnTop(Card c) { + return true; // AI does not know what will happen next (another clash or that would become his topdeck) + } + } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 4c483c25291..f0b24d33101 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -297,4 +297,10 @@ public class PlayerControllerHuman extends PlayerController { List toTop = topN.isEmpty() ? null : GuiChoose.order("Arrange cards to be put on top of your library", "Cards arranged", 0, topN, null, null); return ImmutablePair.of(toTop, toBottom); } + + + @Override + public boolean willPutCardOnTop(Card c) { + return GuiDialog.confirm(c, "Where you put " + c.getName() + " in your library", new String[]{"Top", "Bottom"} ); + } } diff --git a/src/main/java/forge/gui/GuiDialog.java b/src/main/java/forge/gui/GuiDialog.java index a8f88b14c7a..cbf60ce3deb 100644 --- a/src/main/java/forge/gui/GuiDialog.java +++ b/src/main/java/forge/gui/GuiDialog.java @@ -15,35 +15,18 @@ import forge.util.MyRandom; */ public class GuiDialog { - /** - *

- * showYesNoDialog. - *

- * - * @param c - * a {@link forge.Card} object. - * @param question - * a {@link java.lang.String} object. - * @return a boolean. - */ + private static final String[] defaultConfirmOptions = { "Yes", "No" }; public static boolean confirm(final Card c, final String question) { - return GuiDialog.confirm(c, question, true); + return GuiDialog.confirm(c, question, true, null); } - - /** - *

- * showYesNoDialog. - *

- * - * @param c - * a {@link forge.Card} object. - * @param question - * a {@link java.lang.String} object. - * @param defaultNo - * true if the default option should be "No", false otherwise - * @return a boolean. - */ - public static boolean confirm(final Card c, String question, final boolean defaultChoice) { + public static boolean confirm(final Card c, final String question, final boolean defaultChoice) { + return GuiDialog.confirm(c, question, defaultChoice, null); + } + public static boolean confirm(final Card c, final String question, String[] options) { + return GuiDialog.confirm(c, question, true, options); + } + + public static boolean confirm(final Card c, String question, final boolean defaultIsYes, final String[] options) { CMatchUI.SINGLETON_INSTANCE.setCard(c); final StringBuilder title = new StringBuilder(); if ( c != null) @@ -54,14 +37,11 @@ public class GuiDialog { } int answer; - if (!defaultChoice) { - final Object[] options = { "Yes", "No" }; - answer = JOptionPane.showOptionDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION, - JOptionPane.PLAIN_MESSAGE, null, options, options[1]); - } else { - answer = JOptionPane.showConfirmDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION); - } - + + String[] opts = options == null ? defaultConfirmOptions : options; + answer = JOptionPane.showOptionDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, null, opts, opts[defaultIsYes ? 0 : 1]); + return answer == JOptionPane.YES_OPTION; }