removed clash code from Player class, since it's referenced only from ClashEffect.java

Improved GuiDialog.confirm to accept custom values for choice options 
Also added default question icon to dialogs (may remove if it's too ugly)
decision-making about "where to put the card used to clash" moved to PlayerController* classes
This commit is contained in:
Maxmtg
2013-03-16 10:35:38 +00:00
parent ea78324d15
commit c96304666d
8 changed files with 117 additions and 142 deletions

View File

@@ -2,6 +2,9 @@ package forge.card.ability.effects;
import java.util.HashMap; import java.util.HashMap;
import javax.swing.JOptionPane;
import forge.Card;
import forge.Singletons; import forge.Singletons;
import forge.card.ability.AbilityFactory; import forge.card.ability.AbilityFactory;
import forge.card.ability.AbilityUtils; import forge.card.ability.AbilityUtils;
@@ -9,6 +12,10 @@ import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.AbilitySub; import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.trigger.TriggerType; 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 { public class ClashEffect extends SpellAbilityEffect {
@@ -25,7 +32,7 @@ public class ClashEffect extends SpellAbilityEffect {
*/ */
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final boolean victory = sa.getSourceCard().getController().clashWithOpponent(sa.getSourceCard()); final boolean victory = clashWithOpponent(sa.getSourceCard());
// Run triggers // Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>(); final HashMap<String, Object> runParams = new HashMap<String, Object>();
@@ -56,4 +63,85 @@ public class ClashEffect extends SpellAbilityEffect {
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Clashed, runParams, false); Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Clashed, runParams, false);
} }
/**
* <p>
* clashWithOpponent.
* </p>
*
* @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
}
} }

View File

@@ -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) * (non-Javadoc)
* *

View File

@@ -29,7 +29,6 @@ import forge.game.GameState;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiChoose; import forge.gui.GuiChoose;
import forge.gui.GuiDialog; import forge.gui.GuiDialog;
import forge.gui.match.CMatchUI;
import forge.quest.QuestController; import forge.quest.QuestController;
import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestItemType;
@@ -124,21 +123,6 @@ public class HumanPlayer extends Player {
Singletons.getModel().getMatch().getInput().setInput(in); 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) /* (non-Javadoc)
* @see forge.game.player.Player#getType() * @see forge.game.player.Player#getType()
*/ */

View File

@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import javax.swing.JOptionPane;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@@ -2673,87 +2672,6 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
this.lifeLostThisTurn = n; this.lifeLostThisTurn = n;
} }
// //////////////////////////////
//
// Clash
//
// ///////////////////////////////
/**
* <p>
* clashWithOpponent.
* </p>
*
* @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;
}
}
/**
* <p>
* clashMoveToTopOrBottom.
* </p>
*
* @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 * a Player or Planeswalker that this Player must attack if able in an
* upcoming combat. This is cleared at the end of each combat. * upcoming combat. This is cleared at the end of each combat.

View File

@@ -107,4 +107,5 @@ public abstract class PlayerController {
/** Shows the card to this player*/ /** Shows the card to this player*/
public abstract void reveal(String string, List<Card> cards, ZoneType zone, Player owner); public abstract void reveal(String string, List<Card> cards, ZoneType zone, Player owner);
public abstract ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN); public abstract ImmutablePair<List<Card>, List<Card>> arrangeForScry(List<Card> topN);
public abstract boolean willPutCardOnTop(Card c);
} }

View File

@@ -249,4 +249,10 @@ public class PlayerControllerAi extends PlayerController {
return ImmutablePair.of(toTop, toBottom); 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)
}
} }

View File

@@ -297,4 +297,10 @@ public class PlayerControllerHuman extends PlayerController {
List<Card> toTop = topN.isEmpty() ? null : GuiChoose.order("Arrange cards to be put on top of your library", "Cards arranged", 0, topN, null, null); List<Card> 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); 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"} );
}
} }

View File

@@ -15,35 +15,18 @@ import forge.util.MyRandom;
*/ */
public class GuiDialog { public class GuiDialog {
/** private static final String[] defaultConfirmOptions = { "Yes", "No" };
* <p>
* showYesNoDialog.
* </p>
*
* @param c
* a {@link forge.Card} object.
* @param question
* a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean confirm(final Card c, final String question) { public static boolean confirm(final Card c, final String question) {
return GuiDialog.confirm(c, question, true); return GuiDialog.confirm(c, question, true, null);
}
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) {
* <p>
* showYesNoDialog.
* </p>
*
* @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) {
CMatchUI.SINGLETON_INSTANCE.setCard(c); CMatchUI.SINGLETON_INSTANCE.setCard(c);
final StringBuilder title = new StringBuilder(); final StringBuilder title = new StringBuilder();
if ( c != null) if ( c != null)
@@ -54,13 +37,10 @@ public class GuiDialog {
} }
int answer; int answer;
if (!defaultChoice) {
final Object[] options = { "Yes", "No" }; String[] opts = options == null ? defaultConfirmOptions : options;
answer = JOptionPane.showOptionDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION, answer = JOptionPane.showOptionDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE, null, options, options[1]); JOptionPane.QUESTION_MESSAGE, null, opts, opts[defaultIsYes ? 0 : 1]);
} else {
answer = JOptionPane.showConfirmDialog(null, question, title.toString(), JOptionPane.YES_NO_OPTION);
}
return answer == JOptionPane.YES_OPTION; return answer == JOptionPane.YES_OPTION;
} }