mirror of
https://github.com/correl/mage.git
synced 2025-01-11 11:05:23 +00:00
Merge changes.
This commit is contained in:
commit
70a8ede4d5
3 changed files with 996 additions and 804 deletions
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,86 @@
|
|||
package org.mage.test.utils;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.util.ManaUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public class ManaUtilTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
testManaToPayVsLand("{R}", "Blood Crypt", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{1}{R}", "Blood Crypt", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{R}{B}", "Blood Crypt", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{2}{R}{B}", "Blood Crypt", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{R}{R}{B}{B}", "Blood Crypt", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{R}{G}{W}{W}{U}", "Blood Crypt", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{R}{R}{G}{W}{W}{U}", "Blood Crypt", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{R}{R}", "Blood Crypt", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{G}{W}", "Blood Crypt", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{1}{G}{W}", "Blood Crypt", 2, 1); // should use any but auto choose it
|
||||
testManaToPayVsLand("{2}{G}{W}{U}", "Blood Crypt", 2, 1); // should use any but auto choose it
|
||||
testManaToPayVsLand("{3}", "Blood Crypt", 2, 1); // should use any but auto choose it
|
||||
|
||||
testManaToPayVsLand("{R}{R}{G}{W}{W}{U}", "Watery Grave", 2, 1); // should use {U}
|
||||
testManaToPayVsLand("{R}{R}{G}{W}{W}", "Steam Vents", 2, 1); // should use {R}
|
||||
testManaToPayVsLand("{R}{R}{G}{B}{U}", "Temple Garden", 2, 1); // should use {G}
|
||||
testManaToPayVsLand("{W}{W}{G}{B}{U}", "Sacred Foundry", 2, 1); // should use {W}
|
||||
testManaToPayVsLand("{W}{W}{R}{B}{U}", "Overgrown Tomb", 2, 1); // should use {B}
|
||||
|
||||
testManaToPayVsLand("{1}{R}", "Cavern of Souls", 2, 2); // can't auto choose to pay
|
||||
testManaToPayVsLand("{2}", "Cavern of Souls", 2, 2); // can't auto choose to pay
|
||||
}
|
||||
|
||||
/**
|
||||
* Common way to test ManaUtil.tryToAutoPay
|
||||
*
|
||||
* We get all mana abilities, then try to auto pay and compare to expected1 and expected2 params.
|
||||
*
|
||||
* @param manaToPay Mana that should be paid using land.
|
||||
* @param landName Land to use as mana producer.
|
||||
* @param expected1 The amount of mana abilities the land should have.
|
||||
* @param expected2 The amount of mana abilities that ManaUtil.tryToAutoPay should be returned after optimization.
|
||||
*/
|
||||
private void testManaToPayVsLand(String manaToPay, String landName, int expected1, int expected2) {
|
||||
ManaCost unpaid = new ManaCostsImpl(manaToPay);
|
||||
Card card = CardRepository.instance.findCard(landName).getCard();
|
||||
Assert.assertNotNull(card);
|
||||
|
||||
HashMap<UUID, ManaAbility> useableAbilities = getManaAbilities(card);
|
||||
Assert.assertEquals(expected1, useableAbilities.size());
|
||||
|
||||
useableAbilities = ManaUtil.tryToAutoPay(unpaid, (LinkedHashMap)useableAbilities);
|
||||
Assert.assertEquals(expected2, useableAbilities.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts mana abilities from the card.
|
||||
*
|
||||
* @param card Card to extract mana abilities from.
|
||||
* @return
|
||||
*/
|
||||
private HashMap<UUID, ManaAbility> getManaAbilities(Card card) {
|
||||
HashMap<UUID, ManaAbility> useableAbilities = new LinkedHashMap<UUID, ManaAbility>();
|
||||
for (Ability ability: card.getAbilities()) {
|
||||
if (ability instanceof ManaAbility) {
|
||||
ability.newId(); // we need to assign id manually as we are not in game
|
||||
useableAbilities.put(ability.getId(), (ManaAbility)ability);
|
||||
}
|
||||
}
|
||||
return useableAbilities;
|
||||
}
|
||||
}
|
104
Mage/src/mage/util/ManaUtil.java
Normal file
104
Mage/src/mage/util/ManaUtil.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
package mage.util;
|
||||
|
||||
import mage.Mana;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.mana.*;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author noxx
|
||||
*/
|
||||
public class ManaUtil {
|
||||
|
||||
private ManaUtil() {}
|
||||
|
||||
/**
|
||||
* In case the choice of mana to be produced is obvious, let's discard all other abilities.
|
||||
*
|
||||
* Example:
|
||||
* Pay {W}{R}
|
||||
*
|
||||
* Land produces {W} or {G}.
|
||||
*
|
||||
* No need to ask what player wants to choose.
|
||||
* {W} mana ability should be left only.
|
||||
*
|
||||
* But we CAN do auto choice only in case we have basic mana abilities.
|
||||
* Example:
|
||||
* we should pay {1} and we have Cavern of Souls that can produce {1} or any mana of creature type choice.
|
||||
* We can't simply auto choose {1} as the second mana ability also makes spell uncounterable.
|
||||
*
|
||||
* In case we can't auto choose we'll simply return the useableAbilities map back to caller without any modification.
|
||||
*
|
||||
* @param unpaid Mana we need to pay. Can be null (it is for X costs now).
|
||||
* @param useableAbilities List of mana abilities permanent may produce
|
||||
* @return List of mana abilities permanent may produce and are reasonable for unpaid mana
|
||||
*/
|
||||
public static LinkedHashMap<UUID, ManaAbility> tryToAutoPay(ManaCost unpaid, LinkedHashMap<UUID, ManaAbility> useableAbilities) {
|
||||
if (unpaid != null) {
|
||||
Mana mana = unpaid.getMana();
|
||||
// first check if we have only basic mana abilities
|
||||
for (ManaAbility ability : useableAbilities.values()) {
|
||||
if (!(ability instanceof BasicManaAbility)) {
|
||||
// return map as-is without any modification
|
||||
return useableAbilities;
|
||||
}
|
||||
}
|
||||
int countColorfull = 0;
|
||||
int countColorless = 0;
|
||||
ManaAbility chosenManaAbility = null;
|
||||
for (ManaAbility ability : useableAbilities.values()) {
|
||||
if (ability instanceof RedManaAbility && mana.contains(Mana.RedMana)) {
|
||||
chosenManaAbility = ability;
|
||||
countColorfull++;
|
||||
}
|
||||
if (ability instanceof BlackManaAbility && mana.contains(Mana.BlackMana)) {
|
||||
chosenManaAbility = ability;
|
||||
countColorfull++;
|
||||
}
|
||||
if (ability instanceof BlueManaAbility && mana.contains(Mana.BlueMana)) {
|
||||
chosenManaAbility = ability;
|
||||
countColorfull++;
|
||||
}
|
||||
if (ability instanceof WhiteManaAbility && mana.contains(Mana.WhiteMana)) {
|
||||
chosenManaAbility = ability;
|
||||
countColorfull++;
|
||||
}
|
||||
if (ability instanceof GreenManaAbility && mana.contains(Mana.GreenMana)) {
|
||||
chosenManaAbility = ability;
|
||||
countColorfull++;
|
||||
}
|
||||
}
|
||||
|
||||
if (countColorfull == 0) { // seems there is no colorful mana we can use
|
||||
// try to pay {1}
|
||||
if (mana.getColorless() > 0) {
|
||||
// use first
|
||||
return replace(useableAbilities, useableAbilities.values().iterator().next());
|
||||
}
|
||||
|
||||
// return map as-is without any modification
|
||||
return useableAbilities;
|
||||
}
|
||||
|
||||
if (countColorfull > 1) { // we can't auto choose as there are variant of mana payment
|
||||
// return map as-is without any modification
|
||||
return useableAbilities;
|
||||
}
|
||||
|
||||
return replace(useableAbilities, chosenManaAbility);
|
||||
}
|
||||
|
||||
return useableAbilities;
|
||||
}
|
||||
|
||||
private static LinkedHashMap<UUID, ManaAbility> replace(LinkedHashMap<UUID, ManaAbility> useableAbilities, ManaAbility chosenManaAbility) {
|
||||
// modify the map with the chosen mana ability
|
||||
useableAbilities.clear();
|
||||
useableAbilities.put(chosenManaAbility.getId(), chosenManaAbility);
|
||||
|
||||
return useableAbilities;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue