mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
other: reworked target selection: (#13638)
- WIP: AI and multi targets, human and X=0 use cases, human and impossible targets use cases;
- improved stability and shared logic (related to #13606, #11134, #11666, continue from a53eb66b58, close #13617, close #13613);
- improved test logs and debug info to show more target info on errors;
- improved test framework to support multiple addTarget calls;
- improved test framework to find bad commands order for targets (related to #11666);
- fixed game freezes on auto-choice usages with disconnected or under control players (related to #11285);
- gui, game: fixed that player doesn't mark avatar as selected/green in "up to" targeting;
- gui, game: fixed small font in some popup messages on big screens (related to #969);
- gui, game: added min targets info for target selection dialog;
- for devs: added new cheat option to call and test any game dialog (define own dialogs, targets, etc in HumanDialogsTester);
- for devs: now tests require complete an any or up to target selection by addTarget + TestPlayer.TARGET_SKIP or setChoice + TestPlayer.CHOICE_SKIP (if not all max/possible targets used);
- for devs: added detail targets info for activate/trigger/cast, can be useful to debug unit tests, auto-choose or AI (see DebugUtil.GAME_SHOW_CHOOSE_TARGET_LOGS)
This commit is contained in:
parent
80d62727e1
commit
133e4fe425
84 changed files with 2737 additions and 743 deletions
|
|
@ -28,6 +28,7 @@ import mage.target.common.TargetOpponent;
|
|||
import mage.util.CardUtil;
|
||||
import mage.util.MultiAmountMessage;
|
||||
import mage.util.RandomUtil;
|
||||
import mage.utils.testers.TestableDialogsRunner;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
|
@ -69,6 +70,7 @@ public final class SystemUtil {
|
|||
private static final String COMMAND_LANDS_ADD_TO_BATTLEFIELD = "@lands add";
|
||||
private static final String COMMAND_UNDER_CONTROL_TAKE = "@under control take";
|
||||
private static final String COMMAND_UNDER_CONTROL_GIVE = "@under control give";
|
||||
private static final String COMMAND_SHOW_TEST_DIALOGS = "@show dialog";
|
||||
private static final String COMMAND_MANA_ADD = "@mana add"; // TODO: not implemented
|
||||
private static final String COMMAND_RUN_CUSTOM_CODE = "@run custom code"; // TODO: not implemented
|
||||
private static final String COMMAND_SHOW_OPPONENT_HAND = "@show opponent hand";
|
||||
|
|
@ -76,6 +78,7 @@ public final class SystemUtil {
|
|||
private static final String COMMAND_SHOW_MY_HAND = "@show my hand";
|
||||
private static final String COMMAND_SHOW_MY_LIBRARY = "@show my library";
|
||||
private static final Map<String, String> supportedCommands = new HashMap<>();
|
||||
private static final TestableDialogsRunner testableDialogsRunner = new TestableDialogsRunner(); // for tests
|
||||
|
||||
static {
|
||||
// special commands names in choose dialog
|
||||
|
|
@ -89,6 +92,7 @@ public final class SystemUtil {
|
|||
supportedCommands.put(COMMAND_SHOW_OPPONENT_LIBRARY, "SHOW OPPONENT LIBRARY");
|
||||
supportedCommands.put(COMMAND_SHOW_MY_HAND, "SHOW MY HAND");
|
||||
supportedCommands.put(COMMAND_SHOW_MY_LIBRARY, "SHOW MY LIBRARY");
|
||||
supportedCommands.put(COMMAND_SHOW_TEST_DIALOGS, "SHOW TEST DIALOGS");
|
||||
}
|
||||
|
||||
private static final Pattern patternGroup = Pattern.compile("\\[(.+)\\]"); // [test new card]
|
||||
|
|
@ -263,8 +267,13 @@ public final class SystemUtil {
|
|||
public static void executeCheatCommands(Game game, String commandsFilePath, Player feedbackPlayer) {
|
||||
|
||||
// fake test ability for triggers and events
|
||||
Ability fakeSourceAbilityTemplate = new SimpleStaticAbility(Zone.OUTSIDE, new InfoEffect("adding testing cards"));
|
||||
Ability fakeSourceAbilityTemplate = new SimpleStaticAbility(Zone.OUTSIDE, new InfoEffect("fake ability"));
|
||||
fakeSourceAbilityTemplate.setControllerId(feedbackPlayer.getId());
|
||||
Card fakeSourceCard = feedbackPlayer.getLibrary().getFromTop(game);
|
||||
if (fakeSourceCard != null) {
|
||||
// set any existing card as source, so dialogs will show all GUI elements, including source and workable popup info
|
||||
fakeSourceAbilityTemplate.setSourceId(fakeSourceCard.getId());
|
||||
}
|
||||
|
||||
List<String> errorsList = new ArrayList<>();
|
||||
try {
|
||||
|
|
@ -304,8 +313,9 @@ public final class SystemUtil {
|
|||
// add default commands
|
||||
initLines.add(0, String.format("[%s]", COMMAND_LANDS_ADD_TO_BATTLEFIELD));
|
||||
initLines.add(1, String.format("[%s]", COMMAND_CARDS_ADD_TO_HAND));
|
||||
initLines.add(2, String.format("[%s]", COMMAND_UNDER_CONTROL_TAKE));
|
||||
initLines.add(3, String.format("[%s]", COMMAND_UNDER_CONTROL_GIVE));
|
||||
initLines.add(2, String.format("[%s]", COMMAND_SHOW_TEST_DIALOGS));
|
||||
initLines.add(3, String.format("[%s]", COMMAND_UNDER_CONTROL_TAKE));
|
||||
initLines.add(4, String.format("[%s]", COMMAND_UNDER_CONTROL_GIVE));
|
||||
|
||||
// collect all commands
|
||||
CommandGroup currentGroup = null;
|
||||
|
|
@ -538,6 +548,11 @@ public final class SystemUtil {
|
|||
break;
|
||||
}
|
||||
|
||||
case COMMAND_SHOW_TEST_DIALOGS: {
|
||||
testableDialogsRunner.selectAndShowTestableDialog(feedbackPlayer, fakeSourceAbilityTemplate.copy(), game, opponent);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
String mes = String.format("Unknown system command: %s", runGroup.name);
|
||||
errorsList.add(mes);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.common.TargetPermanentOrPlayer;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
abstract class BaseTestableDialog implements TestableDialog {
|
||||
|
||||
private final String group;
|
||||
private final String name;
|
||||
private final String description;
|
||||
|
||||
public BaseTestableDialog(String group, String name, String description) {
|
||||
this.group = group;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public String getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public void showResult(Player player, Game game, String result) {
|
||||
// show message with result
|
||||
game.informPlayer(player, result);
|
||||
// reset game and gui (in most use cases it must return to player's priority)
|
||||
game.firePriorityEvent(player.getId());
|
||||
}
|
||||
|
||||
static Target createAnyTarget(int min, int max) {
|
||||
return createAnyTarget(min, max, false);
|
||||
}
|
||||
|
||||
private static Target createAnyTarget(int min, int max, boolean notTarget) {
|
||||
return new TargetPermanentOrPlayer(min, max).withNotTarget(notTarget);
|
||||
}
|
||||
|
||||
static Target createCreatureTarget(int min, int max) {
|
||||
return createCreatureTarget(min, max, false);
|
||||
}
|
||||
|
||||
private static Target createCreatureTarget(int min, int max, boolean notTarget) {
|
||||
return new TargetCreaturePermanent(min, max).withNotTarget(notTarget);
|
||||
}
|
||||
|
||||
static Target createImpossibleTarget(int min, int max) {
|
||||
return createImpossibleTarget(min, max, false);
|
||||
}
|
||||
|
||||
private static Target createImpossibleTarget(int min, int max, boolean notTarget) {
|
||||
return new TargetCreaturePermanent(min, max, new FilterCreaturePermanent(SubType.TROOPER, "rare type"), notTarget);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetAmount;
|
||||
import mage.target.Targets;
|
||||
import mage.target.common.TargetAnyTargetAmount;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - player.chooseTarget(amount)
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChooseAmountTestableDialog extends BaseTestableDialog {
|
||||
|
||||
boolean isYou; // who choose - you or opponent
|
||||
int distributeAmount;
|
||||
int targetsMin;
|
||||
int targetsMax;
|
||||
|
||||
public ChooseAmountTestableDialog(boolean isYou, String name, int distributeAmount, int targetsMin, int targetsMax) {
|
||||
super(String.format("player.chooseTarget(%s, amount)", isYou ? "you" : "AI"),
|
||||
name,
|
||||
String.format("%d between %d-%d targets", distributeAmount, targetsMin, targetsMax));
|
||||
this.isYou = isYou;
|
||||
this.distributeAmount = distributeAmount;
|
||||
this.targetsMin = targetsMin;
|
||||
this.targetsMax = targetsMax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
TargetAmount choosingTarget = new TargetAnyTargetAmount(this.distributeAmount, this.targetsMin, this.targetsMax);
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
|
||||
// TODO: add "damage" word in ability text, so chooseTargetAmount an show diff dialog (due inner logic - distribute damage or 1/1)
|
||||
boolean chooseRes = choosingPlayer.chooseTargetAmount(Outcome.Benefit, choosingTarget, source, game);
|
||||
List<String> result = new ArrayList<>();
|
||||
if (chooseRes) {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "TRUE", new Targets(choosingTarget), source, game, result);
|
||||
} else {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "FALSE", new Targets(choosingTarget), source, game, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
// test game started with 2 players and 1 land on battlefield
|
||||
// so it's better to use target limits like 0, 1, 3, 5, max
|
||||
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
|
||||
for (boolean isYou : isYous) {
|
||||
// up to
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 0, 0, 0));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 0, 0, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 0, 0, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 0, 0, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to, invalid", 1, 0, 0));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 1, 0, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 1, 0, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 1, 0, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to, invalid", 2, 0, 0));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 2, 0, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 2, 0, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 2, 0, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to, invalid", 3, 0, 0));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 3, 0, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 3, 0, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 3, 0, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to, invalid", 5, 0, 0));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 5, 0, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 5, 0, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "up to", 5, 0, 5));
|
||||
|
||||
// need target
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 0, 1, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 0, 1, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 0, 1, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 1, 1, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 1, 1, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 1, 1, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 2, 1, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 2, 1, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 2, 1, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 3, 1, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 3, 1, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 3, 1, 5));
|
||||
//
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 5, 1, 1));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 5, 1, 3));
|
||||
runner.registerDialog(new ChooseAmountTestableDialog(isYou, "need", 5, 1, 5));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.Targets;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - player.choose(cards)
|
||||
* - player.chooseTarget(cards)
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChooseCardsTestableDialog extends BaseTestableDialog {
|
||||
|
||||
TargetCard target;
|
||||
boolean isTargetChoice; // how to choose - by xxx.choose or xxx.chooseTarget
|
||||
boolean isYou; // who choose - you or opponent
|
||||
|
||||
public ChooseCardsTestableDialog(boolean isTargetChoice, boolean notTarget, boolean isYou, String name, TargetCard target) {
|
||||
super(String.format("%s(%s, %s, cards)",
|
||||
isTargetChoice ? "player.chooseTarget" : "player.choose",
|
||||
isYou ? "you" : "AI",
|
||||
notTarget ? "not target" : "target"), name, target.toString());
|
||||
this.isTargetChoice = isTargetChoice;
|
||||
this.target = target.withNotTarget(notTarget);
|
||||
this.isYou = isYou;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
TargetCard choosingTarget = this.target.copy();
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
|
||||
// make sure hand go first, so user can test diff type of targets
|
||||
List<Card> all = new ArrayList<>();
|
||||
all.addAll(choosingPlayer.getHand().getCards(game));
|
||||
//all.addAll(choosingPlayer.getLibrary().getCards(game));
|
||||
Cards choosingCards = new CardsImpl(all.stream().limit(100).collect(Collectors.toList()));
|
||||
|
||||
boolean chooseRes;
|
||||
if (this.isTargetChoice) {
|
||||
chooseRes = choosingPlayer.chooseTarget(Outcome.Benefit, choosingCards, choosingTarget, source, game);
|
||||
} else {
|
||||
chooseRes = choosingPlayer.choose(Outcome.Benefit, choosingCards, choosingTarget, source, game);
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
if (chooseRes) {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "TRUE", new Targets(choosingTarget), source, game, result);
|
||||
} else {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "FALSE", new Targets(choosingTarget), source, game, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
// test game started with 2 players and 7 cards in hand and 1 draw
|
||||
// so it's better to use target limits like 0, 1, 3, 9, max
|
||||
|
||||
FilterCard anyCard = StaticFilters.FILTER_CARD;
|
||||
FilterCard impossibleCard = new FilterCard();
|
||||
impossibleCard.add(SubType.TROOPER.getPredicate());
|
||||
|
||||
List<Boolean> notTargets = Arrays.asList(false, true);
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
List<Boolean> isTargetChoices = Arrays.asList(false, true);
|
||||
for (boolean notTarget : notTargets) {
|
||||
for (boolean isYou : isYous) {
|
||||
for (boolean isTargetChoice : isTargetChoices) {
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 0, X=0", new TargetCardInHand(0, 0, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 1", new TargetCardInHand(1, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 3", new TargetCardInHand(3, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 9", new TargetCardInHand(9, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 0-1", new TargetCardInHand(0, 1, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 0-3", new TargetCardInHand(0, 3, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 0-9", new TargetCardInHand(0, 9, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand any", new TargetCardInHand(0, Integer.MAX_VALUE, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 1-3", new TargetCardInHand(1, 3, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 2-3", new TargetCardInHand(2, 3, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 2-9", new TargetCardInHand(2, 9, anyCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "hand 8-9", new TargetCardInHand(8, 9, anyCard)));
|
||||
//
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible 0, X=0", new TargetCardInHand(0, impossibleCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible 1", new TargetCardInHand(1, impossibleCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible 3", new TargetCardInHand(3, impossibleCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible 0-1", new TargetCardInHand(0, 1, impossibleCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible 0-3", new TargetCardInHand(0, 3, impossibleCard)));
|
||||
runner.registerDialog(new ChooseCardsTestableDialog(isTargetChoice, notTarget, isYou, "impossible any", new TargetCardInHand(0, Integer.MAX_VALUE, impossibleCard)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.choices.*;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - player.choose(choice)
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChooseChoiceTestableDialog extends BaseTestableDialog {
|
||||
|
||||
boolean isYou; // who choose - you or opponent
|
||||
Choice choice;
|
||||
|
||||
public ChooseChoiceTestableDialog(boolean isYou, String name, Choice choice) {
|
||||
super(String.format("player.choose(%s, choice)", isYou ? "you" : "AI"), name, choice.getClass().getSimpleName());
|
||||
this.isYou = isYou;
|
||||
this.choice = choice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
Choice dialog = this.choice.copy();
|
||||
boolean chooseRes = choosingPlayer.choose(Outcome.Benefit, dialog, game);
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(getGroup() + " - " + this.getName() + " - " + (chooseRes ? "TRUE" : "FALSE"));
|
||||
result.add("");
|
||||
if (dialog.isKeyChoice()) {
|
||||
String key = dialog.getChoiceKey();
|
||||
result.add(String.format("* selected key: %s (%s)", key, dialog.getKeyChoices().getOrDefault(key, null)));
|
||||
} else {
|
||||
result.add(String.format("* selected value: %s", dialog.getChoice()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
// TODO: add require option
|
||||
// TODO: add ChoiceImpl with diff popup hints
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
for (boolean isYou : isYous) {
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceBasicLandType()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceCardType()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceColor()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceColorOrArtifact()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceCreatureType(null, null))); // TODO: must be dynamic to pass game/source
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceLandType()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoiceLeftOrRight()));
|
||||
runner.registerDialog(new ChooseChoiceTestableDialog(isYou, "", new ChoicePlaneswalkerType())); // TODO: must be dynamic to pass game/source
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - player.choosePile()
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChoosePileTestableDialog extends BaseTestableDialog {
|
||||
|
||||
boolean isYou; // who choose - you or opponent
|
||||
int pileSize1;
|
||||
int pileSize2;
|
||||
|
||||
public ChoosePileTestableDialog(boolean isYou, int pileSize1, int pileSize2) {
|
||||
super(String.format("player.choosePile(%s)", isYou ? "you" : "AI"), "pile sizes: " + pileSize1 + " and " + pileSize2, "");
|
||||
this.isYou = isYou;
|
||||
this.pileSize1 = pileSize1;
|
||||
this.pileSize2 = pileSize2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
// TODO: it's ok to show broken title - must add html support in windows's title someday
|
||||
String mainMessage = "main <font color=green>message</font> with html" + CardUtil.getSourceLogName(game, source);
|
||||
|
||||
// random piles (make sure it contain good amount of cards)
|
||||
List<Card> all = new ArrayList<>(game.getCards());
|
||||
Collections.shuffle(all);
|
||||
List<Card> pile1 = all.stream().limit(this.pileSize1).collect(Collectors.toList());
|
||||
Collections.shuffle(all);
|
||||
List<Card> pile2 = all.stream().limit(this.pileSize2).collect(Collectors.toList());
|
||||
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
boolean chooseRes = choosingPlayer.choosePile(Outcome.Benefit, mainMessage, pile1, pile2, game);
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(getGroup() + " - " + this.getName() + " - " + (chooseRes ? "TRUE" : "FALSE"));
|
||||
result.add(" * selected pile: " + (chooseRes ? "pile 1" : "pile 2"));
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
for (boolean isYou : isYous) {
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 3, 5));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 10, 10));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 30, 30));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 90, 90));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 0, 10));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 10, 0));
|
||||
runner.registerDialog(new ChoosePileTestableDialog(isYou, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.Targets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - target.choose()
|
||||
* - target.chooseTarget()
|
||||
* - player.choose(target)
|
||||
* - player.chooseTarget(target)
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChooseTargetTestableDialog extends BaseTestableDialog {
|
||||
|
||||
Target target;
|
||||
boolean isPlayerChoice; // how to choose - by player.choose or by target.choose
|
||||
boolean isTargetChoice; // how to choose - by xxx.choose or xxx.chooseTarget
|
||||
boolean isYou; // who choose - you or opponent
|
||||
|
||||
public ChooseTargetTestableDialog(boolean isPlayerChoice, boolean isTargetChoice, boolean notTarget, boolean isYou, String name, Target target) {
|
||||
super(String.format("%s%s(%s, %s)",
|
||||
isPlayerChoice ? "player.choose" : "target.choose",
|
||||
isTargetChoice ? "target" : "", // chooseTarget or choose
|
||||
isYou ? "you" : "AI",
|
||||
notTarget ? "not target" : "target"), name, target.toString());
|
||||
this.isPlayerChoice = isPlayerChoice;
|
||||
this.isTargetChoice = isTargetChoice;
|
||||
this.target = target.withNotTarget(notTarget);
|
||||
this.isYou = isYou;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
Target choosingTarget = this.target.copy();
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
|
||||
boolean chooseRes;
|
||||
if (this.isPlayerChoice) {
|
||||
// player.chooseXXX
|
||||
if (this.isTargetChoice) {
|
||||
chooseRes = choosingPlayer.chooseTarget(Outcome.Benefit, choosingTarget, source, game);
|
||||
} else {
|
||||
chooseRes = choosingPlayer.choose(Outcome.Benefit, choosingTarget, source, game);
|
||||
}
|
||||
} else {
|
||||
// target.chooseXXX
|
||||
if (this.isTargetChoice) {
|
||||
chooseRes = choosingTarget.chooseTarget(Outcome.Benefit, choosingPlayer.getId(), source, game);
|
||||
} else {
|
||||
chooseRes = choosingTarget.choose(Outcome.Benefit, choosingPlayer.getId(), source, game);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
if (chooseRes) {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "TRUE", new Targets(choosingTarget), source, game, result);
|
||||
} else {
|
||||
Targets.printDebugTargets(getGroup() + " - " + this.getName() + " - " + "FALSE", new Targets(choosingTarget), source, game, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
// test game started with 2 players and 1 land on battlefield
|
||||
// so it's better to use target limits like 0, 1, 3, 5, max
|
||||
|
||||
List<Boolean> notTargets = Arrays.asList(false, true);
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
List<Boolean> isPlayerChoices = Arrays.asList(false, true);
|
||||
List<Boolean> isTargetChoices = Arrays.asList(false, true);
|
||||
for (boolean notTarget : notTargets) {
|
||||
for (boolean isYou : isYous) {
|
||||
for (boolean isTargetChoice : isTargetChoices) {
|
||||
for (boolean isPlayerChoice : isPlayerChoices) {
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 0 e.g. X=0", createAnyTarget(0, 0))); // simulate X=0
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 1", createAnyTarget(1, 1)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 3", createAnyTarget(3, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 5", createAnyTarget(5, 5)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any max", createAnyTarget(0, Integer.MAX_VALUE)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 0-1", createAnyTarget(0, 1)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 0-3", createAnyTarget(0, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 0-5", createAnyTarget(0, 5)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 1-3", createAnyTarget(1, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 2-3", createAnyTarget(2, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 1-5", createAnyTarget(1, 5)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 2-5", createAnyTarget(2, 5)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 3-5", createAnyTarget(3, 5)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "any 4-5", createAnyTarget(4, 5))); // impossible on 3 targets
|
||||
//
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 0, e.g. X=0", createImpossibleTarget(0, 0)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 1", createImpossibleTarget(1, 1)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 3", createImpossibleTarget(3, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 0-1", createImpossibleTarget(0, 1)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 0-3", createImpossibleTarget(0, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 1-3", createImpossibleTarget(1, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible 2-3", createImpossibleTarget(2, 3)));
|
||||
runner.registerDialog(new ChooseTargetTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "impossible max", createImpossibleTarget(0, Integer.MAX_VALUE)));
|
||||
//
|
||||
/*
|
||||
runner.registerDialog(new PlayerChooseTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "creatures 0, e.g. X=0", createCreatureTarget(0, 0))); // simulate X=0
|
||||
runner.registerDialog(new PlayerChooseTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "creatures 1", createCreatureTarget(1, 1)));
|
||||
runner.registerDialog(new PlayerChooseTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "creatures 3", createCreatureTarget(3, 3)));
|
||||
runner.registerDialog(new PlayerChooseTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "creatures 5", createCreatureTarget(5, 5)));
|
||||
runner.registerDialog(new PlayerChooseTestableDialog(isPlayerChoice, isTargetChoice, notTarget, isYou, "creatures max", createCreatureTarget(0, Integer.MAX_VALUE)));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Supported methods:
|
||||
* - player.chooseUse()
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
class ChooseUseTestableDialog extends BaseTestableDialog {
|
||||
|
||||
boolean isYou; // who choose - you or opponent
|
||||
String trueText;
|
||||
String falseText;
|
||||
String messageMain;
|
||||
String messageAdditional;
|
||||
|
||||
public ChooseUseTestableDialog(boolean isYou, String name, String trueText, String falseText, String messageMain, String messageAdditional) {
|
||||
super(String.format("player.chooseUse(%s)", isYou ? "you" : "AI"), name + buildName(trueText, falseText, messageMain, messageAdditional), "");
|
||||
this.isYou = isYou;
|
||||
this.trueText = trueText;
|
||||
this.falseText = falseText;
|
||||
this.messageMain = messageMain;
|
||||
this.messageAdditional = messageAdditional;
|
||||
}
|
||||
|
||||
private static String buildName(String trueText, String falseText, String messageMain, String messageAdditional) {
|
||||
String buttonsInfo = (trueText == null ? "default" : "custom") + "/" + (falseText == null ? "default" : "custom");
|
||||
String messagesInfo = (messageMain == null ? "-" : "main") + "/" + (messageAdditional == null ? "-" : "additional");
|
||||
return String.format("buttons: %s, messages: %s", buttonsInfo, messagesInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> showDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
Player choosingPlayer = this.isYou ? player : opponent;
|
||||
boolean chooseRes = choosingPlayer.chooseUse(
|
||||
Outcome.Benefit,
|
||||
messageMain,
|
||||
messageAdditional == null ? null : messageAdditional + CardUtil.getSourceLogName(game, source),
|
||||
trueText,
|
||||
falseText,
|
||||
source,
|
||||
game
|
||||
);
|
||||
List<String> result = new ArrayList<>();
|
||||
result.add(chooseRes ? "TRUE" : "FALSE");
|
||||
return result;
|
||||
}
|
||||
|
||||
static public void register(TestableDialogsRunner runner) {
|
||||
List<Boolean> isYous = Arrays.asList(false, true);
|
||||
String trueButton = "true button";
|
||||
String falseButton = "false button";
|
||||
String mainMessage = "main <font color=green>message</font> with html";
|
||||
String additionalMessage = "additional main <font color=red>message</font> with html";
|
||||
for (boolean isYou : isYous) {
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "", null, null, mainMessage, additionalMessage));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "", trueButton, falseButton, mainMessage, additionalMessage));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "", null, falseButton, mainMessage, additionalMessage));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "", trueButton, null, mainMessage, additionalMessage));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "error ", trueButton, falseButton, null, additionalMessage));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "", trueButton, falseButton, mainMessage, null));
|
||||
runner.registerDialog(new ChooseUseTestableDialog(isYou, "error ", trueButton, falseButton, null, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* How to use:
|
||||
* - extends BaseTestableDialog
|
||||
* - implement showDialog
|
||||
* - create register with all possible sample dialogs
|
||||
* - call register in main runner's constructor
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
interface TestableDialog {
|
||||
|
||||
String getGroup();
|
||||
|
||||
String getName();
|
||||
|
||||
String getDescription();
|
||||
|
||||
List<String> showDialog(Player player, Ability source, Game game, Player opponent);
|
||||
|
||||
void showResult(Player player, Game game, String result);
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
package mage.utils.testers;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceHintType;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Part of testable game dialogs
|
||||
* <p>
|
||||
* Helper class to create additional options in cheat menu - allow to test any game dialogs with any settings
|
||||
* Allow to call game dialogs from you or from your opponent, e.g. from AI player
|
||||
* <p>
|
||||
* All existing human's choose dialogs (search by waitForResponse):
|
||||
* <p>
|
||||
* Support of single dialogs (can be called inside effects):
|
||||
* [x] choose(target)
|
||||
* [x] choose(cards)
|
||||
* [x] choose(choice)
|
||||
* [x] chooseTarget(target)
|
||||
* [x] chooseTarget(cards)
|
||||
* [x] chooseTargetAmount
|
||||
* [x] chooseUse
|
||||
* [x] choosePile
|
||||
* [ ] announceXMana // TODO: implement
|
||||
* [ ] announceXCost // TODO: implement
|
||||
* [ ] getAmount // TODO: implement
|
||||
* [ ] getMultiAmountWithIndividualConstraints // TODO: implement
|
||||
* <p>
|
||||
* Support of priority dialogs (can be called by game engine, some can be implemented in theory):
|
||||
* --- priority
|
||||
* --- playManaHandling
|
||||
* --- activateSpecialAction
|
||||
* --- activateAbility
|
||||
* --- chooseAbilityForCast
|
||||
* --- chooseLandOrSpellAbility
|
||||
* --- chooseMode
|
||||
* --- chooseMulligan
|
||||
* --- chooseReplacementEffect
|
||||
* --- chooseTriggeredAbility
|
||||
* --- selectAttackers
|
||||
* --- selectBlockers
|
||||
* --- selectCombatGroup (part of selectBlockers)
|
||||
* <p>
|
||||
* Support of outdated dialogs (not used anymore)
|
||||
* --- announceRepetitions (part of removed macro feature)
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class TestableDialogsRunner {
|
||||
|
||||
private final List<TestableDialog> dialogs = new ArrayList<>();
|
||||
|
||||
static final int LAST_SELECTED_GROUP_ID = 997;
|
||||
static final int LAST_SELECTED_DIALOG_ID = 998;
|
||||
|
||||
// for better UX - save last selected options, so can return to it later
|
||||
// it's ok to have it global, cause test mode for local and single user environment
|
||||
static String lastSelectedGroup = null;
|
||||
static TestableDialog lastSelectedDialog = null;
|
||||
|
||||
|
||||
public TestableDialogsRunner() {
|
||||
ChooseTargetTestableDialog.register(this);
|
||||
ChooseCardsTestableDialog.register(this);
|
||||
ChooseUseTestableDialog.register(this);
|
||||
ChooseChoiceTestableDialog.register(this);
|
||||
ChoosePileTestableDialog.register(this);
|
||||
ChooseAmountTestableDialog.register(this);
|
||||
}
|
||||
|
||||
void registerDialog(TestableDialog dialog) {
|
||||
this.dialogs.add(dialog);
|
||||
}
|
||||
|
||||
public void selectAndShowTestableDialog(Player player, Ability source, Game game, Player opponent) {
|
||||
// select group or fast links
|
||||
List<String> groups = this.dialogs.stream()
|
||||
.map(TestableDialog::getGroup)
|
||||
.distinct()
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
Choice choice = prepareSelectGroupChoice(groups);
|
||||
player.choose(Outcome.Benefit, choice, game);
|
||||
String needGroup = null;
|
||||
TestableDialog needDialog = null;
|
||||
if (choice.getChoiceKey() != null) {
|
||||
int needIndex = Integer.parseInt(choice.getChoiceKey());
|
||||
if (needIndex == LAST_SELECTED_GROUP_ID && lastSelectedGroup != null) {
|
||||
// fast link to group
|
||||
needGroup = lastSelectedGroup;
|
||||
} else if (needIndex == LAST_SELECTED_DIALOG_ID && lastSelectedDialog != null) {
|
||||
// fast link to dialog
|
||||
needGroup = lastSelectedDialog.getGroup();
|
||||
needDialog = lastSelectedDialog;
|
||||
} else if (needIndex < groups.size()) {
|
||||
// group
|
||||
needGroup = groups.get(needIndex);
|
||||
}
|
||||
}
|
||||
if (needGroup == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// select dialog
|
||||
if (needDialog == null) {
|
||||
choice = prepareSelectDialogChoice(needGroup);
|
||||
player.choose(Outcome.Benefit, choice, game);
|
||||
if (choice.getChoiceKey() != null) {
|
||||
int needIndex = Integer.parseInt(choice.getChoiceKey());
|
||||
if (needIndex < this.dialogs.size()) {
|
||||
needDialog = this.dialogs.get(needIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needDialog == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// all fine, can show it and finish
|
||||
lastSelectedGroup = needGroup;
|
||||
lastSelectedDialog = needDialog;
|
||||
List<String> resInfo = needDialog.showDialog(player, source, game, opponent);
|
||||
needDialog.showResult(player, game, String.join("<br>", resInfo));
|
||||
}
|
||||
|
||||
private Choice prepareSelectGroupChoice(List<String> groups) {
|
||||
// try to choose group or fast links
|
||||
|
||||
Choice choice = new ChoiceImpl(false);
|
||||
choice.setMessage("Choose dialogs group to run");
|
||||
|
||||
// main groups
|
||||
int recNumber = 0;
|
||||
for (int i = 0; i < groups.size(); i++) {
|
||||
recNumber++;
|
||||
String group = groups.get(i);
|
||||
choice.withItem(
|
||||
String.valueOf(i),
|
||||
String.format("%02d. %s", recNumber, group),
|
||||
recNumber,
|
||||
ChoiceHintType.TEXT,
|
||||
String.join("<br>", group)
|
||||
);
|
||||
}
|
||||
|
||||
// fast link to last group
|
||||
String lastGroupInfo = String.format(" -> last group: %s", lastSelectedGroup == null ? "not used" : lastSelectedGroup);
|
||||
choice.withItem(
|
||||
String.valueOf(LAST_SELECTED_GROUP_ID),
|
||||
lastGroupInfo,
|
||||
-2,
|
||||
ChoiceHintType.TEXT,
|
||||
lastGroupInfo
|
||||
);
|
||||
|
||||
// fast link to last dialog
|
||||
String lastDialogName = (lastSelectedDialog == null ? "not used" : String.format("%s - %s",
|
||||
lastSelectedDialog.getName(), lastSelectedDialog.getDescription()));
|
||||
String lastDialogInfo = String.format(" -> last dialog: %s", lastDialogName);
|
||||
choice.withItem(
|
||||
String.valueOf(LAST_SELECTED_DIALOG_ID),
|
||||
lastDialogInfo,
|
||||
-1,
|
||||
ChoiceHintType.TEXT,
|
||||
lastDialogInfo
|
||||
);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
private Choice prepareSelectDialogChoice(String needGroup) {
|
||||
Choice choice = new ChoiceImpl(false);
|
||||
choice.setMessage("Choose game dialog to run from " + needGroup);
|
||||
int recNumber = 0;
|
||||
for (int i = 0; i < this.dialogs.size(); i++) {
|
||||
TestableDialog dialog = this.dialogs.get(i);
|
||||
if (!dialog.getGroup().equals(needGroup)) {
|
||||
continue;
|
||||
}
|
||||
recNumber++;
|
||||
String info = String.format("%s - %s - %s", dialog.getGroup(), dialog.getName(), dialog.getDescription());
|
||||
choice.withItem(
|
||||
String.valueOf(i),
|
||||
String.format("%02d. %s", recNumber, info),
|
||||
recNumber,
|
||||
ChoiceHintType.TEXT,
|
||||
String.join("<br>", info)
|
||||
);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue