From 4acffc60cd46a14eba49d0e44710bff1daaf875d Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Sat, 16 Mar 2013 10:04:39 +0000 Subject: [PATCH] scry now uses player controllers to learn player's choice, method player.scry() moved to ScryEffect Human uses GuiChoice.order to arrange cards to be put on top or bottom of library (that means less popping windows) AI has a method in ComputerUtil to learn where to put a given card. --- .../card/ability/effects/ScryEffect.java | 40 ++++++++++++++++++- src/main/java/forge/game/ai/ComputerUtil.java | 16 ++++++++ src/main/java/forge/game/player/AIPlayer.java | 36 ----------------- .../java/forge/game/player/HumanPlayer.java | 25 ------------ src/main/java/forge/game/player/Player.java | 32 ++------------- .../forge/game/player/PlayerController.java | 3 ++ .../forge/game/player/PlayerControllerAi.java | 21 ++++++++++ .../game/player/PlayerControllerHuman.java | 9 +++++ 8 files changed, 92 insertions(+), 90 deletions(-) diff --git a/src/main/java/forge/card/ability/effects/ScryEffect.java b/src/main/java/forge/card/ability/effects/ScryEffect.java index 714f389fa39..72e22124e8a 100644 --- a/src/main/java/forge/card/ability/effects/ScryEffect.java +++ b/src/main/java/forge/card/ability/effects/ScryEffect.java @@ -1,12 +1,19 @@ package forge.card.ability.effects; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import forge.Card; import forge.card.ability.AbilityUtils; import forge.card.ability.SpellAbilityEffect; import forge.card.spellability.SpellAbility; import forge.card.spellability.Target; import forge.game.player.Player; +import forge.game.zone.PlayerZone; +import forge.game.zone.ZoneType; public class ScryEffect extends SpellAbilityEffect { @@ -42,7 +49,38 @@ public class ScryEffect extends SpellAbilityEffect { for (final Player p : tgtPlayers) { if ((tgt == null) || p.canBeTargetedBy(sa)) { - p.scry(num); + scry(p, num); + } + } + } + + /** + *

+ * scry. + *

+ * + * @param numScry + * a int. + */ + public final void scry(Player p, int numScry) { + final List topN = new ArrayList(); + final PlayerZone library = p.getZone(ZoneType.Library); + numScry = Math.min(numScry, library.size()); + for (int i = 0; i < numScry; i++) { + topN.add(library.get(i)); + } + + ImmutablePair, List> lists = p.getController().arrangeForScry(topN); + + for(Card c : lists.getRight()) { + p.getGame().getAction().moveToBottomOfLibrary(c); + } + + List toTop = lists.getLeft(); + if ( null != toTop ) { + Collections.reverse(toTop); // the last card in list will become topmost in library, have to revert thus. + for(Card c : toTop) { + p.getGame().getAction().moveToLibrary(c); } } } diff --git a/src/main/java/forge/game/ai/ComputerUtil.java b/src/main/java/forge/game/ai/ComputerUtil.java index 5d3cf8d97f9..b8d8ad5b8cc 100644 --- a/src/main/java/forge/game/ai/ComputerUtil.java +++ b/src/main/java/forge/game/ai/ComputerUtil.java @@ -24,6 +24,7 @@ import java.util.Random; import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; import forge.Card; import forge.CardLists; @@ -1223,4 +1224,19 @@ public class ComputerUtil { return (handList.size() > AI_MULLIGAN_THRESHOLD) && hasLittleCmc0Cards; } + + + public static boolean scryWillMoveCardToBottomOfLibrary(AIPlayer player, Card c) { + boolean bottom = false; + if (c.isBasicLand()) { + List bl = player.getCardsIn(ZoneType.Battlefield); + int nBasicLands = Iterables.size(Iterables.filter(bl, CardPredicates.Presets.BASIC_LANDS)); + bottom = nBasicLands > 5; // if control more than 5 Basic land, probably don't need more + } else if (c.isCreature()) { + List cl = player.getCardsIn(ZoneType.Battlefield); + cl = CardLists.filter(cl, CardPredicates.Presets.CREATURES); + bottom = cl.size() > 5; // if control more than 5 Creatures, probably don't need more + } + return bottom; + } } diff --git a/src/main/java/forge/game/player/AIPlayer.java b/src/main/java/forge/game/player/AIPlayer.java index 066b2482a67..fd928405cc8 100644 --- a/src/main/java/forge/game/player/AIPlayer.java +++ b/src/main/java/forge/game/player/AIPlayer.java @@ -20,7 +20,6 @@ package forge.game.player; import java.util.List; import java.util.Random; -import com.google.common.collect.Iterables; import forge.Card; import forge.CardLists; @@ -135,41 +134,6 @@ public class AIPlayer extends Player { // ///////////////////////// - /** {@inheritDoc} */ - @Override - protected final void doScry(final List topN, final int n) { - int num = n; - for (int i = 0; i < num; i++) { - boolean bottom = false; - if (topN.get(i).isBasicLand()) { - List bl = this.getCardsIn(ZoneType.Battlefield); - int nBasicLands = Iterables.size(Iterables.filter(bl, CardPredicates.Presets.BASIC_LANDS)); - - bottom = nBasicLands > 5; // if control more than 5 Basic land, - // probably don't need more - } else if (topN.get(i).isCreature()) { - List cl = this.getCardsIn(ZoneType.Battlefield); - cl = CardLists.filter(cl, CardPredicates.Presets.CREATURES); - bottom = cl.size() > 5; // if control more than 5 Creatures, - // probably don't need more - } - if (bottom) { - final Card c = topN.get(i); - game.getAction().moveToBottomOfLibrary(c); - // topN.remove(c); - } - } - num = topN.size(); - // put the rest on top in random order - for (int i = 0; i < num; i++) { - final Random rndm = MyRandom.getRandom(); - final int r = rndm.nextInt(topN.size()); - final Card c = topN.get(r); - game.getAction().moveToLibrary(c); - topN.remove(r); - } - } - /** {@inheritDoc} */ @Override public final void sacrificePermanent(final String prompt, final List choices) { diff --git a/src/main/java/forge/game/player/HumanPlayer.java b/src/main/java/forge/game/player/HumanPlayer.java index fe39a66595b..6fc76bb1463 100644 --- a/src/main/java/forge/game/player/HumanPlayer.java +++ b/src/main/java/forge/game/player/HumanPlayer.java @@ -117,31 +117,6 @@ public class HumanPlayer extends Player { Singletons.getModel().getMatch().getInput().setInputInterrupt(PlayerUtil.inputChainsDiscard()); } - /** {@inheritDoc} */ - @Override - protected final void doScry(final List topN, final int n) { - int num = n; - for (int i = 0; i < num; i++) { - final Card c = GuiChoose.oneOrNone("Put on bottom of library.", topN); - if (c != null) { - topN.remove(c); - game.getAction().moveToBottomOfLibrary(c); - } else { - // no card chosen for the bottom - break; - } - } - num = topN.size(); - for (int i = 0; i < num; i++) { - final Card c = GuiChoose.one("Put on top of library.", topN); - if (c != null) { - topN.remove(c); - game.getAction().moveToLibrary(c); - } - // no else - a card must have been chosen - } - } - /** {@inheritDoc} */ @Override public final void sacrificePermanent(final String prompt, final List choices) { diff --git a/src/main/java/forge/game/player/Player.java b/src/main/java/forge/game/player/Player.java index 4e16c286a29..b6098f654bb 100644 --- a/src/main/java/forge/game/player/Player.java +++ b/src/main/java/forge/game/player/Player.java @@ -192,6 +192,10 @@ public abstract class Player extends GameEntity implements Comparable { this.setName(lobbyPlayer.getName()); } + public GameState getGame() { // I'll probably regret about this + return game; + } + public final PlayerStatistics getStats() { return stats; } @@ -1844,35 +1848,7 @@ public abstract class Player extends GameEntity implements Comparable { // ////////////////////////////// // ////////////////////////////// - /** - *

- * doScry. - *

- * - * @param topN - * a {@link forge.CardList} object. - * @param n - * a int. - */ - protected abstract void doScry(List topN, int n); - /** - *

- * scry. - *

- * - * @param numScry - * a int. - */ - public final void scry(int numScry) { - final List topN = new ArrayList(); - final PlayerZone library = this.getZone(ZoneType.Library); - numScry = Math.min(numScry, library.size()); - for (int i = 0; i < numScry; i++) { - topN.add(library.get(i)); - } - this.doScry(topN, topN.size()); - } // ///////////////////////////// diff --git a/src/main/java/forge/game/player/PlayerController.java b/src/main/java/forge/game/player/PlayerController.java index bc3fc07cb41..4a5352cf301 100644 --- a/src/main/java/forge/game/player/PlayerController.java +++ b/src/main/java/forge/game/player/PlayerController.java @@ -3,6 +3,8 @@ package forge.game.player; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.tuple.ImmutablePair; + import forge.Card; import forge.GameEntity; import forge.card.spellability.SpellAbility; @@ -104,4 +106,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); } diff --git a/src/main/java/forge/game/player/PlayerControllerAi.java b/src/main/java/forge/game/player/PlayerControllerAi.java index 696043136cc..c179c49a099 100644 --- a/src/main/java/forge/game/player/PlayerControllerAi.java +++ b/src/main/java/forge/game/player/PlayerControllerAi.java @@ -1,8 +1,12 @@ package forge.game.player; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.tuple.ImmutablePair; + import forge.Card; import forge.GameEntity; import forge.card.spellability.Spell; @@ -228,4 +232,21 @@ public class PlayerControllerAi extends PlayerController { // We don't know how to reveal cards to AI } + @Override + public ImmutablePair, List> arrangeForScry(List topN) { + List toBottom = new ArrayList(); + List toTop = new ArrayList(); + + for (Card c: topN) { + if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c)) + toBottom.add(c); + else + toTop.add(c); + } + + // put the rest on top in random order + Collections.shuffle(toTop); + return ImmutablePair.of(toTop, toBottom); + } + } diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index 1bd07544911..4c483c25291 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -8,6 +8,7 @@ import java.util.Map; import javax.swing.JOptionPane; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; import forge.Card; import forge.GameEntity; @@ -288,4 +289,12 @@ public class PlayerControllerHuman extends PlayerController { message = String.format("Looking at %s's %s", owner, zone); GuiChoose.oneOrNone(message, cards); } + + @Override + public ImmutablePair, List> arrangeForScry(List topN) { + List toBottom = GuiChoose.order("Select cards to be put on the bottom of your library", "Cards to put on the bottom", -1, topN, null, null); + topN.removeAll(toBottom); + 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); + } }