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);
+ }
}