mirror of
https://github.com/magefree/mage.git
synced 2026-01-09 12:22:10 -08:00
[LTR] Add Goldberry, River-Daughter (#10524)
* Added Goldberry * Slight optimizaztion * Happy Path Test * More unhappy tests * Sanity check for Goldberry's counter choices * Updated player.getMultiAmount to support individual constraints * Some cleanup Also modified ResourcefulDefense to use new multi amount api * Updated logging * Added hint for number of counters * Fixed issue with Resourceful Defense * Improvements to defaults Default list will properly make sure to stay within individual maximums If a player is asked for a choice that isn't actually a choice because each choice's min and max are equal, instead the default response is immediately returned. This helps with situations like moving a counter off of Goldberry when she only has one counter on her. * -1/-1 Counter test * Fixed issue with -1/-1 counters * Adjusted dialog to properly enforce constraints
This commit is contained in:
parent
fe1efef25b
commit
a36a7d9b7f
23 changed files with 678 additions and 180 deletions
|
|
@ -0,0 +1,145 @@
|
|||
package org.mage.test.cards.single.ltr;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
|
||||
public class GoldberryRiverDaughterTest extends CardTestPlayerBase {
|
||||
static final String goldberry = "Goldberry, River-Daughter";
|
||||
static final String ability1 = "{T}: Move a counter of each kind not on {this} from another target permanent you control onto Goldberry.";
|
||||
static final String ability2 = "{U}, {T}: Move one or more counters from Goldberry onto another target permanent you control. If you do, draw a card.";
|
||||
|
||||
@Test
|
||||
// Author: alexander-novo
|
||||
// Happy path test - remove some counters from something. Then put some of them on something else.
|
||||
public void testHappyPath() {
|
||||
CounterType counter1 = CounterType.ACORN;
|
||||
CounterType counter2 = CounterType.AEGIS;
|
||||
String island = "Island";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, goldberry, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, island, 1);
|
||||
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter1, 2);
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter2, 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability1, island);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
checkPermanentCounters("First Ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter1, 1);
|
||||
checkPermanentCounters("First Ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter2, 0);
|
||||
checkPermanentCounters("First Ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goldberry, counter1, 1);
|
||||
checkPermanentCounters("First Ability", 1, PhaseStep.PRECOMBAT_MAIN, playerA, goldberry, counter2, 1);
|
||||
|
||||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, ability2, island);
|
||||
waitStackResolved(3, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
setChoiceAmount(playerA, 0, 1); // acorn, aegis counters
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(3, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(island, counter1, 1);
|
||||
assertCounterCount(island, counter2, 1);
|
||||
assertCounterCount(goldberry, counter1, 1);
|
||||
assertCounterCount(goldberry, counter2, 0);
|
||||
|
||||
// One from turn 2 draw, one from goldberry
|
||||
assertHandCount(playerA, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Author: alexander-novo
|
||||
// Unhappy path - Try to remove some counters from something when some of those counters are already on Goldberry
|
||||
public void testCounterAlreadyOnGoldberry() {
|
||||
CounterType counter = CounterType.ACORN;
|
||||
String island = "Island";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, goldberry, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, island, 1);
|
||||
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter, 1);
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, goldberry, counter, 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability1, island);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(island, counter, 1);
|
||||
assertCounterCount(goldberry, counter, 1);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
// Author: alexander-novo
|
||||
// Unhappy path - Try to not move a counter from Goldberry even though she has a counter on her.
|
||||
// Should fail since we are attempting to move 0 counters, even though we must move at least one if possible.
|
||||
public void testNotMovingCounter() {
|
||||
CounterType counter = CounterType.ACORN;
|
||||
String island = "Island";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, goldberry, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, island, 1);
|
||||
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, goldberry, counter, 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability2, island);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
setChoiceAmount(playerA, 0); // Try to remove 0 counters from goldberry
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(goldberry, counter, 0);
|
||||
assertCounterCount(island, counter, 1);
|
||||
assertHandCount(playerA, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Author: alexander-novo
|
||||
// Unhappy path - Activate second ability with no counters on Goldberry
|
||||
public void testNoCounters() {
|
||||
String island = "Island";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, goldberry, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, island, 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability2, island);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertHandCount(playerA, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
// Author: alexander-novo
|
||||
// Bug - Goldberry doesn't seem to get some of the effects from some of the counters she takes
|
||||
public void testM1M1Counters() {
|
||||
CounterType counter = CounterType.M1M1;
|
||||
String island = "Island";
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, goldberry, 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, island, 1);
|
||||
|
||||
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, island, counter, 1);
|
||||
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, ability1, island);
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN, 1);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
execute();
|
||||
|
||||
assertCounterCount(goldberry, counter, 1);
|
||||
assertPowerToughness(playerA, goldberry, 0, 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,8 +115,7 @@ public class ResourcefulDefenseTest extends CardTestPlayerBase {
|
|||
activateAbility(3, PhaseStep.PRECOMBAT_MAIN, playerA, "{4}{W}: ");
|
||||
addTarget(playerA, steelbaneHydra);
|
||||
addTarget(playerA, vividCreek);
|
||||
setChoiceAmount(playerA, 2);
|
||||
setChoiceAmount(playerA, 1);
|
||||
setChoiceAmount(playerA, 1, 2); // +1/+1, Charge
|
||||
|
||||
setStopAt(3, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package org.mage.test.cards.targets;
|
|||
import mage.constants.MultiAmountType;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.util.MultiAmountMessage;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
|
|
@ -10,6 +12,7 @@ import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
|
|
@ -20,117 +23,132 @@ public class TargetMultiAmountTest extends CardTestPlayerBaseWithAIHelps {
|
|||
@Test
|
||||
public void test_DefaultValues() {
|
||||
// default values must be assigned from first to last by minimum values
|
||||
assertDefaultValues("", 0, 0, 0);
|
||||
assertDefaultValuesUnconstrained("", 0, 0, 0);
|
||||
//
|
||||
assertDefaultValues("0", 1, 0, 0);
|
||||
assertDefaultValues("0 0", 2, 0, 0);
|
||||
assertDefaultValues("0 0 0", 3, 0, 0);
|
||||
assertDefaultValuesUnconstrained("0", 1, 0, 0);
|
||||
assertDefaultValuesUnconstrained("0 0", 2, 0, 0);
|
||||
assertDefaultValuesUnconstrained("0 0 0", 3, 0, 0);
|
||||
//
|
||||
assertDefaultValues("1", 1, 1, 1);
|
||||
assertDefaultValues("1 0", 2, 1, 1);
|
||||
assertDefaultValues("1 0 0", 3, 1, 1);
|
||||
assertDefaultValuesUnconstrained("1", 1, 1, 1);
|
||||
assertDefaultValuesUnconstrained("1 0", 2, 1, 1);
|
||||
assertDefaultValuesUnconstrained("1 0 0", 3, 1, 1);
|
||||
//
|
||||
assertDefaultValues("1", 1, 1, 2);
|
||||
assertDefaultValues("1 0", 2, 1, 2);
|
||||
assertDefaultValues("1 0 0", 3, 1, 2);
|
||||
assertDefaultValuesUnconstrained("1", 1, 1, 2);
|
||||
assertDefaultValuesUnconstrained("1 0", 2, 1, 2);
|
||||
assertDefaultValuesUnconstrained("1 0 0", 3, 1, 2);
|
||||
//
|
||||
assertDefaultValues("2", 1, 2, 2);
|
||||
assertDefaultValues("2 0", 2, 2, 2);
|
||||
assertDefaultValues("2 0 0", 3, 2, 2);
|
||||
assertDefaultValuesUnconstrained("2", 1, 2, 2);
|
||||
assertDefaultValuesUnconstrained("2 0", 2, 2, 2);
|
||||
assertDefaultValuesUnconstrained("2 0 0", 3, 2, 2);
|
||||
//
|
||||
assertDefaultValues("2", 1, 2, 10);
|
||||
assertDefaultValues("2 0", 2, 2, 10);
|
||||
assertDefaultValues("2 0 0", 3, 2, 10);
|
||||
assertDefaultValuesUnconstrained("2", 1, 2, 10);
|
||||
assertDefaultValuesUnconstrained("2 0", 2, 2, 10);
|
||||
assertDefaultValuesUnconstrained("2 0 0", 3, 2, 10);
|
||||
//
|
||||
// performance test
|
||||
assertDefaultValues("2 0 0", 3, 2, Integer.MAX_VALUE);
|
||||
assertDefaultValuesUnconstrained("2 0 0", 3, 2, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private void assertDefaultValues(String need, int count, int min, int max) {
|
||||
List<Integer> defaultValues = MultiAmountType.prepareDefaltValues(count, min, max);
|
||||
private List<MultiAmountMessage> getUnconstrainedConstraints(int count) {
|
||||
return IntStream.range(0, count).mapToObj(i -> new MultiAmountMessage("", Integer.MIN_VALUE, Integer.MAX_VALUE))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void assertDefaultValuesUnconstrained(String need, int count, int min, int max) {
|
||||
List<MultiAmountMessage> constraints = getUnconstrainedConstraints(count);
|
||||
List<Integer> defaultValues = MultiAmountType.prepareDefaltValues(constraints, min, max);
|
||||
String current = defaultValues
|
||||
.stream()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(" "));
|
||||
Assert.assertEquals("default values", need, current);
|
||||
Assert.assertTrue("default values must be good", MultiAmountType.isGoodValues(defaultValues, count, min, max));
|
||||
Assert.assertTrue("default values must be good",
|
||||
MultiAmountType.isGoodValues(defaultValues, constraints, min, max));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_MaxValues() {
|
||||
// max possible values must be assigned from first to last by max possible values
|
||||
assertMaxValues("", 0, 0, 0);
|
||||
assertMaxValuesUnconstrained("", 0, 0, 0);
|
||||
//
|
||||
assertMaxValues("0", 1, 0, 0);
|
||||
assertMaxValues("0 0", 2, 0, 0);
|
||||
assertMaxValues("0 0 0", 3, 0, 0);
|
||||
assertMaxValuesUnconstrained("0", 1, 0, 0);
|
||||
assertMaxValuesUnconstrained("0 0", 2, 0, 0);
|
||||
assertMaxValuesUnconstrained("0 0 0", 3, 0, 0);
|
||||
//
|
||||
assertMaxValues("1", 1, 1, 1);
|
||||
assertMaxValues("1 0", 2, 1, 1);
|
||||
assertMaxValues("1 0 0", 3, 1, 1);
|
||||
assertMaxValuesUnconstrained("1", 1, 1, 1);
|
||||
assertMaxValuesUnconstrained("1 0", 2, 1, 1);
|
||||
assertMaxValuesUnconstrained("1 0 0", 3, 1, 1);
|
||||
//
|
||||
assertMaxValues("2", 1, 1, 2);
|
||||
assertMaxValues("1 1", 2, 1, 2);
|
||||
assertMaxValues("1 1 0", 3, 1, 2);
|
||||
assertMaxValuesUnconstrained("2", 1, 1, 2);
|
||||
assertMaxValuesUnconstrained("1 1", 2, 1, 2);
|
||||
assertMaxValuesUnconstrained("1 1 0", 3, 1, 2);
|
||||
//
|
||||
assertMaxValues("2", 1, 2, 2);
|
||||
assertMaxValues("1 1", 2, 2, 2);
|
||||
assertMaxValues("1 1 0", 3, 2, 2);
|
||||
assertMaxValuesUnconstrained("2", 1, 2, 2);
|
||||
assertMaxValuesUnconstrained("1 1", 2, 2, 2);
|
||||
assertMaxValuesUnconstrained("1 1 0", 3, 2, 2);
|
||||
//
|
||||
assertMaxValues("10", 1, 2, 10);
|
||||
assertMaxValues("5 5", 2, 2, 10);
|
||||
assertMaxValues("4 3 3", 3, 2, 10);
|
||||
assertMaxValuesUnconstrained("10", 1, 2, 10);
|
||||
assertMaxValuesUnconstrained("5 5", 2, 2, 10);
|
||||
assertMaxValuesUnconstrained("4 3 3", 3, 2, 10);
|
||||
//
|
||||
assertMaxValues("1 1 1 1 1 0 0 0 0 0", 10, 2, 5);
|
||||
assertMaxValuesUnconstrained("1 1 1 1 1 0 0 0 0 0", 10, 2, 5);
|
||||
//
|
||||
// performance test
|
||||
assertMaxValues(String.valueOf(Integer.MAX_VALUE), 1, 2, Integer.MAX_VALUE);
|
||||
assertMaxValuesUnconstrained(String.valueOf(Integer.MAX_VALUE), 1, 2, Integer.MAX_VALUE);
|
||||
int part = Integer.MAX_VALUE / 3;
|
||||
String need = String.format("%d %d %d", part + 1, part, part);
|
||||
assertMaxValues(need, 3, 2, Integer.MAX_VALUE);
|
||||
assertMaxValuesUnconstrained(need, 3, 2, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private void assertMaxValues(String need, int count, int min, int max) {
|
||||
List<Integer> maxValues = MultiAmountType.prepareMaxValues(count, min, max);
|
||||
private void assertMaxValuesUnconstrained(String need, int count, int min, int max) {
|
||||
List<MultiAmountMessage> constraints = getUnconstrainedConstraints(count);
|
||||
List<Integer> maxValues = MultiAmountType.prepareMaxValues(constraints, min, max);
|
||||
String current = maxValues
|
||||
.stream()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(" "));
|
||||
Assert.assertEquals("max values", need, current);
|
||||
Assert.assertTrue("max values must be good", MultiAmountType.isGoodValues(maxValues, count, min, max));
|
||||
Assert.assertTrue("max values must be good", MultiAmountType.isGoodValues(maxValues, constraints, min, max));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_GoodValues() {
|
||||
List<List<MultiAmountMessage>> constraints = List.of(
|
||||
getUnconstrainedConstraints(0),
|
||||
getUnconstrainedConstraints(1),
|
||||
getUnconstrainedConstraints(2),
|
||||
getUnconstrainedConstraints(3),
|
||||
getUnconstrainedConstraints(4));
|
||||
|
||||
// good values are checking in test_DefaultValues, it's an additional
|
||||
List<Integer> list = MultiAmountType.prepareDefaltValues(3, 0, 0);
|
||||
List<Integer> list = MultiAmountType.prepareDefaltValues(constraints.get(3), 0, 0);
|
||||
|
||||
// count (0, 0, 0)
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, 0, 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, 1, 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, 2, 0, 0));
|
||||
Assert.assertTrue("count", MultiAmountType.isGoodValues(list, 3, 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, 4, 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, constraints.get(0), 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, constraints.get(1), 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, constraints.get(2), 0, 0));
|
||||
Assert.assertTrue("count", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 0));
|
||||
Assert.assertFalse("count", MultiAmountType.isGoodValues(list, constraints.get(4), 0, 0));
|
||||
|
||||
// min (0, 1, 1)
|
||||
list.set(0, 0);
|
||||
list.set(1, 1);
|
||||
list.set(2, 1);
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, 3, 0, 100));
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, 3, 1, 100));
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, 3, 2, 100));
|
||||
Assert.assertFalse("min", MultiAmountType.isGoodValues(list, 3, 3, 100));
|
||||
Assert.assertFalse("min", MultiAmountType.isGoodValues(list, 3, 4, 100));
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 100));
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, constraints.get(3), 1, 100));
|
||||
Assert.assertTrue("min", MultiAmountType.isGoodValues(list, constraints.get(3), 2, 100));
|
||||
Assert.assertFalse("min", MultiAmountType.isGoodValues(list, constraints.get(3), 3, 100));
|
||||
Assert.assertFalse("min", MultiAmountType.isGoodValues(list, constraints.get(3), 4, 100));
|
||||
|
||||
// max (0, 1, 1)
|
||||
list.set(0, 0);
|
||||
list.set(1, 1);
|
||||
list.set(2, 1);
|
||||
Assert.assertFalse("max", MultiAmountType.isGoodValues(list, 3, 0, 0));
|
||||
Assert.assertFalse("max", MultiAmountType.isGoodValues(list, 3, 0, 1));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, 3, 0, 2));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, 3, 0, 3));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, 3, 0, 4));
|
||||
Assert.assertFalse("max", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 0));
|
||||
Assert.assertFalse("max", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 1));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 2));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 3));
|
||||
Assert.assertTrue("max", MultiAmountType.isGoodValues(list, constraints.get(3), 0, 4));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -138,32 +156,36 @@ public class TargetMultiAmountTest extends CardTestPlayerBaseWithAIHelps {
|
|||
// parse must use correct values on good data or default values on broken data
|
||||
|
||||
// simple parse without data check
|
||||
assertParse("", 3, 1, 3, "", false);
|
||||
assertParse("1", 3, 1, 3, "1", false);
|
||||
assertParse("0 0 0", 3, 1, 3, "0 0 0", false);
|
||||
assertParse("1 0 3", 3, 1, 3, "1 0 3", false);
|
||||
assertParse("0 5 0 6", 3, 1, 3, "1,text 5 4. 6", false);
|
||||
assertParseUnconstrained("", 3, 1, 3, "", false);
|
||||
assertParseUnconstrained("1", 3, 1, 3, "1", false);
|
||||
assertParseUnconstrained("0 0 0", 3, 1, 3, "0 0 0", false);
|
||||
assertParseUnconstrained("1 0 3", 3, 1, 3, "1 0 3", false);
|
||||
assertParseUnconstrained("0 5 0 6", 3, 1, 3, "1,text 5 4. 6", false);
|
||||
|
||||
// parse with data check - good data
|
||||
assertParse("1 0 2", 3, 0, 3, "1 0 2", true);
|
||||
assertParseUnconstrained("1 0 2", 3, 0, 3, "1 0 2", true);
|
||||
|
||||
// parse with data check - broken data (must return defalt - 1 0 0)
|
||||
assertParse("1 0 0", 3, 1, 3, "", true);
|
||||
assertParse("1 0 0", 3, 1, 3, "1", true);
|
||||
assertParse("1 0 0", 3, 1, 3, "0 0 0", true);
|
||||
assertParse("1 0 0", 3, 1, 3, "1 0 3", true);
|
||||
assertParse("1 0 0", 3, 1, 3, "1,text 4.", true);
|
||||
assertParseUnconstrained("1 0 0", 3, 1, 3, "", true);
|
||||
assertParseUnconstrained("1 0 0", 3, 1, 3, "1", true);
|
||||
assertParseUnconstrained("1 0 0", 3, 1, 3, "0 0 0", true);
|
||||
assertParseUnconstrained("1 0 0", 3, 1, 3, "1 0 3", true);
|
||||
assertParseUnconstrained("1 0 0", 3, 1, 3, "1,text 4.", true);
|
||||
}
|
||||
|
||||
private void assertParse(String need, int count, int min, int max, String answerToParse, Boolean returnDefaultOnError) {
|
||||
List<Integer> parsedValues = MultiAmountType.parseAnswer(answerToParse, count, min, max, returnDefaultOnError);
|
||||
private void assertParseUnconstrained(String need, int count, int min, int max, String answerToParse,
|
||||
Boolean returnDefaultOnError) {
|
||||
List<MultiAmountMessage> constraints = getUnconstrainedConstraints(count);
|
||||
List<Integer> parsedValues = MultiAmountType.parseAnswer(answerToParse, constraints, min, max,
|
||||
returnDefaultOnError);
|
||||
String current = parsedValues
|
||||
.stream()
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(" "));
|
||||
Assert.assertEquals("parsed values", need, current);
|
||||
if (returnDefaultOnError) {
|
||||
Assert.assertTrue("parsed values must be good", MultiAmountType.isGoodValues(parsedValues, count, min, max));
|
||||
Assert.assertTrue("parsed values must be good",
|
||||
MultiAmountType.isGoodValues(parsedValues, constraints, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import mage.players.net.UserData;
|
|||
import mage.target.*;
|
||||
import mage.target.common.*;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.MultiAmountMessage;
|
||||
import mage.util.RandomUtil;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
|
|
@ -2831,11 +2832,12 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getMultiAmount(Outcome outcome, List<String> messages, int min, int max, MultiAmountType type, Game game) {
|
||||
public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, List<MultiAmountMessage> messages,
|
||||
int min, int max, MultiAmountType type, Game game) {
|
||||
assertAliasSupportInChoices(false);
|
||||
|
||||
int needCount = messages.size();
|
||||
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(needCount, min, max);
|
||||
List<Integer> defaultList = MultiAmountType.prepareDefaltValues(messages, min, max);
|
||||
if (needCount == 0) {
|
||||
return defaultList;
|
||||
}
|
||||
|
|
@ -2861,7 +2863,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
// extra check
|
||||
if (!MultiAmountType.isGoodValues(answer, needCount, min, max)) {
|
||||
if (!MultiAmountType.isGoodValues(answer, messages, min, max)) {
|
||||
Assert.fail("Wrong choices in multi amount: " + answer
|
||||
.stream()
|
||||
.map(String::valueOf)
|
||||
|
|
@ -2872,7 +2874,7 @@ public class TestPlayer implements Player {
|
|||
}
|
||||
|
||||
this.chooseStrictModeFailed("choice", game, "Multi amount: " + type.getHeader());
|
||||
return computerPlayer.getMultiAmount(outcome, messages, min, max, type, game);
|
||||
return computerPlayer.getMultiAmountWithIndividualConstraints(outcome, messages, min, max, type, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import mage.target.Target;
|
|||
import mage.target.TargetAmount;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.MultiAmountMessage;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
|
@ -983,7 +984,8 @@ public class PlayerStub implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getMultiAmount(Outcome outcome, List<String> messages, int min, int max, MultiAmountType type, Game game) {
|
||||
public List<Integer> getMultiAmountWithIndividualConstraints(Outcome outcome, List<MultiAmountMessage> messages,
|
||||
int min, int max, MultiAmountType type, Game game) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue