From dd7c1939d3b1fd649f3cf841cc1cebb23291a36a Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Wed, 23 Dec 2020 10:26:49 +0400 Subject: [PATCH] * Game: fixed that Snow-Covered lands can be added to auto-generated or submitted/timeout decks (#7222); --- .../client/deck/generator/DeckGenerator.java | 12 ++--- .../mage/client/dialog/AddLandDialog.java | 13 +++-- .../java/mage/verify/VerifyCardDataTest.java | 8 +-- .../mage/cards/repository/CardCriteria.java | 24 +++++++++ .../mage/cards/repository/CardRepository.java | 16 +++--- .../main/java/mage/util/TournamentUtil.java | 49 +++++++++---------- 6 files changed, 71 insertions(+), 51 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java index ab7e7b0774..374ba29c51 100644 --- a/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java +++ b/Mage.Client/src/main/java/mage/client/deck/generator/DeckGenerator.java @@ -1,12 +1,5 @@ package mage.client.deck.generator; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - import mage.cards.Card; import mage.cards.decks.Deck; import mage.cards.repository.CardCriteria; @@ -21,6 +14,8 @@ import mage.constants.Rarity; import mage.util.RandomUtil; import mage.util.TournamentUtil; +import java.util.*; + /** * Generates random card pool and builds a deck. * @@ -289,6 +284,7 @@ public final class DeckGenerator { if (!landSets.isEmpty()) { criteria.setCodes(landSets.toArray(new String[landSets.size()])); } + criteria.ignoreSetsWithSnowLands(); Map> basicLandMap = new HashMap<>(); @@ -297,7 +293,7 @@ public final class DeckGenerator { criteria.rarities(Rarity.LAND).name(landName); List cards = CardRepository.instance.findCards(criteria); if (cards.isEmpty()) { // Workaround to get basic lands if lands are not available for the given sets - criteria.setCodes("ORI"); + criteria.setCodes("M15"); cards = CardRepository.instance.findCards(criteria); } basicLandMap.put(landName, cards); diff --git a/Mage.Client/src/main/java/mage/client/dialog/AddLandDialog.java b/Mage.Client/src/main/java/mage/client/dialog/AddLandDialog.java index b2a742e4bf..c75ca0559d 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/AddLandDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/AddLandDialog.java @@ -37,10 +37,6 @@ public class AddLandDialog extends MageDialog { this.setModal(true); } - private boolean setHaveSnowLands(ExpansionInfo exp) { - return CardRepository.instance.haveSnowLands(exp.getCode()); - } - public void showDialog(Deck deck, DeckEditorMode mode) { this.deck = deck; SortedSet landSetNames = new TreeSet<>(); @@ -49,7 +45,7 @@ public class AddLandDialog extends MageDialog { // decide from which sets basic lands are taken from for (String setCode : deck.getExpansionSetCodes()) { ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode); - if (expansionInfo != null && expansionInfo.hasBasicLands() && !setHaveSnowLands(expansionInfo)) { + if (expansionInfo != null && expansionInfo.hasBasicLands() && !CardRepository.haveSnowLands(expansionInfo.getCode())) { defaultSetName = expansionInfo.getName(); break; } @@ -62,7 +58,7 @@ public class AddLandDialog extends MageDialog { if (expansionInfo != null) { List blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName()); for (ExpansionInfo blockSet : blockSets) { - if (blockSet.hasBasicLands() && !setHaveSnowLands(expansionInfo)) { + if (blockSet.hasBasicLands() && !CardRepository.haveSnowLands(expansionInfo.getCode())) { defaultSetName = expansionInfo.getName(); break; } @@ -71,11 +67,12 @@ public class AddLandDialog extends MageDialog { } } } + // if still no set with lands found, add list of all available List basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate(); for (ExpansionInfo expansionInfo : basicLandSets) { // snow lands only in free mode - if (mode != DeckEditorMode.FREE_BUILDING && setHaveSnowLands(expansionInfo)) { + if (mode != DeckEditorMode.FREE_BUILDING && CardRepository.haveSnowLands(expansionInfo.getCode())) { continue; } landSetNames.add(expansionInfo.getName()); @@ -148,6 +145,8 @@ public class AddLandDialog extends MageDialog { throw new IllegalArgumentException("Code of Set " + landSetName + " not found"); } criteria.setCodes(expansionInfo.getCode()); + } else { + criteria.ignoreSetsWithSnowLands(); } criteria.rarities(Rarity.LAND).name(landName); List cards = CardRepository.instance.findCards(criteria); diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index e0e1f50794..59e3cc7b5b 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -820,11 +820,11 @@ public class VerifyCardDataTest { // CHECK: wrong basic lands settings (it's for lands search, not booster construct) for (ExpansionSet set : sets) { Boolean needLand = set.hasBasicLands(); - Boolean foundedLand = false; + Boolean foundLand = false; Map foundLandsList = new HashMap<>(); for (ExpansionSet.SetCardInfo card : set.getSetCardInfo()) { if (isBasicLandName(card.getName())) { - foundedLand = true; + foundLand = true; int count = foundLandsList.getOrDefault(card.getName(), 0); foundLandsList.put(card.getName(), count + 1); } @@ -834,11 +834,11 @@ public class VerifyCardDataTest { .map(p -> (p.getKey() + " - " + p.getValue().toString())) .sorted().collect(Collectors.joining(", ")); - if (needLand && !foundedLand) { + if (needLand && !foundLand) { errorsList.add("error, found set with wrong hasBasicLands - it's true, but haven't land cards: " + set.getCode() + " in " + set.getClass().getName()); } - if (!needLand && foundedLand) { + if (!needLand && foundLand) { errorsList.add("error, found set with wrong hasBasicLands - it's false, but have land cards: " + set.getCode() + " in " + set.getClass().getName() + ", lands: " + landNames); } diff --git a/Mage/src/main/java/mage/cards/repository/CardCriteria.java b/Mage/src/main/java/mage/cards/repository/CardCriteria.java index 7497e76aec..cb8ec259fd 100644 --- a/Mage/src/main/java/mage/cards/repository/CardCriteria.java +++ b/Mage/src/main/java/mage/cards/repository/CardCriteria.java @@ -20,6 +20,7 @@ public class CardCriteria { private String nameExact; private String rules; private final List setCodes; + private final List ignoreSetCodes; // sets to ignore, use with little amount of sets (example: ignore sets with snow lands) private final List types; private final List notTypes; private final List supertypes; @@ -42,6 +43,7 @@ public class CardCriteria { public CardCriteria() { this.setCodes = new ArrayList<>(); + this.ignoreSetCodes = new ArrayList<>(); this.rarities = new ArrayList<>(); this.types = new ArrayList<>(); this.notTypes = new ArrayList<>(); @@ -130,6 +132,16 @@ public class CardCriteria { return this; } + public CardCriteria ignoreSetCodes(String... ignoreSetCodes) { + this.ignoreSetCodes.addAll(Arrays.asList(ignoreSetCodes)); + return this; + } + + public CardCriteria ignoreSetsWithSnowLands() { + this.ignoreSetCodes.addAll(CardRepository.snowLandSetCodes); + return this; + } + public CardCriteria types(CardType... types) { this.types.addAll(Arrays.asList(types)); return this; @@ -216,6 +228,14 @@ public class CardCriteria { clausesCount++; } + for (String ignoreSetCode : ignoreSetCodes) { + where.ne("setCode", ignoreSetCode); + } + if (!ignoreSetCodes.isEmpty()) { + where.or(ignoreSetCodes.size()); + clausesCount++; + } + if (types.size() != 7) { //if all types selected - no selection needed (Tribal and Conspiracy not selectable yet) for (CardType type : types) { where.like("types", new SelectArg('%' + type.name() + '%')); @@ -357,6 +377,10 @@ public class CardCriteria { return setCodes; } + public List getIgnoreSetCodes() { + return ignoreSetCodes; + } + public List getTypes() { return types; } diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index bcd3d6609c..3eb612d934 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -41,6 +41,14 @@ public enum CardRepository { private Set classNames; private final RepositoryEventSource eventSource = new RepositoryEventSource(); + public static final Set snowLandSetCodes = new HashSet<>(Arrays.asList( + "CSP", + "MH1", + "SLD", + "ME2", + "ICE" + )); + CardRepository() { File file = new File("db"); if (!file.exists()) { @@ -188,12 +196,8 @@ public enum CardRepository { return names; } - public Boolean haveSnowLands(String setCode) { - return setCode.equals("CSP") - || setCode.equals("MH1") - || setCode.equals("SLD") - || setCode.equals("ME2") - || setCode.equals("ICE"); + public static Boolean haveSnowLands(String setCode) { + return snowLandSetCodes.contains(setCode); } public Set getNonbasicLandNames() { diff --git a/Mage/src/main/java/mage/util/TournamentUtil.java b/Mage/src/main/java/mage/util/TournamentUtil.java index 7049100391..d47a683aaa 100644 --- a/Mage/src/main/java/mage/util/TournamentUtil.java +++ b/Mage/src/main/java/mage/util/TournamentUtil.java @@ -6,51 +6,43 @@ package mage.util; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - import mage.cards.Card; -import mage.cards.repository.CardCriteria; -import mage.cards.repository.CardInfo; -import mage.cards.repository.CardRepository; -import mage.cards.repository.ExpansionInfo; -import mage.cards.repository.ExpansionRepository; +import mage.cards.repository.*; import mage.constants.Rarity; +import java.util.*; +import java.util.stream.Collectors; + /** - * * @author LevelX2 */ public final class TournamentUtil { - + /** * Tries to calculate the most appropiate sets to add basic lands for cards of a deck - * + * * @param setCodesDeck * @return setCode for lands */ - + public static Set getLandSetCodeForDeckSets(Collection setCodesDeck) { - + Set landSetCodes = new HashSet<>(); // decide from which sets basic lands are taken from - for (String setCode :setCodesDeck) { + for (String setCode : setCodesDeck) { ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode); - if (expansionInfo.hasBasicLands()) { + if (expansionInfo.hasBasicLands() && !CardRepository.haveSnowLands(setCode)) { landSetCodes.add(expansionInfo.getCode()); } } // if sets have no basic land, take land from block if (landSetCodes.isEmpty()) { - for (String setCode :setCodesDeck) { + for (String setCode : setCodesDeck) { ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(setCode); List blockSets = ExpansionRepository.instance.getSetsFromBlock(expansionInfo.getBlockName()); - for (ExpansionInfo blockSet: blockSets) { - if (blockSet.hasBasicLands()) { + for (ExpansionInfo blockSet : blockSets) { + if (blockSet.hasBasicLands() && !CardRepository.haveSnowLands(blockSet.getCode())) { landSetCodes.add(blockSet.getCode()); } } @@ -60,7 +52,10 @@ public final class TournamentUtil { 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 basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate(); + List basicLandSets = ExpansionRepository.instance.getSetsWithBasicLandsByReleaseDate() + .stream() + .filter(exp -> !CardRepository.haveSnowLands(exp.getCode())) + .collect(Collectors.toList()); if (!basicLandSets.isEmpty()) { landSetCodes.add(basicLandSets.get(RandomUtil.nextInt(basicLandSets.size())).getCode()); } @@ -71,11 +66,13 @@ public final class TournamentUtil { } return landSetCodes; } - + public static List getLands(String landName, int number, Set landSets) { CardCriteria criteria = new CardCriteria(); if (!landSets.isEmpty()) { criteria.setCodes(landSets.toArray(new String[landSets.size()])); + } else { + criteria.ignoreSetsWithSnowLands(); } criteria.rarities(Rarity.LAND).name(landName); List lands = CardRepository.instance.findCards(criteria); @@ -84,9 +81,9 @@ public final class TournamentUtil { for (int i = 0; i < number; i++) { Card land = lands.get(RandomUtil.nextInt(lands.size())).getCard(); cards.add(land); - } - } + } + } return cards; } - + }