mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
tests: added tests for auto-lands suggestion in deck editor and tourney (related to #13127)
This commit is contained in:
parent
40e2cf7cda
commit
2955535927
4 changed files with 180 additions and 21 deletions
|
|
@ -87,7 +87,7 @@ public class AddLandDialog extends MageDialog {
|
|||
landSetNames.add(expansionInfo.getName());
|
||||
}
|
||||
if (landSetNames.isEmpty()) {
|
||||
throw new IllegalArgumentException("No set with basic land was found");
|
||||
throw new IllegalArgumentException("No set with basic land was found (possible memory problems, need client restart)");
|
||||
}
|
||||
if (landSetNames.size() > 1) {
|
||||
landSetNames.add("<Random lands>");
|
||||
|
|
@ -477,6 +477,7 @@ public class AddLandDialog extends MageDialog {
|
|||
}//GEN-LAST:event_btnSetFastSearchActionPerformed
|
||||
|
||||
private void autoAddLands() {
|
||||
// suggest lands amount for deck without lands
|
||||
int deckSize = ((Number) spnDeckSize.getValue()).intValue();
|
||||
int[] lands = DeckBuildUtils.landCountSuggestion(deckSize, deck.getMaindeckCards());
|
||||
spnPlains.setValue(lands[0]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,166 @@
|
|||
package org.mage.test.serverside.deck;
|
||||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckCardInfo;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.game.GameException;
|
||||
import mage.util.DeckBuildUtils;
|
||||
import mage.util.TournamentUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.MageTestPlayerBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Testing lands suggestion and adding. It used in:
|
||||
* - client side: for auto-lands suggest button
|
||||
* - server side: for AI and invalid deck's timeout
|
||||
*
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class DeckAutoLandsTest extends MageTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_OneColor() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Grizzly Bears", "129", "S99", 40)
|
||||
));
|
||||
assertSuggestedLands("one color", deck, 60, 0, 0, 0, 0, 20);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_TwoColors() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Arbalest Engineers", "206", "BRO", 40)
|
||||
));
|
||||
assertSuggestedLands("two colors", deck, 60, 0, 0, 0, 10, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_ThreeColors() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Adun Oakenshield", "216", "LEG", 40)
|
||||
));
|
||||
assertSuggestedLands("tree colors", deck, 60, 0, 0, 7, 7, 6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_FiveColors() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Atogatog", "286", "ODY", 40)
|
||||
));
|
||||
assertSuggestedLands("five colors", deck, 60, 4, 4, 4, 4, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_NoColors() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Abstruse Archaic", "712", "CMM", 40)
|
||||
));
|
||||
assertSuggestedLands("no colors", deck, 60, 4, 4, 4, 4, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_LandsSuggest_NoNeedLands() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Grizzly Bears", "129", "S99", 40)
|
||||
));
|
||||
assertSuggestedLands("no need lands - 39", deck, 39, 0, 0, 0, 0, 0);
|
||||
assertSuggestedLands("no need lands - 40", deck, 40, 0, 0, 0, 0, 0);
|
||||
assertSuggestedLands("no need lands - 41", deck, 41, 0, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
private Deck prepareDeck(List<DeckCardInfo> cards) {
|
||||
DeckCardLists source = new DeckCardLists();
|
||||
source.getCards().addAll(cards);
|
||||
Deck deck = null;
|
||||
try {
|
||||
deck = Deck.load(source, true);
|
||||
} catch (GameException e) {
|
||||
Assert.fail("Can't prepare deck: " + cards);
|
||||
}
|
||||
return deck;
|
||||
}
|
||||
|
||||
private void assertSuggestedLands(
|
||||
String info,
|
||||
Deck deck,
|
||||
int needTotal,
|
||||
int needPlains,
|
||||
int needIslands,
|
||||
int needSwamps,
|
||||
int needMountains,
|
||||
int needForests) {
|
||||
int[] lands = DeckBuildUtils.landCountSuggestion(needTotal, deck.getMaindeckCards());
|
||||
List<Integer> current = new ArrayList<>(Arrays.asList(lands[0], lands[1], lands[2], lands[3], lands[4]));
|
||||
List<Integer> need = new ArrayList<>(Arrays.asList(needPlains, needIslands, needSwamps, needMountains, needForests));
|
||||
Assert.assertTrue(info + " - wrong deck size", deck.getMaindeckCards().size() + current.stream().mapToInt(x -> x).sum() >= needTotal);
|
||||
Assert.assertEquals(info + " - wrong lands count (WUBRG)", need, current);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PossibleSets_OneCompatibleSet() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Grizzly Bears", "129", "S99", 1)
|
||||
));
|
||||
assertPossibleSets("one compatible set", deck, Arrays.asList("S99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PossibleSets_MakeSureNoSnowLands() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Grizzly Bears", "129", "S99", 1),
|
||||
new DeckCardInfo("Abominable Treefolk", "194", "MH1", 1) // MH1 with snow lands
|
||||
));
|
||||
assertPossibleSets("no snow lands", deck, Arrays.asList("S99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PossibleSets_MultipleCompatibleSets() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Grizzly Bears", "129", "S99", 1),
|
||||
new DeckCardInfo("Akki Raider", "92", "BOK", 1), // BOK without lands, but with boosters
|
||||
new DeckCardInfo("Grizzly Bears", "169", "POR", 1),
|
||||
new DeckCardInfo("Aggravated Assault", "25", "MP2", 1) // MP2 without lands and boosters
|
||||
));
|
||||
assertPossibleSets("multiple compatible sets", deck, Arrays.asList("POR", "S99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PossibleSets_CompatibleBlocks() {
|
||||
// BOK from Kamigawa block, so it must look at:
|
||||
// * CHK - Champions of Kamigawa - has lands
|
||||
// * SOK - Saviors of Kamigawa - no lands
|
||||
// * BOK - Betrayers of Kamigawa - no lands
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Akki Raider", "92", "BOK", 1), // BOK without lands, but with boosters
|
||||
new DeckCardInfo("Aggravated Assault", "25", "MP2", 1) // MP2 without lands and boosters
|
||||
));
|
||||
assertPossibleSets("compatible block", deck, Arrays.asList("CHK"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PossibleSets_NoCompatibleSetsOrBlocks() {
|
||||
Deck deck = prepareDeck(Arrays.asList(
|
||||
new DeckCardInfo("Amulet of Kroog", "36", "ATQ", 1) // ATQ without lands
|
||||
));
|
||||
// must find 2 random sets
|
||||
List<String> possibleSets1 = TournamentUtil.getLandSetCodeForDeckSets(deck.getExpansionSetCodes()).stream().sorted().collect(Collectors.toList());
|
||||
List<String> possibleSets2 = TournamentUtil.getLandSetCodeForDeckSets(deck.getExpansionSetCodes()).stream().sorted().collect(Collectors.toList());
|
||||
Assert.assertEquals("must find 1 random set, try 1", 1, possibleSets1.size());
|
||||
Assert.assertEquals("must find 1 random set, try 2", 1, possibleSets2.size());
|
||||
Assert.assertNotEquals("must find random sets, try 3", possibleSets1.get(0), possibleSets2.get(0));
|
||||
}
|
||||
|
||||
private void assertPossibleSets(
|
||||
String info,
|
||||
Deck deck,
|
||||
List<String> needSets) {
|
||||
List<String> possibleSets = TournamentUtil.getLandSetCodeForDeckSets(deck.getExpansionSetCodes()).stream().sorted().collect(Collectors.toList());
|
||||
Assert.assertEquals(info + " - wrong possible sets", needSets, possibleSets);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,12 +6,12 @@ import java.util.Set;
|
|||
|
||||
public final class DeckBuildUtils {
|
||||
|
||||
/**
|
||||
* Returns the number of basic lands suggested to complete a deck
|
||||
* as an array of five ints: plains, islands, swamps, mountains, forests
|
||||
* Total number of lands always sufficient to reach deckSize
|
||||
*/
|
||||
public static int[] landCountSuggestion(int deckSize, Set<Card> deckList) {
|
||||
/*
|
||||
Returns the number of basic lands suggested to complete a deck
|
||||
as an array of five ints: plains, islands, swamps, mountains, forests
|
||||
Total number of lands always sufficient to reach deckSize
|
||||
*/
|
||||
int plains = 0, islands = 0, swamps = 0, mountains = 0, forests = 0;
|
||||
int landsNeeded = deckSize - deckList.size();
|
||||
if (landsNeeded > 0) {
|
||||
|
|
@ -51,9 +51,4 @@ public final class DeckBuildUtils {
|
|||
}
|
||||
return new int[] {plains, islands, swamps, mountains, forests};
|
||||
}
|
||||
|
||||
// Hide constructor - not to be instantiated
|
||||
private DeckBuildUtils() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,12 @@ public final class TournamentUtil {
|
|||
/**
|
||||
* Tries to calculate the most appropriate sets to add basic lands for cards of a deck
|
||||
*
|
||||
* @param setCodesDeck
|
||||
* @return setCode for lands
|
||||
* @param setCodesDeck all sets in current deck
|
||||
*/
|
||||
|
||||
public static Set<String> getLandSetCodeForDeckSets(Collection<String> setCodesDeck) {
|
||||
|
||||
Set<String> landSetCodes = new HashSet<>();
|
||||
// decide from which sets basic lands are taken from
|
||||
|
||||
// from deck's sets
|
||||
for (String setCode : setCodesDeck) {
|
||||
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
|
||||
if (expansionInfo.hasBasicLands() && !CardRepository.haveSnowLands(setCode)) {
|
||||
|
|
@ -30,7 +28,7 @@ public final class TournamentUtil {
|
|||
}
|
||||
}
|
||||
|
||||
// if sets have no basic land, take land from block
|
||||
// from deck's blocks
|
||||
if (landSetCodes.isEmpty()) {
|
||||
for (String setCode : setCodesDeck) {
|
||||
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode);
|
||||
|
|
@ -42,10 +40,9 @@ public final class TournamentUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
// if still no set with lands found, take one by random
|
||||
|
||||
// from random
|
||||
if (landSetCodes.isEmpty()) {
|
||||
// if sets have no basic lands and also it has no parent or parent has no lands get last set with lands
|
||||
// select a set with basic lands by random
|
||||
List<ExpansionInfo> basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate()
|
||||
.stream()
|
||||
.filter(exp -> !CardRepository.haveSnowLands(exp.getCode()))
|
||||
|
|
@ -56,7 +53,7 @@ public final class TournamentUtil {
|
|||
}
|
||||
|
||||
if (landSetCodes.isEmpty()) {
|
||||
throw new IllegalArgumentException("No set with basic land was found");
|
||||
throw new IllegalArgumentException("No set with basic land was found (possible memory problems, need server restart)");
|
||||
}
|
||||
return landSetCodes;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue