mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
Refactor: Significant speed-up for ManaOptions (#9233)
This commit is contained in:
parent
23a4d2640b
commit
55a6acba22
32 changed files with 782 additions and 408 deletions
|
|
@ -1536,7 +1536,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
if (!unpaid.getMana().includesMana(mana)) {
|
if (!unpaid.getMana().includesMana(mana)) {
|
||||||
continue ManaAbility;
|
continue ManaAbility;
|
||||||
}
|
}
|
||||||
colored += mana.countColored();
|
colored += CardUtil.overflowInc(colored, mana.countColored());
|
||||||
}
|
}
|
||||||
if (colored > 1 && (cost instanceof ColoredManaCost)) {
|
if (colored > 1 && (cost instanceof ColoredManaCost)) {
|
||||||
for (Mana netMana : manaAbility.getNetMana(game)) {
|
for (Mana netMana : manaAbility.getNetMana(game)) {
|
||||||
|
|
@ -1773,7 +1773,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
||||||
a2Max = netMana.count();
|
a2Max = netMana.count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return a2Max - a1Max;
|
return CardUtil.overflowDec(a2Max, a1Max);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,20 @@ class CavernOfSoulsManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered";
|
return "Spend this mana only to cast a creature spell of the chosen type, and that spell can't be countered";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.creatureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.creatureType == ((CavernOfSoulsManaBuilder) obj).creatureType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CavernOfSoulsConditionalMana extends ConditionalMana {
|
class CavernOfSoulsConditionalMana extends ConditionalMana {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage.cards.k;
|
package mage.cards.k;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import mage.ConditionalMana;
|
import mage.ConditionalMana;
|
||||||
|
|
@ -125,6 +126,20 @@ class TheRinghartCrestManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast a creature spell of the chosen type or a legendary creature spell";
|
return "Spend this mana only to cast a creature spell of the chosen type or a legendary creature spell";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.creatureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.creatureType == ((TheRinghartCrestManaBuilder) obj).creatureType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TheRinghartCrestConditionalMana extends ConditionalMana {
|
class TheRinghartCrestConditionalMana extends ConditionalMana {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
package mage.cards.p;
|
package mage.cards.p;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.ConditionalMana;
|
import mage.ConditionalMana;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
|
|
@ -72,6 +73,21 @@ class PillarOfOriginsManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast a creature spell of the chosen type";
|
return "Spend this mana only to cast a creature spell of the chosen type";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.creatureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.creatureType == ((PillarOfOriginsManaBuilder) obj).creatureType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PillarOfOriginsConditionalMana extends ConditionalMana {
|
class PillarOfOriginsConditionalMana extends ConditionalMana {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.ConditionalMana;
|
import mage.ConditionalMana;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
|
|
@ -83,12 +84,24 @@ class SecludedCourtyardManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast a creature spell of the chosen type or activate an ability of a creature or creature card of the chosen type";
|
return "Spend this mana only to cast a creature spell of the chosen type or activate an ability of a creature or creature card of the chosen type";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.creatureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.creatureType == ((SecludedCourtyardManaBuilder) obj).creatureType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SecludedCourtyardConditionalMana extends ConditionalMana {
|
class SecludedCourtyardConditionalMana extends ConditionalMana {
|
||||||
|
|
||||||
SubType creatureType;
|
|
||||||
|
|
||||||
public SecludedCourtyardConditionalMana(Mana mana, SubType creatureType) {
|
public SecludedCourtyardConditionalMana(Mana mana, SubType creatureType) {
|
||||||
super(mana);
|
super(mana);
|
||||||
staticText = "Spend this mana only to cast a creature spell of the chosen type or activate an ability of a creature or creature card of the chosen type";
|
staticText = "Spend this mana only to cast a creature spell of the chosen type or activate an ability of a creature or creature card of the chosen type";
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package mage.cards.s;
|
package mage.cards.s;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -82,8 +79,8 @@ class SquanderedResourcesEffect extends ManaEffect {
|
||||||
}
|
}
|
||||||
allPossibleMana.addMana(currentPossibleMana);
|
allPossibleMana.addMana(currentPossibleMana);
|
||||||
}
|
}
|
||||||
allPossibleMana.removeDuplicated();
|
allPossibleMana.removeFullyIncludedVariations();
|
||||||
return allPossibleMana.stream().collect(Collectors.toList());
|
return new ArrayList<>(allPossibleMana);
|
||||||
}
|
}
|
||||||
return ManaType.getManaListFromManaTypes(getManaTypesFromSacrificedPermanent(game, source), false);
|
return ManaType.getManaListFromManaTypes(getManaTypesFromSacrificedPermanent(game, source), false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
package mage.cards.u;
|
package mage.cards.u;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.ConditionalMana;
|
import mage.ConditionalMana;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
|
|
@ -79,6 +80,20 @@ class UnclaimedTerritoryManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast a creature spell of the chosen type";
|
return "Spend this mana only to cast a creature spell of the chosen type";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.creatureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.creatureType == ((UnclaimedTerritoryManaBuilder) obj).creatureType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnclaimedTerritoryConditionalMana extends ConditionalMana {
|
class UnclaimedTerritoryConditionalMana extends ConditionalMana {
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,7 @@ public class BestowTest extends CardTestPlayerBase {
|
||||||
assertPermanentCount(playerB, "Song of the Dryads", 1);
|
assertPermanentCount(playerB, "Song of the Dryads", 1);
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 1 green mana", "{G}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 1 green mana", "{G}", options.getAtIndex(0).toString());
|
||||||
|
|
||||||
assertPermanentCount(playerA, "Nighthowler", 1);
|
assertPermanentCount(playerA, "Nighthowler", 1);
|
||||||
assertPowerToughness(playerA, "Nighthowler", 2, 2);
|
assertPowerToughness(playerA, "Nighthowler", 2, 2);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -45,7 +44,6 @@ public class SasayaOrochiAscendantTest extends CardTestPlayerBase {
|
||||||
assertManaPool(playerA, ManaType.GREEN, 2);
|
assertManaPool(playerA, ManaType.GREEN, 2);
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{G}{G}{G}{G}{G}", manaOptions);
|
assertManaOptions("{G}{G}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -81,7 +79,6 @@ public class SasayaOrochiAscendantTest extends CardTestPlayerBase {
|
||||||
assertLife(playerA, 18);
|
assertLife(playerA, 18);
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
assertManaOptions("{C}{C}{C}{G}{G}", manaOptions);
|
assertManaOptions("{C}{C}{C}{G}{G}", manaOptions);
|
||||||
|
|
@ -121,7 +118,6 @@ public class SasayaOrochiAscendantTest extends CardTestPlayerBase {
|
||||||
assertLife(playerA, 20);
|
assertLife(playerA, 20);
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||||
assertManaOptions("{R}{R}{R}{R}{G}{G}{G}{G}{G}", manaOptions);
|
assertManaOptions("{R}{R}{R}{R}{G}{G}{G}{G}{G}", manaOptions);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,7 +26,6 @@ public class HarvesterDruidTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(options);
|
|
||||||
Assert.assertEquals(2, options.size());
|
Assert.assertEquals(2, options.size());
|
||||||
assertManaOptions("{U}{R}{R}", options);
|
assertManaOptions("{U}{R}{R}", options);
|
||||||
assertManaOptions("{U}{U}{R}", options);
|
assertManaOptions("{U}{U}{R}", options);
|
||||||
|
|
@ -45,7 +43,6 @@ public class HarvesterDruidTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(options);
|
|
||||||
Assert.assertEquals(3, options.size());
|
Assert.assertEquals(3, options.size());
|
||||||
assertManaOptions("{U}{R}{R}{R}", options);
|
assertManaOptions("{U}{R}{R}{R}", options);
|
||||||
assertManaOptions("{U}{U}{R}{R}", options);
|
assertManaOptions("{U}{U}{R}{R}", options);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,9 +49,7 @@ public class NagaVitalistTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
|
||||||
assertManaOptions("{B}", manaOptions);
|
|
||||||
assertManaOptions("{Any}{Any}", manaOptions);
|
assertManaOptions("{Any}{Any}", manaOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 2 red mana", "{R}{R}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 2 red mana", "{R}{R}", options.getAtIndex(0).toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 3 red mana", "{R}{R}{R}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 3 red mana", "{R}{R}{R}", options.getAtIndex(0).toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 3 red mana", "{R}{R}{R}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 3 red mana", "{R}{R}{R}", options.getAtIndex(0).toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ public class ReflectingPoolTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 2 red mana", "{G}{G}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 2 green mana", "{G}{G}", options.getAtIndex(0).toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ public class SylvokExplorerTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{R}{W}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 1 red and 1 white mana", "{R}{W}", options.getAtIndex(0).toString());
|
||||||
Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{W}{U}", options.get(1).toString());
|
Assert.assertEquals("Player should be able to create 1 blue and 1 white mana", "{W}{U}", options.getAtIndex(1).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -45,6 +45,6 @@ public class SylvokExplorerTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
ManaOptions options = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("Player should be able to create 3 white mana", "{W}{W}{W}", options.get(0).toString());
|
Assert.assertEquals("Player should be able to create 3 white mana", "{W}{W}{W}", options.getAtIndex(0).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package org.mage.test.cards.mana.conditional;
|
package org.mage.test.cards.mana.conditional;
|
||||||
|
|
||||||
|
import mage.ConditionalMana;
|
||||||
|
import mage.Mana;
|
||||||
|
import mage.abilities.condition.common.AdamantCondition;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.mana.ManaOptions;
|
import mage.abilities.mana.ManaOptions;
|
||||||
import mage.constants.PhaseStep;
|
import mage.constants.PhaseStep;
|
||||||
|
|
@ -9,7 +12,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -330,7 +332,6 @@ public class ConditionalManaTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{R}{R}", manaOptions);
|
assertManaOptions("{R}{R}", manaOptions);
|
||||||
}
|
}
|
||||||
|
|
@ -386,4 +387,34 @@ public class ConditionalManaTest extends CardTestPlayerBase {
|
||||||
assertManaOptions("{C}{C}{C}{C}{C}{C}{R}[{RosheenMeandererManaCondition}{TitansNestManaCondition}]", manaOptions);
|
assertManaOptions("{C}{C}{C}{C}{C}{C}{R}[{RosheenMeandererManaCondition}{TitansNestManaCondition}]", manaOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConditionalManaDeduplication() {
|
||||||
|
ManaOptions manaOptions = new ManaOptions();
|
||||||
|
|
||||||
|
ConditionalMana originalMana = new ConditionalMana(Mana.GreenMana(1));
|
||||||
|
|
||||||
|
ConditionalMana mana2 = originalMana.copy();
|
||||||
|
mana2.addCondition(AdamantCondition.WHITE);
|
||||||
|
|
||||||
|
ConditionalMana mana3 = originalMana.copy();
|
||||||
|
mana3.addCondition(AdamantCondition.BLUE);
|
||||||
|
ConditionalMana mana3Copy = originalMana.copy();
|
||||||
|
mana3Copy.addCondition(AdamantCondition.BLUE);
|
||||||
|
mana3Copy.add(Mana.GreenMana(1));
|
||||||
|
|
||||||
|
ConditionalMana mana4 = originalMana.copy();
|
||||||
|
mana4.addCondition(AdamantCondition.BLACK);
|
||||||
|
ConditionalMana mana4Copy = originalMana.copy();
|
||||||
|
mana4Copy.addCondition(AdamantCondition.BLACK);
|
||||||
|
|
||||||
|
manaOptions.add(originalMana);
|
||||||
|
manaOptions.add(mana2);
|
||||||
|
manaOptions.add(mana3);
|
||||||
|
manaOptions.add(mana3Copy); // Added, and should remain since different amount of Green mana
|
||||||
|
manaOptions.add(mana4);
|
||||||
|
manaOptions.add(mana4Copy); // Adding it to make sure it gets removed
|
||||||
|
|
||||||
|
Assert.assertEquals("Incorrect number of mana", 5, manaOptions.size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
public class ManaReflectionTest extends CardTestPlayerBase {
|
public class ManaReflectionTest extends CardTestPlayerBase {
|
||||||
|
|
@ -72,7 +71,6 @@ public class ManaReflectionTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||||
assertManaOptions("{R}{R}{R}{R}{R}{R}{G}{G}", manaOptions);
|
assertManaOptions("{R}{R}{R}{R}{R}{R}{G}{G}", manaOptions);
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.utils.ManaOptionsTestUtils;
|
import org.mage.test.utils.ManaOptionsTestUtils;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
|
|
@ -44,7 +42,7 @@ public class ThePrismaticPiperTest2 extends ThePrismaticPiperBaseTest {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
ManaOptionsTestUtils.assertManaOptions("{U}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{U}", manaOptions);
|
||||||
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ import org.mage.test.utils.ManaOptionsTestUtils;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
|
|
@ -54,7 +52,7 @@ public class ThePrismaticPiperTest7 extends ThePrismaticPiperBaseTest {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
||||||
ManaOptionsTestUtils.assertManaOptions("{G}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{G}", manaOptions);
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.utils.ManaOptionsTestUtils;
|
import org.mage.test.utils.ManaOptionsTestUtils;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author TheElk801
|
* @author TheElk801
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,7 +48,7 @@ public class ThePrismaticPiperTest8 extends ThePrismaticPiperBaseTest {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
ManaOptionsTestUtils.assertManaOptions("{U}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{U}", manaOptions);
|
||||||
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
ManaOptionsTestUtils.assertManaOptions("{R}", manaOptions);
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import mage.constants.PhaseStep;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertDuplicatedManaOptions;
|
|
||||||
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
import static org.mage.test.utils.ManaOptionsTestUtils.assertManaOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,7 +27,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{G}{G}{G}", manaOptions);
|
assertManaOptions("{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -45,7 +44,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||||
assertManaOptions("{G}{G}{G}", manaOptions);
|
assertManaOptions("{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -66,7 +64,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 10, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 10, manaOptions.size());
|
||||||
assertManaOptions("{C}{C}{C}", manaOptions);
|
assertManaOptions("{C}{C}{C}", manaOptions);
|
||||||
|
|
@ -92,7 +89,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{Any}{Any}", manaOptions);
|
assertManaOptions("{Any}{Any}", manaOptions);
|
||||||
|
|
@ -110,7 +106,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{W}{W}{Any}{Any}", manaOptions);
|
assertManaOptions("{W}{W}{Any}{Any}", manaOptions);
|
||||||
|
|
@ -129,7 +124,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{W}{W}", manaOptions);
|
assertManaOptions("{C}{G}{G}{W}{W}", manaOptions);
|
||||||
|
|
@ -148,7 +142,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}{W}{W}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}{W}{W}", manaOptions);
|
||||||
|
|
@ -169,7 +162,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -188,7 +180,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -206,7 +197,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{Any}", manaOptions);
|
assertManaOptions("{C}{G}{Any}", manaOptions);
|
||||||
|
|
@ -225,7 +215,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -249,7 +238,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -267,7 +255,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
assertManaOptions("{G}{W}{W}", manaOptions);
|
assertManaOptions("{G}{W}{W}", manaOptions);
|
||||||
|
|
@ -296,7 +283,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 6, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 6, manaOptions.size());
|
||||||
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
assertManaOptions("{C}{G}{G}{G}", manaOptions);
|
||||||
|
|
@ -316,7 +302,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -328,7 +313,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -357,7 +341,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 3, manaOptions.size());
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
assertManaOptions("{C}{C}", manaOptions);
|
assertManaOptions("{C}{C}", manaOptions);
|
||||||
assertManaOptions("{Any}{Any}", manaOptions);
|
assertManaOptions("{Any}{Any}", manaOptions);
|
||||||
assertManaOptions("{C}{Any}", manaOptions);
|
assertManaOptions("{C}{Any}", manaOptions);
|
||||||
|
|
@ -374,7 +357,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||||
assertManaOptions("{C}{W}", manaOptions);
|
assertManaOptions("{C}{W}", manaOptions);
|
||||||
|
|
@ -396,9 +378,8 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size()); // TODO: Why one, should there be {B} and {B}{U}?
|
||||||
assertManaOptions("{W}{B}", manaOptions);
|
assertManaOptions("{W}{B}", manaOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,7 +393,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
assertManaOptions("{W}{B}{B}", manaOptions);
|
assertManaOptions("{W}{B}{B}", manaOptions);
|
||||||
|
|
@ -432,7 +412,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{W}{B}", manaOptions);
|
assertManaOptions("{C}{W}{B}", manaOptions);
|
||||||
|
|
@ -452,7 +431,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{C}{C}{C}{W}{B}", manaOptions);
|
assertManaOptions("{C}{C}{C}{C}{W}{B}", manaOptions);
|
||||||
|
|
@ -470,7 +448,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{B}{B}", manaOptions);
|
assertManaOptions("{B}{B}", manaOptions);
|
||||||
|
|
@ -489,7 +466,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}", manaOptions);
|
assertManaOptions("{C}", manaOptions);
|
||||||
|
|
@ -508,7 +484,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 1, manaOptions.size());
|
||||||
assertManaOptions("{C}{C}", manaOptions);
|
assertManaOptions("{C}{C}", manaOptions);
|
||||||
|
|
@ -529,7 +504,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 16, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 16, manaOptions.size());
|
||||||
assertManaOptions("{C}{C}{C}{C}{W}{W}{W}", manaOptions);
|
assertManaOptions("{C}{C}{C}{C}{W}{W}{W}", manaOptions);
|
||||||
|
|
@ -561,7 +535,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 2, manaOptions.size());
|
||||||
|
|
||||||
|
|
@ -582,7 +555,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 88, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 88, manaOptions.size());
|
||||||
|
|
||||||
|
|
@ -603,7 +575,6 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
execute();
|
execute();
|
||||||
|
|
||||||
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
assertDuplicatedManaOptions(manaOptions);
|
|
||||||
|
|
||||||
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
Assert.assertEquals("mana variations don't fit", 4, manaOptions.size());
|
||||||
assertManaOptions("{U}{U}", manaOptions);
|
assertManaOptions("{U}{U}", manaOptions);
|
||||||
|
|
@ -612,4 +583,47 @@ public class ManaOptionsTest extends CardTestPlayerBase {
|
||||||
assertManaOptions("{G}{W}{W}", manaOptions);
|
assertManaOptions("{G}{W}{W}", manaOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a stress test for the implementation of ManaUtils.
|
||||||
|
* Based on the bug from: https://github.com/magefree/mage/issues/7710
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCascadingCataracts() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Desert", 5);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Cascading Cataracts", 3);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
|
// The size below is based on no optimization to remove any mana possibilities beyond exact duplicates.
|
||||||
|
Assert.assertEquals("mana variations don't match", 6902, manaOptions.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to above, except without a hardcoded expected result, and used to check scaling.
|
||||||
|
* Leave the @Ignore added when pushing commits.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testCascadingCataractsN() {
|
||||||
|
int n = 5;
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Swamp", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mountain", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Forest", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Desert", n);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Cascading Cataracts", n);
|
||||||
|
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
ManaOptions manaOptions = playerA.getAvailableManaTest(currentGame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
package org.mage.test.utils;
|
package org.mage.test.utils;
|
||||||
|
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.mana.ManaOptions;
|
import mage.abilities.mana.ManaOptions;
|
||||||
|
import mage.util.ManaUtil;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
@ -19,8 +23,8 @@ public class ManaOptionsTestUtils {
|
||||||
//mana info
|
//mana info
|
||||||
//logger.info(playerA.getManaPool().getMana().toString());
|
//logger.info(playerA.getManaPool().getMana().toString());
|
||||||
//logger.info(playerA.getManaAvailable(currentGame).toString());
|
//logger.info(playerA.getManaAvailable(currentGame).toString());
|
||||||
public static boolean manaOptionsContain(ManaOptions list, String searchMana) {
|
public static boolean manaOptionsContain(String searchMana, ManaOptions manaOptions) {
|
||||||
for (Mana mana : list) {
|
for (Mana mana : manaOptions) {
|
||||||
if (mana instanceof ConditionalMana) {
|
if (mana instanceof ConditionalMana) {
|
||||||
if ((mana.toString() + ((ConditionalMana)mana).getConditionString()).equals(searchMana)) {
|
if ((mana.toString() + ((ConditionalMana)mana).getConditionString()).equals(searchMana)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -34,21 +38,9 @@ public class ManaOptionsTestUtils {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assertManaOptions(String searchMana, ManaOptions manaList) {
|
public static void assertManaOptions(String searchMana, ManaOptions manaOptions) {
|
||||||
if (!manaOptionsContain(manaList, searchMana)) {
|
if (!manaOptionsContain(searchMana, manaOptions)) {
|
||||||
Assert.fail("Can't find " + searchMana + " in " + manaList.toString());
|
Assert.fail("Can't find " + searchMana + " in " + manaOptions.toString());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void assertDuplicatedManaOptions(ManaOptions manaList) {
|
|
||||||
Set<String> list = new HashSet<>();
|
|
||||||
for (Mana mana : manaList) {
|
|
||||||
String s = mana.toString();
|
|
||||||
if (list.contains(s)) {
|
|
||||||
Assert.fail("Found duplicated mana option " + s + " in " + manaList.toString());
|
|
||||||
} else {
|
|
||||||
list.add(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,12 @@ import mage.game.Game;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* If subclassing and adding extra field, you must be sure to override equals() and hashCode to include the new fields.
|
||||||
|
*
|
||||||
* @author nantuko
|
* @author nantuko
|
||||||
*/
|
*/
|
||||||
public class ConditionalMana extends Mana implements Serializable, Emptiable {
|
public class ConditionalMana extends Mana implements Serializable, Emptiable {
|
||||||
|
|
@ -188,11 +191,17 @@ public class ConditionalMana extends Mana implements Serializable, Emptiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getConditionString() {
|
public String getConditionString() {
|
||||||
String condStr = "[";
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append('[');
|
||||||
for (Condition condition : conditions) {
|
for (Condition condition : conditions) {
|
||||||
condStr += condition.getManaText();
|
sb.append('{');
|
||||||
|
sb.append(condition.getManaText());
|
||||||
|
sb.append('}');
|
||||||
}
|
}
|
||||||
return condStr + "]";
|
sb.append(']');
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(ManaType manaType, int amount) {
|
public void add(ManaType manaType, int amount) {
|
||||||
|
|
@ -220,4 +229,42 @@ public class ConditionalMana extends Mana implements Serializable, Emptiable {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), conditions, staticText, scope, manaProducerId, manaProducerOriginalId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
// Check Mana.equals(). If that's isn't equal no need to check further.
|
||||||
|
if (!super.equals(o)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ConditionalMana that = (ConditionalMana) o;
|
||||||
|
|
||||||
|
if (!Objects.equals(this.staticText, that.staticText)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.manaProducerId, that.manaProducerId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.manaProducerOriginalId, that.manaProducerOriginalId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(this.scope, that.scope)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.conditions == null || that.conditions == null
|
||||||
|
|| this.conditions.size() != that.conditions.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < this.conditions.size(); i++) {
|
||||||
|
if (!(Objects.equals(this.conditions.get(i), that.conditions.get(i)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package mage;
|
package mage;
|
||||||
|
|
||||||
|
import mage.abilities.condition.Condition;
|
||||||
import mage.constants.ColoredManaSymbol;
|
import mage.constants.ColoredManaSymbol;
|
||||||
import mage.constants.ManaType;
|
import mage.constants.ManaType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
|
|
@ -8,10 +9,8 @@ import mage.util.Copyable;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
import java.util.function.BiFunction;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WARNING, all mana operations must use overflow check, see usage of CardUtil.addWithOverflowCheck and same methods
|
* WARNING, all mana operations must use overflow check, see usage of CardUtil.addWithOverflowCheck and same methods
|
||||||
|
|
@ -320,32 +319,51 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increases the given mana by one.
|
* Increases this mana by one of the passed in ManaType.
|
||||||
*
|
*
|
||||||
* @param manaType the type of mana to increase by one.
|
* @param manaType the type of mana to increase by one.
|
||||||
*/
|
*/
|
||||||
public void increase(ManaType manaType) {
|
public void increase(ManaType manaType) {
|
||||||
|
increaseOrDecrease(manaType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decreases this mana by onw of the passed in ManaType.
|
||||||
|
*
|
||||||
|
* @param manaType the type of mana to increase by one.
|
||||||
|
*/
|
||||||
|
public void decrease(ManaType manaType) {
|
||||||
|
increaseOrDecrease(manaType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for increase and decrease to not have the code duplicated.
|
||||||
|
* @param manaType
|
||||||
|
* @param increase
|
||||||
|
*/
|
||||||
|
private void increaseOrDecrease(ManaType manaType, boolean increase) {
|
||||||
|
BiFunction<Integer, Integer, Integer> overflowIncOrDec = increase ? CardUtil::overflowInc : CardUtil::overflowDec;
|
||||||
switch (manaType) {
|
switch (manaType) {
|
||||||
case WHITE:
|
case WHITE:
|
||||||
white = CardUtil.overflowInc(white, 1);
|
white = overflowIncOrDec.apply(white, 1);
|
||||||
break;
|
break;
|
||||||
case BLUE:
|
case BLUE:
|
||||||
blue = CardUtil.overflowInc(blue, 1);
|
blue = overflowIncOrDec.apply(blue, 1);
|
||||||
break;
|
break;
|
||||||
case BLACK:
|
case BLACK:
|
||||||
black = CardUtil.overflowInc(black, 1);
|
black = overflowIncOrDec.apply(black, 1);
|
||||||
break;
|
break;
|
||||||
case RED:
|
case RED:
|
||||||
red = CardUtil.overflowInc(red, 1);
|
red = overflowIncOrDec.apply(red, 1);
|
||||||
break;
|
break;
|
||||||
case GREEN:
|
case GREEN:
|
||||||
green = CardUtil.overflowInc(green, 1);
|
green = overflowIncOrDec.apply(green, 1);
|
||||||
break;
|
break;
|
||||||
case COLORLESS:
|
case COLORLESS:
|
||||||
colorless = CardUtil.overflowInc(colorless, 1);
|
colorless = overflowIncOrDec.apply(colorless, 1);
|
||||||
break;
|
break;
|
||||||
case GENERIC:
|
case GENERIC:
|
||||||
generic = CardUtil.overflowInc(generic, 1);
|
generic = overflowIncOrDec.apply(generic, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,6 +417,13 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
colorless = CardUtil.overflowInc(colorless, 1);
|
colorless = CardUtil.overflowInc(colorless, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void increaseAny() {
|
||||||
|
any = CardUtil.overflowInc(any, 1);
|
||||||
|
}
|
||||||
|
public void decreaseAny() {
|
||||||
|
any = CardUtil.overflowDec(any, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtracts the passed in mana values from this instance.
|
* Subtracts the passed in mana values from this instance.
|
||||||
*
|
*
|
||||||
|
|
@ -477,14 +502,11 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
* @return the total count of all combined mana.
|
* @return the total count of all combined mana.
|
||||||
*/
|
*/
|
||||||
public int count() {
|
public int count() {
|
||||||
return white
|
int sum = countColored();
|
||||||
+ blue
|
sum = CardUtil.overflowInc(sum, generic);
|
||||||
+ black
|
sum = CardUtil.overflowInc(sum, colorless);
|
||||||
+ red
|
|
||||||
+ green
|
return sum;
|
||||||
+ generic
|
|
||||||
+ colorless
|
|
||||||
+ any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -493,12 +515,13 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
* @return the total count of all colored mana.
|
* @return the total count of all colored mana.
|
||||||
*/
|
*/
|
||||||
public int countColored() {
|
public int countColored() {
|
||||||
return white
|
int sum = CardUtil.overflowInc(white, blue);
|
||||||
+ blue
|
sum = CardUtil.overflowInc(sum, black);
|
||||||
+ black
|
sum = CardUtil.overflowInc(sum, red);
|
||||||
+ red
|
sum = CardUtil.overflowInc(sum, green);
|
||||||
+ green
|
sum = CardUtil.overflowInc(sum, any);
|
||||||
+ any;
|
|
||||||
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1103,7 +1126,7 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
case GREEN:
|
case GREEN:
|
||||||
return green;
|
return green;
|
||||||
case COLORLESS:
|
case COLORLESS:
|
||||||
return CardUtil.overflowInc(generic, colorless);
|
return CardUtil.overflowInc(generic, colorless); // TODO: This seems like a mistake
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -1206,77 +1229,114 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMoreValuableThan(Mana that) {
|
||||||
|
// Use of == is intentional since getMoreValuableMana returns one of its inputs.
|
||||||
|
return this == Mana.getMoreValuableMana(this, that);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mana that is more colored or has a greater amount but does
|
* Returns the mana that is more colored or has a greater amount but does
|
||||||
* not contain one less mana in any color but generic.
|
* not contain one less mana in any type but generic.
|
||||||
|
* <p>
|
||||||
|
* See tests ManaTest.moreValuableManaTest for several examples
|
||||||
*
|
*
|
||||||
* Examples:
|
* Examples:
|
||||||
|
* {1} and {R} -> {R}
|
||||||
|
* {2} and {1}{W} -> {1}{W}
|
||||||
|
* {3} and {1}{W} -> {1}{W}
|
||||||
* {1}{W}{R} and {G}{W}{R} -> {G}{W}{R}
|
* {1}{W}{R} and {G}{W}{R} -> {G}{W}{R}
|
||||||
* {G}{W}{R} and {G}{W}{R} -> {G}{W}{R}
|
* {G}{W}{R} and {G}{W}{R} -> null
|
||||||
* {G}{W}{B} and {G}{W}{R} -> null
|
* {G}{W}{B} and {G}{W}{R} -> null
|
||||||
|
* {C} and {ANY} -> null
|
||||||
*
|
*
|
||||||
* @param mana1 The 1st mana to compare.
|
* @param mana1 The 1st mana to compare.
|
||||||
* @param mana2 The 2nd mana to compare.
|
* @param mana2 The 2nd mana to compare.
|
||||||
* @return The greater of the two manas, or null if they're the same
|
* @return The greater of the two manas, or null if they're the same OR they cannot be compared
|
||||||
*/
|
*/
|
||||||
public static Mana getMoreValuableMana(final Mana mana1, final Mana mana2) {
|
public static Mana getMoreValuableMana(final Mana mana1, final Mana mana2) {
|
||||||
String conditionString1 = "";
|
if (mana1.equals(mana2)) {
|
||||||
String conditionString2 = "";
|
|
||||||
if (mana1 instanceof ConditionalMana) {
|
|
||||||
conditionString1 = ((ConditionalMana) mana1).getConditionString();
|
|
||||||
}
|
|
||||||
if (mana2 instanceof ConditionalMana) {
|
|
||||||
conditionString2 = ((ConditionalMana) mana2).getConditionString();
|
|
||||||
}
|
|
||||||
if (!conditionString1.equals(conditionString2)) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean mana1IsConditional = mana1 instanceof ConditionalMana;
|
||||||
|
boolean mana2IsConditional = mana2 instanceof ConditionalMana;
|
||||||
|
if (mana1IsConditional != mana2IsConditional) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mana1IsConditional) {
|
||||||
|
List<Condition> conditions1 = ((ConditionalMana) mana1).getConditions();
|
||||||
|
List<Condition> conditions2 = ((ConditionalMana) mana2).getConditions();
|
||||||
|
if (!Objects.equals(conditions1, conditions2)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set one mana as moreMana and one as lessMana.
|
||||||
Mana moreMana;
|
Mana moreMana;
|
||||||
Mana lessMana;
|
Mana lessMana;
|
||||||
if (mana2.countColored() > mana1.countColored() || mana2.getAny() > mana1.getAny() || mana2.count() > mana1.count()) {
|
if (mana2.any > mana1.any
|
||||||
|
|| mana2.colorless > mana1.colorless
|
||||||
|
|| mana2.countColored() > mana1.countColored()
|
||||||
|
|| (mana2.countColored() == mana1.countColored()
|
||||||
|
&& mana2.colorless == mana1.colorless
|
||||||
|
&& mana2.count() > mana1.count())) {
|
||||||
moreMana = mana2;
|
moreMana = mana2;
|
||||||
lessMana = mana1;
|
lessMana = mana1;
|
||||||
} else {
|
} else {
|
||||||
moreMana = mana1;
|
moreMana = mana1;
|
||||||
lessMana = mana2;
|
lessMana = mana2;
|
||||||
}
|
}
|
||||||
int anyDiff = CardUtil.overflowDec(mana2.getAny(), mana1.getAny());
|
|
||||||
if (lessMana.getWhite() > moreMana.getWhite()) {
|
if (lessMana.any > moreMana.any) {
|
||||||
anyDiff = CardUtil.overflowDec(anyDiff, CardUtil.overflowDec(lessMana.getWhite(), moreMana.getWhite()));
|
|
||||||
if (anyDiff < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lessMana.getRed() > moreMana.getRed()) {
|
|
||||||
anyDiff = CardUtil.overflowDec(anyDiff, CardUtil.overflowDec(lessMana.getRed(), moreMana.getRed()));
|
|
||||||
if (anyDiff < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lessMana.getGreen() > moreMana.getGreen()) {
|
|
||||||
anyDiff = CardUtil.overflowDec(anyDiff, CardUtil.overflowDec(lessMana.getGreen(), moreMana.getGreen()));
|
|
||||||
if (anyDiff < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lessMana.getBlue() > moreMana.getBlue()) {
|
|
||||||
anyDiff = CardUtil.overflowDec(anyDiff, CardUtil.overflowDec(lessMana.getBlue(), moreMana.getBlue()));
|
|
||||||
if (anyDiff < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lessMana.getBlack() > moreMana.getBlack()) {
|
|
||||||
anyDiff = CardUtil.overflowDec(anyDiff, CardUtil.overflowDec(lessMana.getBlack(), moreMana.getBlack()));
|
|
||||||
if (anyDiff < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lessMana.getColorless() > moreMana.getColorless()) {
|
|
||||||
return null; // Any (color) can't produce colorless mana
|
|
||||||
}
|
|
||||||
if (lessMana.getAny() > moreMana.getAny()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (lessMana.colorless > moreMana.colorless) {
|
||||||
|
return null; // Any (color) can't produce colorless mana
|
||||||
|
}
|
||||||
|
|
||||||
|
int anyDiff = CardUtil.overflowDec(moreMana.any, lessMana.any);
|
||||||
|
|
||||||
|
int whiteDiff = CardUtil.overflowDec(lessMana.white, moreMana.white);
|
||||||
|
if (whiteDiff > 0) {
|
||||||
|
anyDiff = CardUtil.overflowDec(anyDiff, whiteDiff);
|
||||||
|
if (anyDiff < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int redDiff = CardUtil.overflowDec(lessMana.red, moreMana.red);
|
||||||
|
if (redDiff > 0) {
|
||||||
|
anyDiff = CardUtil.overflowDec(anyDiff, redDiff);
|
||||||
|
if (anyDiff < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int greenDiff = CardUtil.overflowDec(lessMana.green, moreMana.green);
|
||||||
|
if (greenDiff > 0) {
|
||||||
|
anyDiff = CardUtil.overflowDec(anyDiff, greenDiff);
|
||||||
|
if (anyDiff < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blueDiff = CardUtil.overflowDec(lessMana.blue, moreMana.blue);
|
||||||
|
if (blueDiff > 0) {
|
||||||
|
anyDiff = CardUtil.overflowDec(anyDiff, blueDiff);
|
||||||
|
if (anyDiff < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blackDiff = CardUtil.overflowDec(lessMana.black, moreMana.black);
|
||||||
|
if (blackDiff > 0) {
|
||||||
|
anyDiff = CardUtil.overflowDec(anyDiff, blackDiff);
|
||||||
|
if (anyDiff < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return moreMana;
|
return moreMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1323,9 +1383,27 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
|
||||||
&& any == mana.any;
|
&& any == mana.any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hardcoding here versus using Objects.hash in order to increase performance since this is
|
||||||
|
* called thousands of times by {@link mage.abilities.mana.ManaOptions#addManaWithCost(List, Game)}
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(white, blue, black, red, green, generic, colorless, any, flag);
|
long result = 1;
|
||||||
|
|
||||||
|
result = 31 * result + white;
|
||||||
|
result = 31 * result + blue;
|
||||||
|
result = 31 * result + black;
|
||||||
|
result = 31 * result + red;
|
||||||
|
result = 31 * result + green;
|
||||||
|
result = 31 * result + generic;
|
||||||
|
result = 31 * result + colorless;
|
||||||
|
result = 31 * result + any;
|
||||||
|
result = 31 * result + (flag ? 1 : 0);
|
||||||
|
|
||||||
|
return Long.hashCode(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public interface Condition extends Serializable {
|
||||||
boolean apply(Game game, Ability source);
|
boolean apply(Game game, Ability source);
|
||||||
|
|
||||||
default String getManaText() {
|
default String getManaText() {
|
||||||
return "{" + this.getClass().getSimpleName() + "}";
|
return this.getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean caresAboutManaColor() {
|
default boolean caresAboutManaColor() {
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ public class AddManaInAnyCombinationEffect extends ManaEffect {
|
||||||
|
|
||||||
allPossibleMana.addMana(currentPossibleMana);
|
allPossibleMana.addMana(currentPossibleMana);
|
||||||
}
|
}
|
||||||
allPossibleMana.removeDuplicated();
|
allPossibleMana.removeFullyIncludedVariations();
|
||||||
return new ArrayList<>(allPossibleMana);
|
return new ArrayList<>(allPossibleMana);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ public class ConvokeAbility extends SimpleStaticAbility implements AlternateMana
|
||||||
options.addMana(permMana);
|
options.addMana(permMana);
|
||||||
});
|
});
|
||||||
|
|
||||||
options.removeDuplicated();
|
options.removeFullyIncludedVariations();
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ public class OfferingAbility extends StaticAbility implements AlternateManaPayme
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
additionalManaOptionsForThisAbility.removeDuplicated();
|
additionalManaOptionsForThisAbility.removeFullyIncludedVariations();
|
||||||
return additionalManaOptionsForThisAbility;
|
return additionalManaOptionsForThisAbility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@ package mage.abilities.mana;
|
||||||
import mage.ConditionalMana;
|
import mage.ConditionalMana;
|
||||||
import mage.Mana;
|
import mage.Mana;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
import mage.constants.ManaType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.events.ManaEvent;
|
import mage.game.events.ManaEvent;
|
||||||
import mage.game.events.TappedForManaEvent;
|
import mage.game.events.TappedForManaEvent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
import mage.util.TreeNode;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -19,10 +21,14 @@ import java.util.*;
|
||||||
* be used to find all the ways to pay a mana cost or all the different mana
|
* be used to find all the ways to pay a mana cost or all the different mana
|
||||||
* combinations available to a player
|
* combinations available to a player
|
||||||
* <p>
|
* <p>
|
||||||
* TODO: Conditional Mana is not supported yet. The mana adding removes the
|
* TODO: Conditional Mana is not supported yet.
|
||||||
* condition of conditional mana
|
* The mana adding removes the condition of conditional mana
|
||||||
|
* <p>
|
||||||
|
* A LinkedHashSet is used to get the performance benefits of automatic de-duplication of the Mana
|
||||||
|
* to avoid performance issues related with manual de-duplication (see https://github.com/magefree/mage/issues/7710).
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class ManaOptions extends ArrayList<Mana> {
|
public class ManaOptions extends LinkedHashSet<Mana> {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ManaOptions.class);
|
private static final Logger logger = Logger.getLogger(ManaOptions.class);
|
||||||
|
|
||||||
|
|
@ -39,69 +45,68 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
this.add(new Mana());
|
this.add(new Mana());
|
||||||
}
|
}
|
||||||
if (!abilities.isEmpty()) {
|
if (abilities.isEmpty()) {
|
||||||
if (abilities.size() == 1) {
|
return; // Do nothing
|
||||||
//if there is only one mana option available add it to all the existing options
|
}
|
||||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
|
||||||
if (netManas.size() == 1) {
|
|
||||||
checkManaReplacementAndTriggeredMana(abilities.get(0), game, netManas.get(0));
|
|
||||||
addMana(netManas.get(0));
|
|
||||||
addTriggeredMana(game, abilities.get(0));
|
|
||||||
} else if (netManas.size() > 1) {
|
|
||||||
addManaVariation(netManas, abilities.get(0), game);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { // mana source has more than 1 ability
|
if (abilities.size() == 1) {
|
||||||
//perform a union of all existing options and the new options
|
//if there is only one mana option available add it to all the existing options
|
||||||
List<Mana> copy = copy();
|
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||||
this.clear();
|
if (netManas.size() == 1) {
|
||||||
for (ActivatedManaAbilityImpl ability : abilities) {
|
checkManaReplacementAndTriggeredMana(abilities.get(0), game, netManas.get(0));
|
||||||
for (Mana netMana : ability.getNetMana(game)) {
|
addMana(netManas.get(0));
|
||||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
addTriggeredMana(game, abilities.get(0));
|
||||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
} else if (netManas.size() > 1) {
|
||||||
SkipAddMana:
|
addManaVariation(netManas, abilities.get(0), game);
|
||||||
for (Mana mana : copy) {
|
}
|
||||||
Mana newMana = new Mana();
|
|
||||||
newMana.add(mana);
|
} else { // mana source has more than 1 ability
|
||||||
newMana.add(triggeredManaVariation);
|
//perform a union of all existing options and the new options
|
||||||
for (Mana existingMana : this) {
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
if (existingMana.equalManaValue(newMana)) {
|
this.clear();
|
||||||
continue SkipAddMana;
|
for (ActivatedManaAbilityImpl ability : abilities) {
|
||||||
}
|
for (Mana netMana : ability.getNetMana(game)) {
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||||
if (moreValuable != null) {
|
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||||
// only keep the more valuable mana
|
SkipAddMana:
|
||||||
existingMana.setToMana(moreValuable);
|
for (Mana mana : copy) {
|
||||||
continue SkipAddMana;
|
Mana newMana = new Mana();
|
||||||
}
|
newMana.add(mana);
|
||||||
|
newMana.add(triggeredManaVariation);
|
||||||
|
for (Mana existingMana : this) {
|
||||||
|
if (existingMana.equalManaValue(newMana)) {
|
||||||
|
continue SkipAddMana;
|
||||||
|
}
|
||||||
|
Mana moreValuable = Mana.getMoreValuableMana(newMana, existingMana);
|
||||||
|
if (moreValuable != null) {
|
||||||
|
// only keep the more valuable mana
|
||||||
|
existingMana.setToMana(moreValuable);
|
||||||
|
continue SkipAddMana;
|
||||||
}
|
}
|
||||||
this.add(newMana);
|
|
||||||
}
|
}
|
||||||
|
this.add(newMana);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forceManaDeduplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addManaVariation(List<Mana> netManas, ActivatedManaAbilityImpl ability, Game game) {
|
private void addManaVariation(List<Mana> netManas, ActivatedManaAbilityImpl ability, Game game) {
|
||||||
List<Mana> copy = copy();
|
Mana newMana;
|
||||||
|
|
||||||
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana netMana : netManas) {
|
for (Mana netMana : netManas) {
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
if (!ability.hasTapCost() || checkManaReplacementAndTriggeredMana(ability, game, netMana)) {
|
if (!ability.hasTapCost() || checkManaReplacementAndTriggeredMana(ability, game, netMana)) {
|
||||||
Mana newMana = new Mana();
|
newMana = mana.copy();
|
||||||
newMana.add(mana);
|
|
||||||
newMana.add(netMana);
|
newMana.add(netMana);
|
||||||
this.add(newMana);
|
this.add(newMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forceManaDeduplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<List<Mana>> getSimulatedTriggeredManaFromPlayer(Game game, Ability ability) {
|
private static List<List<Mana>> getSimulatedTriggeredManaFromPlayer(Game game, Ability ability) {
|
||||||
|
|
@ -138,8 +143,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This adds the mana the abilities can produce to the possible mana
|
* This adds the mana the abilities can produce to the possible mana variation.
|
||||||
* variabtion.
|
|
||||||
*
|
*
|
||||||
* @param abilities
|
* @param abilities
|
||||||
* @param game
|
* @param game
|
||||||
|
|
@ -147,14 +151,13 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
*/
|
*/
|
||||||
public boolean addManaWithCost(List<ActivatedManaAbilityImpl> abilities, Game game) {
|
public boolean addManaWithCost(List<ActivatedManaAbilityImpl> abilities, Game game) {
|
||||||
boolean wasUsable = false;
|
boolean wasUsable = false;
|
||||||
int replaces = 0;
|
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
this.add(new Mana()); // needed if this is the first available mana, otherwise looping over existing options woold not loop
|
this.add(new Mana()); // needed if this is the first available mana, otherwise looping over existing options woold not loop
|
||||||
}
|
}
|
||||||
if (!abilities.isEmpty()) {
|
if (!abilities.isEmpty()) {
|
||||||
if (abilities.size() == 1) {
|
if (abilities.size() == 1) {
|
||||||
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
List<Mana> netManas = abilities.get(0).getNetMana(game);
|
||||||
if (netManas.size() > 0) { // ability can produce mana
|
if (!netManas.isEmpty()) { // ability can produce mana
|
||||||
ActivatedManaAbilityImpl ability = abilities.get(0);
|
ActivatedManaAbilityImpl ability = abilities.get(0);
|
||||||
// The ability has no mana costs
|
// The ability has no mana costs
|
||||||
if (ability.getManaCosts().isEmpty()) { // No mana costs, so no mana to subtract from available
|
if (ability.getManaCosts().isEmpty()) { // No mana costs, so no mana to subtract from available
|
||||||
|
|
@ -163,14 +166,13 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
addMana(netManas.get(0));
|
addMana(netManas.get(0));
|
||||||
addTriggeredMana(game, ability);
|
addTriggeredMana(game, ability);
|
||||||
} else {
|
} else {
|
||||||
List<Mana> copy = copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana netMana : netManas) {
|
for (Mana netMana : netManas) {
|
||||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
Mana newMana = new Mana();
|
Mana newMana = new Mana(mana);
|
||||||
newMana.add(mana);
|
|
||||||
newMana.add(triggeredManaVariation);
|
newMana.add(triggeredManaVariation);
|
||||||
this.add(newMana);
|
this.add(newMana);
|
||||||
wasUsable = true;
|
wasUsable = true;
|
||||||
|
|
@ -179,23 +181,22 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {// The ability has mana costs
|
} else {// The ability has mana costs
|
||||||
List<Mana> copy = copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
|
Mana manaCosts = ability.getManaCosts().getMana();
|
||||||
for (Mana netMana : netManas) {
|
for (Mana netMana : netManas) {
|
||||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||||
for (Mana prevMana : copy) {
|
for (Mana startingMana : copy) {
|
||||||
Mana startingMana = prevMana.copy();
|
|
||||||
Mana manaCosts = ability.getManaCosts().getMana();
|
|
||||||
if (startingMana.includesMana(manaCosts)) { // can pay the mana costs to use the ability
|
if (startingMana.includesMana(manaCosts)) { // can pay the mana costs to use the ability
|
||||||
if (!subtractCostAddMana(manaCosts, triggeredManaVariation, ability.getCosts().isEmpty(), startingMana, ability, game)) {
|
if (!subtractCostAddMana(manaCosts, triggeredManaVariation, ability.getCosts().isEmpty(), startingMana, ability, game)) {
|
||||||
// the starting mana includes mana parts that the increased mana does not include, so add starting mana also as an option
|
// the starting mana includes mana parts that the increased mana does not include, so add starting mana also as an option
|
||||||
add(prevMana);
|
add(startingMana);
|
||||||
}
|
}
|
||||||
wasUsable = true;
|
wasUsable = true;
|
||||||
} else {
|
} else {
|
||||||
// mana costs can't be paid so keep starting mana
|
// mana costs can't be paid so keep starting mana
|
||||||
add(prevMana);
|
add(startingMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +205,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//perform a union of all existing options and the new options
|
//perform a union of all existing options and the new options
|
||||||
List<Mana> copy = copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (ActivatedManaAbilityImpl ability : abilities) {
|
for (ActivatedManaAbilityImpl ability : abilities) {
|
||||||
List<Mana> netManas = ability.getNetMana(game);
|
List<Mana> netManas = ability.getNetMana(game);
|
||||||
|
|
@ -213,8 +214,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
Mana newMana = new Mana();
|
Mana newMana = new Mana(mana);
|
||||||
newMana.add(mana);
|
|
||||||
newMana.add(triggeredManaVariation);
|
newMana.add(triggeredManaVariation);
|
||||||
this.add(newMana);
|
this.add(newMana);
|
||||||
wasUsable = true;
|
wasUsable = true;
|
||||||
|
|
@ -226,9 +226,9 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
checkManaReplacementAndTriggeredMana(ability, game, netMana);
|
||||||
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
for (Mana triggeredManaVariation : getTriggeredManaVariations(game, ability, netMana)) {
|
||||||
for (Mana previousMana : copy) {
|
for (Mana previousMana : copy) {
|
||||||
CombineWithExisting:
|
|
||||||
for (Mana manaOption : ability.getManaCosts().getManaOptions()) {
|
for (Mana manaOption : ability.getManaCosts().getManaOptions()) {
|
||||||
if (previousMana.includesMana(manaOption)) { // costs can be paid
|
if (previousMana.includesMana(manaOption)) { // costs can be paid
|
||||||
|
// subtractCostAddMana has side effects on {this}. Do not add wasUsable to the if-statement above
|
||||||
wasUsable |= subtractCostAddMana(manaOption, triggeredManaVariation, ability.getCosts().isEmpty(), previousMana, ability, game);
|
wasUsable |= subtractCostAddMana(manaOption, triggeredManaVariation, ability.getCosts().isEmpty(), previousMana, ability, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -241,41 +241,41 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.size() > 30 || replaces > 30) {
|
if (logger.isTraceEnabled() && this.size() > 30) {
|
||||||
logger.trace("ManaOptionsCosts " + this.size() + " Ign:" + replaces + " => " + this.toString());
|
logger.trace("ManaOptionsCosts " + this.size());
|
||||||
logger.trace("Abilities: " + abilities.toString());
|
logger.trace("Abilities: " + abilities.toString());
|
||||||
}
|
}
|
||||||
forceManaDeduplication();
|
|
||||||
|
|
||||||
return wasUsable;
|
return wasUsable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addManaPoolDependant(List<ActivatedManaAbilityImpl> abilities, Game game) {
|
public boolean addManaPoolDependant(List<ActivatedManaAbilityImpl> abilities, Game game) {
|
||||||
|
if (abilities.isEmpty() || abilities.size() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
boolean wasUsable = false;
|
boolean wasUsable = false;
|
||||||
if (!abilities.isEmpty()) {
|
ActivatedManaAbilityImpl ability = (ActivatedManaAbilityImpl) abilities.get(0);
|
||||||
if (abilities.size() == 1) {
|
Mana manaCosts = ability.getManaCosts().getMana();
|
||||||
ActivatedManaAbilityImpl ability = (ActivatedManaAbilityImpl) abilities.get(0);
|
|
||||||
List<Mana> copy = copy();
|
Set<Mana> copy = copy();
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana previousMana : copy) {
|
|
||||||
Mana startingMana = previousMana.copy();
|
for (Mana previousMana : copy) {
|
||||||
Mana manaCosts = ability.getManaCosts().getMana();
|
if (previousMana.includesMana(manaCosts)) { // can pay the mana costs to use the ability
|
||||||
if (startingMana.includesMana(manaCosts)) { // can pay the mana costs to use the ability
|
for (Mana manaOption : ability.getManaCosts().getManaOptions()) {
|
||||||
for (Mana manaOption : ability.getManaCosts().getManaOptions()) {
|
if (!subtractCostAddMana(manaOption, null, ability.getCosts().isEmpty(), previousMana, ability, game)) {
|
||||||
if (!subtractCostAddMana(manaOption, null, ability.getCosts().isEmpty(), startingMana, ability, game)) {
|
// the starting mana includes mana parts that the increased mana does not include, so add starting mana also as an option
|
||||||
// the starting mana includes mana parts that the increased mana does not include, so add starting mana also as an option
|
|
||||||
add(previousMana);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wasUsable = true;
|
|
||||||
} else {
|
|
||||||
// mana costs can't be paid so keep starting mana
|
|
||||||
add(previousMana);
|
add(previousMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wasUsable = true;
|
||||||
|
} else {
|
||||||
|
// mana costs can't be paid so keep starting mana
|
||||||
|
add(previousMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wasUsable;
|
return wasUsable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,20 +311,17 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
addMana(triggeredNetMana.get(0));
|
addMana(triggeredNetMana.get(0));
|
||||||
} else if (triggeredNetMana.size() > 1) {
|
} else if (triggeredNetMana.size() > 1) {
|
||||||
// Add variations
|
// Add variations
|
||||||
List<Mana> copy = copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana triggeredMana : triggeredNetMana) {
|
for (Mana triggeredMana : triggeredNetMana) {
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
Mana newMana = new Mana();
|
Mana newMana = new Mana(mana);
|
||||||
newMana.add(mana);
|
|
||||||
newMana.add(triggeredMana);
|
newMana.add(triggeredMana);
|
||||||
this.add(newMana);
|
this.add(newMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forceManaDeduplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -337,7 +334,7 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
this.add(new Mana());
|
this.add(new Mana());
|
||||||
}
|
}
|
||||||
if (addMana instanceof ConditionalMana) {
|
if (addMana instanceof ConditionalMana) {
|
||||||
ManaOptions copy = this.copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
ConditionalMana condMana = ((ConditionalMana) addMana).copy();
|
ConditionalMana condMana = ((ConditionalMana) addMana).copy();
|
||||||
|
|
@ -351,8 +348,6 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
mana.add(addMana);
|
mana.add(addMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forceManaDeduplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMana(ManaOptions options) {
|
public void addMana(ManaOptions options) {
|
||||||
|
|
@ -362,32 +357,20 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
if (!options.isEmpty()) {
|
if (!options.isEmpty()) {
|
||||||
if (options.size() == 1) {
|
if (options.size() == 1) {
|
||||||
//if there is only one mana option available add it to all the existing options
|
//if there is only one mana option available add it to all the existing options
|
||||||
addMana(options.get(0));
|
addMana(options.getAtIndex(0));
|
||||||
} else {
|
} else {
|
||||||
//perform a union of all existing options and the new options
|
//perform a union of all existing options and the new options
|
||||||
List<Mana> copy = copy();
|
List<Mana> copy = new ArrayList<>(this);
|
||||||
this.clear();
|
this.clear();
|
||||||
for (Mana addMana : options) {
|
for (Mana addMana : options) {
|
||||||
for (Mana mana : copy) {
|
for (Mana mana : copy) {
|
||||||
Mana newMana = new Mana();
|
Mana newMana = new Mana(mana);
|
||||||
newMana.add(mana);
|
|
||||||
newMana.add(addMana);
|
newMana.add(addMana);
|
||||||
this.add(newMana);
|
this.add(newMana);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forceManaDeduplication();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void forceManaDeduplication() {
|
|
||||||
// memory overflow protection - force de-duplication on too much mana sources
|
|
||||||
// bug example: https://github.com/magefree/mage/issues/6938
|
|
||||||
// use it after new mana adding
|
|
||||||
if (this.size() > 1000) {
|
|
||||||
this.removeDuplicated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManaOptions copy() {
|
public ManaOptions copy() {
|
||||||
|
|
@ -406,62 +389,46 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
* @param oldManaWasReplaced returns the info if the new complete mana does
|
* @param oldManaWasReplaced returns the info if the new complete mana does
|
||||||
* replace the current mana completely
|
* replace the current mana completely
|
||||||
*/
|
*/
|
||||||
private boolean subtractCostAddMana(Mana cost, Mana manaToAdd, boolean onlyManaCosts, Mana currentMana, ManaAbility manaAbility, Game game) {
|
private boolean subtractCostAddMana(Mana cost, Mana manaToAdd, boolean onlyManaCosts, final Mana currentMana, ManaAbility manaAbility, Game game) {
|
||||||
boolean oldManaWasReplaced = false; // true if the newly created mana includes all mana possibilities of the old
|
boolean oldManaWasReplaced = false; // True if the newly created mana includes all mana possibilities of the old
|
||||||
boolean repeatable = false;
|
boolean repeatable = manaToAdd != null // TODO: re-write "only replace to any with mana costs only will be repeated if able"
|
||||||
if (manaToAdd != null && (manaToAdd.countColored() > 0 || manaToAdd.getAny() > 0) && manaToAdd.count() > 0 && onlyManaCosts) {
|
&& onlyManaCosts
|
||||||
repeatable = true; // only replace to any with mana costs only will be repeated if able
|
&& (manaToAdd.getAny() > 0 || manaToAdd.countColored() > 0)
|
||||||
}
|
&& manaToAdd.count() > 0;
|
||||||
|
boolean newCombinations;
|
||||||
|
|
||||||
|
Mana newMana = new Mana();
|
||||||
|
Mana currentManaCopy = new Mana();
|
||||||
|
|
||||||
for (Mana payCombination : ManaOptions.getPossiblePayCombinations(cost, currentMana)) {
|
for (Mana payCombination : ManaOptions.getPossiblePayCombinations(cost, currentMana)) {
|
||||||
Mana currentManaCopy = currentMana.copy(); // copy start mana because in iteration it will be updated
|
currentManaCopy.setToMana(currentMana); // copy start mana because in iteration it will be updated
|
||||||
while (currentManaCopy.includesMana(payCombination)) { // loop for multiple usage if possible
|
do { // loop for multiple usage if possible
|
||||||
boolean newCombinations = false;
|
newCombinations = false;
|
||||||
|
|
||||||
if (manaToAdd == null) {
|
newMana.setToMana(currentManaCopy);
|
||||||
Mana newMana = currentManaCopy.copy();
|
newMana.subtract(payCombination);
|
||||||
newMana.subtract(payCombination);
|
// Get the mana to iterate over.
|
||||||
for (Mana mana : manaAbility.getNetMana(game, newMana)) { // get the mana to add from the ability related to the currently generated possible mana pool
|
// If manaToAdd is specified add it, otherwise add the mana produced by the mana ability
|
||||||
newMana.add(mana);
|
List<Mana> manasToAdd = (manaToAdd != null) ? Collections.singletonList(manaToAdd) : manaAbility.getNetMana(game, newMana);
|
||||||
if (!isExistingManaCombination(newMana)) {
|
for (Mana mana : manasToAdd) {
|
||||||
this.add(newMana); // add the new combination
|
newMana.add(mana);
|
||||||
newCombinations = true; // repeat the while as long there are new combinations and usage is repeatable
|
if (this.contains(newMana)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(currentManaCopy, newMana);
|
this.add(newMana.copy()); // add the new combination
|
||||||
if (newMana.equals(moreValuable)) {
|
newCombinations = true; // repeat the while as long there are new combinations and usage is repeatable
|
||||||
oldManaWasReplaced = true; // the new mana includes all possibilities of the old one, so no need to add it after return
|
|
||||||
if (!currentMana.equalManaValue(currentManaCopy)) {
|
if (newMana.isMoreValuableThan(currentManaCopy)) {
|
||||||
this.removeEqualMana(currentManaCopy);
|
oldManaWasReplaced = true; // the new mana includes all possible mana of the old one, so no need to add it after return
|
||||||
}
|
if (!currentMana.equalManaValue(currentManaCopy)) {
|
||||||
}
|
this.removeEqualMana(currentManaCopy);
|
||||||
currentManaCopy = newMana.copy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
currentManaCopy.setToMana(newMana);
|
||||||
Mana newMana = currentManaCopy.copy();
|
|
||||||
newMana.subtract(payCombination);
|
|
||||||
newMana.add(manaToAdd);
|
|
||||||
if (!isExistingManaCombination(newMana)) {
|
|
||||||
this.add(newMana); // add the new combination
|
|
||||||
newCombinations = true; // repeat the while as long there are new combinations and usage is repeatable
|
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(currentManaCopy, newMana);
|
|
||||||
if (newMana.equals(moreValuable)) {
|
|
||||||
oldManaWasReplaced = true; // the new mana includes all possible mana of the old one, so no need to add it after return
|
|
||||||
if (!currentMana.equalManaValue(currentManaCopy)) {
|
|
||||||
this.removeEqualMana(currentManaCopy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentManaCopy = newMana.copy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!newCombinations || !repeatable) {
|
} while (repeatable && newCombinations && currentManaCopy.includesMana(payCombination));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
forceManaDeduplication();
|
|
||||||
|
|
||||||
return oldManaWasReplaced;
|
return oldManaWasReplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -470,86 +437,72 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
* @param manaAvailable
|
* @param manaAvailable
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static List<Mana> getPossiblePayCombinations(Mana manaCost, Mana manaAvailable) {
|
public static Set<Mana> getPossiblePayCombinations(Mana manaCost, Mana manaAvailable) {
|
||||||
List<Mana> payCombinations = new ArrayList<>();
|
Set<Mana> payCombinations = new HashSet<>();
|
||||||
List<String> payCombinationsStrings = new ArrayList<>();
|
|
||||||
// handle fixed mana costs
|
|
||||||
Mana fixedMana = manaCost.copy();
|
Mana fixedMana = manaCost.copy();
|
||||||
|
|
||||||
|
// If there are no generic costs, then there is only one combination of colors available to pay for it.
|
||||||
|
// That combination is itself (fixedMana)
|
||||||
if (manaCost.getGeneric() == 0) {
|
if (manaCost.getGeneric() == 0) {
|
||||||
payCombinations.add(fixedMana);
|
payCombinations.add(fixedMana);
|
||||||
return payCombinations;
|
return payCombinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the available mana left to pay for the cost after subtracting the non-generic parts of the cost from it
|
||||||
fixedMana.setGeneric(0);
|
fixedMana.setGeneric(0);
|
||||||
Mana manaAfterFixedPayment = manaAvailable.copy();
|
Mana manaAfterFixedPayment = manaAvailable.copy();
|
||||||
manaAfterFixedPayment.subtract(fixedMana);
|
manaAfterFixedPayment.subtract(fixedMana);
|
||||||
|
|
||||||
// handle generic mana costs
|
// handle generic mana costs
|
||||||
if (manaAvailable.countColored() > 0) {
|
if (manaAvailable.countColored() == 0) {
|
||||||
|
payCombinations.add(Mana.ColorlessMana(manaCost.getGeneric()));
|
||||||
|
} else {
|
||||||
|
ManaType[] manaTypes = ManaType.values(); // Do not move, here for optimization reasons.
|
||||||
|
Mana manaToPayFrom = new Mana();
|
||||||
for (int i = 0; i < manaCost.getGeneric(); i++) {
|
for (int i = 0; i < manaCost.getGeneric(); i++) {
|
||||||
List<Mana> existingManas = new ArrayList<>();
|
List<Mana> existingManas = new ArrayList<>(payCombinations.size());
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
existingManas.addAll(payCombinations);
|
existingManas.addAll(payCombinations);
|
||||||
payCombinations.clear();
|
payCombinations.clear();
|
||||||
payCombinationsStrings.clear();
|
|
||||||
} else {
|
} else {
|
||||||
existingManas.add(new Mana());
|
existingManas.add(new Mana());
|
||||||
}
|
}
|
||||||
for (Mana existingMana : existingManas) {
|
|
||||||
Mana manaToPayFrom = manaAfterFixedPayment.copy();
|
|
||||||
manaToPayFrom.subtract(existingMana);
|
|
||||||
String manaString = existingMana.toString();
|
|
||||||
|
|
||||||
if (manaToPayFrom.getBlack() > 0 && !payCombinationsStrings.contains(manaString + Mana.BlackMana(1))) {
|
for (Mana existingMana : existingManas) {
|
||||||
manaToPayFrom.subtract(Mana.BlackMana(1));
|
manaToPayFrom.setToMana(manaAfterFixedPayment);
|
||||||
ManaOptions.addManaCombination(Mana.BlackMana(1), existingMana, payCombinations, payCombinationsStrings);
|
manaToPayFrom.subtract(existingMana);
|
||||||
}
|
|
||||||
if (manaToPayFrom.getBlue() > 0 && !payCombinationsStrings.contains(manaString + Mana.BlueMana(1).toString())) {
|
for (ManaType manaType : manaTypes) {
|
||||||
manaToPayFrom.subtract(Mana.BlueMana(1));
|
existingMana.increase(manaType);
|
||||||
ManaOptions.addManaCombination(Mana.BlueMana(1), existingMana, payCombinations, payCombinationsStrings);
|
if (manaToPayFrom.get(manaType) > 0 && !payCombinations.contains(existingMana)) {
|
||||||
}
|
payCombinations.add(existingMana.copy());
|
||||||
if (manaToPayFrom.getGreen() > 0 && !payCombinationsStrings.contains(manaString + Mana.GreenMana(1).toString())) {
|
|
||||||
manaToPayFrom.subtract(Mana.GreenMana(1));
|
manaToPayFrom.decrease(manaType);
|
||||||
ManaOptions.addManaCombination(Mana.GreenMana(1), existingMana, payCombinations, payCombinationsStrings);
|
}
|
||||||
}
|
existingMana.decrease(manaType);
|
||||||
if (manaToPayFrom.getRed() > 0 && !payCombinationsStrings.contains(manaString + Mana.RedMana(1).toString())) {
|
|
||||||
manaToPayFrom.subtract(Mana.RedMana(1));
|
|
||||||
ManaOptions.addManaCombination(Mana.RedMana(1), existingMana, payCombinations, payCombinationsStrings);
|
|
||||||
}
|
|
||||||
if (manaToPayFrom.getWhite() > 0 && !payCombinationsStrings.contains(manaString + Mana.WhiteMana(1).toString())) {
|
|
||||||
manaToPayFrom.subtract(Mana.WhiteMana(1));
|
|
||||||
ManaOptions.addManaCombination(Mana.WhiteMana(1), existingMana, payCombinations, payCombinationsStrings);
|
|
||||||
}
|
|
||||||
if (manaToPayFrom.getColorless() > 0 && !payCombinationsStrings.contains(manaString + Mana.ColorlessMana(1).toString())) {
|
|
||||||
manaToPayFrom.subtract(Mana.ColorlessMana(1));
|
|
||||||
ManaOptions.addManaCombination(Mana.ColorlessMana(1), existingMana, payCombinations, payCombinationsStrings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pay with any only needed if colored payment was not possible
|
// Pay with any only needed if colored payment was not possible
|
||||||
if (payCombinations.isEmpty() && manaToPayFrom.getAny() > 0 && !payCombinationsStrings.contains(manaString + Mana.AnyMana(1).toString())) {
|
// NOTE: This isn't in the for loop since ManaType doesn't include ANY.
|
||||||
manaToPayFrom.subtract(Mana.AnyMana(1));
|
existingMana.increaseAny();
|
||||||
ManaOptions.addManaCombination(Mana.AnyMana(1), existingMana, payCombinations, payCombinationsStrings);
|
if (payCombinations.isEmpty() && manaToPayFrom.getAny() > 0) {
|
||||||
|
payCombinations.add(existingMana.copy());
|
||||||
|
|
||||||
|
manaToPayFrom.decreaseAny();
|
||||||
}
|
}
|
||||||
|
existingMana.decreaseAny();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
payCombinations.add(Mana.ColorlessMana(manaCost.getGeneric()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Mana mana : payCombinations) {
|
for (Mana mana : payCombinations) {
|
||||||
mana.add(fixedMana);
|
mana.add(fixedMana);
|
||||||
}
|
}
|
||||||
|
// All mana values in here are of length 5
|
||||||
return payCombinations;
|
return payCombinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isExistingManaCombination(Mana newMana) {
|
|
||||||
for (Mana mana : this) {
|
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(mana, newMana);
|
|
||||||
if (mana.equals(moreValuable)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeEqualMana(Mana manaToRemove) {
|
public boolean removeEqualMana(Mana manaToRemove) {
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
for (Iterator<Mana> iterator = this.iterator(); iterator.hasNext(); ) {
|
for (Iterator<Mana> iterator = this.iterator(); iterator.hasNext(); ) {
|
||||||
|
|
@ -562,22 +515,20 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addManaCombination(Mana mana, Mana existingMana, List<Mana> payCombinations, List<String> payCombinationsStrings) {
|
/**
|
||||||
Mana newMana = existingMana.copy();
|
* Remove fully included variations.
|
||||||
newMana.add(mana);
|
* E.g. If both {R} and {R}{W} are in this, then {R} will be removed.
|
||||||
payCombinations.add(newMana);
|
*/
|
||||||
payCombinationsStrings.add(newMana.toString());
|
public void removeFullyIncludedVariations() {
|
||||||
}
|
List<Mana> that = new ArrayList<>(this);
|
||||||
|
|
||||||
public void removeDuplicated() {
|
|
||||||
Set<String> list = new HashSet<>();
|
Set<String> list = new HashSet<>();
|
||||||
|
|
||||||
for (int i = this.size() - 1; i >= 0; i--) {
|
for (int i = this.size() - 1; i >= 0; i--) {
|
||||||
String s;
|
String s;
|
||||||
if (this.get(i) instanceof ConditionalMana) {
|
if (that.get(i) instanceof ConditionalMana) {
|
||||||
s = this.get(i).toString() + ((ConditionalMana) this.get(i)).getConditionString();
|
s = that.get(i).toString() + ((ConditionalMana) that.get(i)).getConditionString();
|
||||||
} else {
|
} else {
|
||||||
s = this.get(i).toString();
|
s = that.get(i).toString();
|
||||||
}
|
}
|
||||||
if (s.isEmpty()) {
|
if (s.isEmpty()) {
|
||||||
this.remove(i);
|
this.remove(i);
|
||||||
|
|
@ -590,18 +541,19 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove fully included variations
|
// Remove fully included variations
|
||||||
// TODO: research too many manas and freeze (put 1 card to slow down, put 3 cards to freeze here)
|
|
||||||
// battlefield:Human:Cascading Cataracts:1
|
|
||||||
for (int i = this.size() - 1; i >= 0; i--) {
|
for (int i = this.size() - 1; i >= 0; i--) {
|
||||||
for (int ii = 0; ii < i; ii++) {
|
for (int ii = 0; ii < i; ii++) {
|
||||||
Mana moreValuable = Mana.getMoreValuableMana(this.get(i), this.get(ii));
|
Mana moreValuable = Mana.getMoreValuableMana(that.get(i), that.get(ii));
|
||||||
if (moreValuable != null) {
|
if (moreValuable != null) {
|
||||||
this.get(ii).setToMana(moreValuable);
|
that.get(ii).setToMana(moreValuable);
|
||||||
this.remove(i);
|
that.remove(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.clear();
|
||||||
|
this.addAll(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -648,4 +600,81 @@ public class ManaOptions extends ArrayList<Mana> {
|
||||||
sb.append(',').append(' ');
|
sb.append(',').append(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility function to get a Mana from ManaOptions at the specified position.
|
||||||
|
* Since the implementation uses a LinkedHashSet the ordering of the items is preserved.
|
||||||
|
*
|
||||||
|
* NOTE: Do not use in tight loops as performance of the lookup is much worse than
|
||||||
|
* for ArrayList (the previous superclass of ManaOptions).
|
||||||
|
*/
|
||||||
|
public Mana getAtIndex(int i) {
|
||||||
|
if (i < 0 || i >= this.size()) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
Iterator<Mana> itr = this.iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
if (i == 0) {
|
||||||
|
return itr.next();
|
||||||
|
} else {
|
||||||
|
itr.next(); // Ignore the value
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null; // Not sure how we'd ever get here, but leave just in case since IDE complains.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* from: https://stackoverflow.com/a/35000727/7983747
|
||||||
|
* @author Gili Tzabari
|
||||||
|
*/
|
||||||
|
final class Comparators
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Verify that a comparator is transitive.
|
||||||
|
*
|
||||||
|
* @param <T> the type being compared
|
||||||
|
* @param comparator the comparator to test
|
||||||
|
* @param elements the elements to test against
|
||||||
|
* @throws AssertionError if the comparator is not transitive
|
||||||
|
*/
|
||||||
|
public static <T> void verifyTransitivity(Comparator<T> comparator, Collection<T> elements) {
|
||||||
|
for (T first: elements) {
|
||||||
|
for (T second: elements) {
|
||||||
|
int result1 = comparator.compare(first, second);
|
||||||
|
int result2 = comparator.compare(second, first);
|
||||||
|
if (result1 != -result2 && !(result1 == 0 && result1 == result2)) {
|
||||||
|
// Uncomment the following line to step through the failed case
|
||||||
|
comparator.compare(first, second);
|
||||||
|
comparator.compare(second, first);
|
||||||
|
throw new AssertionError("compare(" + first + ", " + second + ") == " + result1 +
|
||||||
|
" but swapping the parameters returns " + result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (T first: elements) {
|
||||||
|
for (T second: elements) {
|
||||||
|
int firstGreaterThanSecond = comparator.compare(first, second);
|
||||||
|
if (firstGreaterThanSecond <= 0)
|
||||||
|
continue;
|
||||||
|
for (T third: elements) {
|
||||||
|
int secondGreaterThanThird = comparator.compare(second, third);
|
||||||
|
if (secondGreaterThanThird <= 0)
|
||||||
|
continue;
|
||||||
|
int firstGreaterThanThird = comparator.compare(first, third);
|
||||||
|
if (firstGreaterThanThird <= 0) {
|
||||||
|
// Uncomment the following line to step through the failed case
|
||||||
|
comparator.compare(first, second);
|
||||||
|
comparator.compare(second, third);
|
||||||
|
comparator.compare(first, third);
|
||||||
|
throw new AssertionError("compare(" + first + ", " + second + ") > 0, " +
|
||||||
|
"compare(" + second + ", " + third + ") > 0, but compare(" + first + ", " + third + ") == " +
|
||||||
|
firstGreaterThanThird);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Comparators() {}
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,8 @@ import mage.Mana;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author noxx
|
* @author noxx
|
||||||
*/
|
*/
|
||||||
|
|
@ -19,4 +21,22 @@ public abstract class ConditionalManaBuilder implements Builder<ConditionalMana>
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract String getRule();
|
public abstract String getRule();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == null || this.getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(this.mana, ((ConditionalManaBuilder) obj).mana);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mana);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@ import mage.game.Game;
|
||||||
import mage.game.command.Commander;
|
import mage.game.command.Commander;
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.game.stack.StackObject;
|
import mage.game.stack.StackObject;
|
||||||
|
import sun.font.CreatedFontTracker;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,6 +40,20 @@ public class ConditionalSpellManaBuilder extends ConditionalManaBuilder {
|
||||||
public String getRule() {
|
public String getRule() {
|
||||||
return "Spend this mana only to cast " + filter.getMessage() + '.';
|
return "Spend this mana only to cast " + filter.getMessage() + '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), this.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(this.filter, ((ConditionalSpellManaBuilder) obj).filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SpellCastConditionalMana extends ConditionalMana {
|
class SpellCastConditionalMana extends ConditionalMana {
|
||||||
|
|
|
||||||
|
|
@ -3352,7 +3352,6 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
}
|
}
|
||||||
if (used) {
|
if (used) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
availableMana.removeDuplicated();
|
|
||||||
anAbilityWasUsed = true;
|
anAbilityWasUsed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3363,9 +3362,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove duplicated variants (see ManaOptionsTest for info - when that rises)
|
availableMana.removeFullyIncludedVariations();
|
||||||
availableMana.removeDuplicated();
|
availableMana.remove(new Mana()); // Remove any empty mana that was left over from the way the code is written
|
||||||
|
|
||||||
game.setCheckPlayableState(oldState);
|
game.setCheckPlayableState(oldState);
|
||||||
return availableMana;
|
return availableMana;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ public final class CardUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore unknown mana
|
// ignore unknown mana
|
||||||
if (manaCost.getOptions().size() == 0) {
|
if (manaCost.getOptions().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@ public final class CardUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generic mana reduce
|
// generic mana reduce
|
||||||
Mana mana = manaCost.getOptions().get(0);
|
Mana mana = manaCost.getOptions().getAtIndex(0);
|
||||||
int colorless = mana != null ? mana.getGeneric() : 0;
|
int colorless = mana != null ? mana.getGeneric() : 0;
|
||||||
if (restToReduce != 0 && colorless > 0) {
|
if (restToReduce != 0 && colorless > 0) {
|
||||||
if ((colorless - restToReduce) > 0) {
|
if ((colorless - restToReduce) > 0) {
|
||||||
|
|
@ -219,7 +219,7 @@ public final class CardUtil {
|
||||||
if (manaCost instanceof MonoHybridManaCost) {
|
if (manaCost instanceof MonoHybridManaCost) {
|
||||||
// current implemention supports reduce from left to right hybrid cost without cost parts announce
|
// current implemention supports reduce from left to right hybrid cost without cost parts announce
|
||||||
MonoHybridManaCost mono = (MonoHybridManaCost) manaCost;
|
MonoHybridManaCost mono = (MonoHybridManaCost) manaCost;
|
||||||
int colorless = mono.getOptions().get(1).getGeneric();
|
int colorless = mono.getOptions().getAtIndex(1).getGeneric();
|
||||||
if (restToReduce != 0 && colorless > 0) {
|
if (restToReduce != 0 && colorless > 0) {
|
||||||
if ((colorless - restToReduce) > 0) {
|
if ((colorless - restToReduce) > 0) {
|
||||||
// partly reduce
|
// partly reduce
|
||||||
|
|
@ -254,7 +254,7 @@ public final class CardUtil {
|
||||||
// add to existing cost
|
// add to existing cost
|
||||||
if (reduceCount != 0 && manaCost instanceof GenericManaCost) {
|
if (reduceCount != 0 && manaCost instanceof GenericManaCost) {
|
||||||
GenericManaCost gen = (GenericManaCost) manaCost;
|
GenericManaCost gen = (GenericManaCost) manaCost;
|
||||||
changedCost.put(manaCost, new GenericManaCost(gen.getOptions().get(0).getGeneric() + -reduceCount));
|
changedCost.put(manaCost, new GenericManaCost(gen.getOptions().getAtIndex(0).getGeneric() + -reduceCount));
|
||||||
reduceCount = 0;
|
reduceCount = 0;
|
||||||
added = true;
|
added = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -708,9 +708,9 @@ public final class CardUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int overflowResult(long value) {
|
private static int overflowResult(long value) {
|
||||||
if (value > Integer.MAX_VALUE) {
|
if (value >= Integer.MAX_VALUE) {
|
||||||
return Integer.MAX_VALUE;
|
return Integer.MAX_VALUE;
|
||||||
} else if (value < Integer.MIN_VALUE) {
|
} else if (value <= Integer.MIN_VALUE) {
|
||||||
return Integer.MIN_VALUE;
|
return Integer.MIN_VALUE;
|
||||||
} else {
|
} else {
|
||||||
return (int) value;
|
return (int) value;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package mage;
|
||||||
|
|
||||||
import mage.abilities.SpellAbility;
|
import mage.abilities.SpellAbility;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
import mage.abilities.costs.mana.ManaCostImpl;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.constants.ColoredManaSymbol;
|
import mage.constants.ColoredManaSymbol;
|
||||||
import mage.constants.ManaType;
|
import mage.constants.ManaType;
|
||||||
|
|
@ -12,6 +13,9 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -767,11 +771,11 @@ public class ManaTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mana.needed is used by the AI to know how much mana it needs in order to be able to play a card.
|
* Mana.needed is used by the AI to know how much mana it needs in order to be able to play a card.
|
||||||
|
*
|
||||||
|
* TODO: How should generic and any be handled?
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void should() {
|
public void manaNeededWorks() {
|
||||||
// TODO: How does it handle generic and any.
|
|
||||||
// How *should* it handle them?
|
|
||||||
testManaNeeded(
|
testManaNeeded(
|
||||||
new Mana(ManaType.COLORLESS, 1), // Available
|
new Mana(ManaType.COLORLESS, 1), // Available
|
||||||
new Mana(ManaType.COLORLESS, 2), // Cost
|
new Mana(ManaType.COLORLESS, 2), // Cost
|
||||||
|
|
@ -794,6 +798,99 @@ public class ManaTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that {@link Mana#getMoreValuableMana(Mana, Mana)} works as intended.
|
||||||
|
* All calls to getMoreValuableMana are run twice, with the second time having the inputs flipped to make sure the same result is given.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void moreValuableManaTest() {
|
||||||
|
final Mana anyMana = Mana.AnyMana(1);
|
||||||
|
final Mana genericMana = Mana.GenericMana(1);
|
||||||
|
final Mana colorlessMana = Mana.ColorlessMana(1);
|
||||||
|
|
||||||
|
final Mana whiteMana = Mana.WhiteMana(1);
|
||||||
|
final Mana blueMana = Mana.BlueMana(1);
|
||||||
|
final Mana blackMana = Mana.BlackMana(1);
|
||||||
|
final Mana redMana = Mana.RedMana(1);
|
||||||
|
final Mana greenMana = Mana.GreenMana(1);
|
||||||
|
|
||||||
|
final List<Mana> coloredManas = Arrays.asList(whiteMana, blueMana, blackMana, redMana, greenMana);
|
||||||
|
|
||||||
|
// 1. A color of WUBURG is not more valuable than any other
|
||||||
|
for (Mana coloredMana1 : coloredManas) {
|
||||||
|
for (Mana coloredMana2 : coloredManas) {
|
||||||
|
assertNull(coloredMana1 + " and " + coloredMana2 + " should not be comparable.", Mana.getMoreValuableMana(coloredMana1, coloredMana2));
|
||||||
|
assertNull(coloredMana1 + " and " + coloredMana2 + " should not be comparable.", Mana.getMoreValuableMana(coloredMana2, coloredMana1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Generic is less valuable than any other type of mana
|
||||||
|
final List<Mana> nonGenericManas = Arrays.asList(whiteMana, blueMana, blackMana, redMana, greenMana, colorlessMana);
|
||||||
|
for (Mana coloredMana : nonGenericManas) {
|
||||||
|
assertEquals(coloredMana, Mana.getMoreValuableMana(coloredMana, genericMana));
|
||||||
|
assertEquals(coloredMana, Mana.getMoreValuableMana(genericMana, coloredMana));
|
||||||
|
}
|
||||||
|
assertEquals(anyMana, Mana.getMoreValuableMana(genericMana, anyMana));
|
||||||
|
assertEquals(anyMana, Mana.getMoreValuableMana(anyMana, genericMana));
|
||||||
|
|
||||||
|
// 3. ANY mana is more valuable than generic or a specific color
|
||||||
|
for (Mana coloredMana : coloredManas) {
|
||||||
|
assertEquals(anyMana, Mana.getMoreValuableMana(coloredMana, anyMana));
|
||||||
|
assertEquals(anyMana, Mana.getMoreValuableMana(anyMana, coloredMana));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Colorless mana is not comparable with colored mana or ANY mana
|
||||||
|
for (Mana coloredMana : coloredManas) {
|
||||||
|
assertNull(Mana.getMoreValuableMana(colorlessMana, coloredMana));
|
||||||
|
assertNull(Mana.getMoreValuableMana(coloredMana, colorlessMana));
|
||||||
|
}
|
||||||
|
assertNull(Mana.getMoreValuableMana(anyMana, colorlessMana));
|
||||||
|
assertNull(Mana.getMoreValuableMana(colorlessMana, anyMana));
|
||||||
|
|
||||||
|
// 5. Mana is more valuable if it has more of any type of mana but not less of any type (other than generic)
|
||||||
|
final List<Mana> allManas = Arrays.asList(whiteMana, blueMana, blackMana, redMana, greenMana, colorlessMana, genericMana, anyMana);
|
||||||
|
for (Mana specificMana : nonGenericManas) {
|
||||||
|
for (Mana toAddMana : allManas) {
|
||||||
|
Mana manaToCompare = specificMana.copy();
|
||||||
|
manaToCompare.add(toAddMana);
|
||||||
|
manaToCompare.add(toAddMana);
|
||||||
|
|
||||||
|
assertEquals(manaToCompare, Mana.getMoreValuableMana(specificMana, manaToCompare));
|
||||||
|
assertEquals(manaToCompare, Mana.getMoreValuableMana(manaToCompare, specificMana));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Greater amount of mana but no less of any kind other than generic
|
||||||
|
final List<Mana> nonAnyManas = Arrays.asList(whiteMana, blueMana, blackMana, redMana, greenMana, colorlessMana, genericMana);
|
||||||
|
Mana manaBase = new ManaCostsImpl<>("{1}{W}{U}{B}{R}{G}{C}").getMana();
|
||||||
|
Mana manaToCompare = manaBase.copy();
|
||||||
|
|
||||||
|
// To avoid the copying that goes with it, manaToCompare is edited in place and always
|
||||||
|
// reset back to its base state at the end of each outer loop.
|
||||||
|
for (Mana manaToAddTwice : nonAnyManas) {
|
||||||
|
manaToCompare.add(manaToAddTwice);
|
||||||
|
manaToCompare.add(manaToAddTwice);
|
||||||
|
for (Mana manaToSubtract : nonAnyManas) {
|
||||||
|
manaToCompare.subtract(manaToSubtract);
|
||||||
|
|
||||||
|
if (manaToSubtract == genericMana || manaToSubtract == manaToAddTwice) {
|
||||||
|
assertEquals(manaToCompare, Mana.getMoreValuableMana(manaBase, manaToCompare));
|
||||||
|
assertEquals(manaToCompare, Mana.getMoreValuableMana(manaToCompare, manaBase));
|
||||||
|
} else if (manaToAddTwice == genericMana ){
|
||||||
|
assertEquals(manaBase, Mana.getMoreValuableMana(manaBase, manaToCompare));
|
||||||
|
assertEquals(manaBase, Mana.getMoreValuableMana(manaToCompare, manaBase));
|
||||||
|
} else {
|
||||||
|
assertNull(Mana.getMoreValuableMana(manaBase, manaToCompare));
|
||||||
|
assertNull(Mana.getMoreValuableMana(manaToCompare, manaBase));
|
||||||
|
}
|
||||||
|
|
||||||
|
manaToCompare.add(manaToSubtract);
|
||||||
|
}
|
||||||
|
manaToCompare.subtract(manaToAddTwice);
|
||||||
|
manaToCompare.subtract(manaToAddTwice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the mana needed calculations produces the expected needed mana amount.
|
* Checks if the mana needed calculations produces the expected needed mana amount.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue