mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
GUI: deck legality improves:
* Added partly valid status for deck legality panel (if all cards are fine but user must add more cards to complete, see #6854); * Improved legality errors sorting (important errors visible at the top now, e.g. commander's errors);
This commit is contained in:
parent
9dfc6eed69
commit
e95b9f145c
20 changed files with 335 additions and 201 deletions
|
@ -2,6 +2,7 @@ package mage.client.components;
|
|||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.decks.DeckValidatorError;
|
||||
import mage.cards.decks.importer.DeckImporter;
|
||||
import org.unbescape.html.HtmlEscape;
|
||||
import org.unbescape.html.HtmlEscapeLevel;
|
||||
|
@ -10,7 +11,6 @@ import org.unbescape.html.HtmlEscapeType;
|
|||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Elandril
|
||||
|
@ -19,6 +19,7 @@ public class LegalityLabel extends JLabel {
|
|||
|
||||
protected static final Color COLOR_UNKNOWN = new Color(174, 174, 174);
|
||||
protected static final Color COLOR_LEGAL = new Color(117, 152, 110);
|
||||
protected static final Color COLOR_PARTLY_LEGAL = new Color(191, 176, 80);
|
||||
protected static final Color COLOR_NOT_LEGAL = new Color(191, 84, 74);
|
||||
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
|
||||
protected static final Dimension DIM_MINIMUM = new Dimension(75, 25);
|
||||
|
@ -105,11 +106,17 @@ public class LegalityLabel extends JLabel {
|
|||
return HtmlEscape.escapeHtml(string, HtmlEscapeType.HTML4_NAMED_REFERENCES_DEFAULT_TO_HEXA, HtmlEscapeLevel.LEVEL_0_ONLY_MARKUP_SIGNIFICANT_EXCEPT_APOS);
|
||||
}
|
||||
|
||||
protected String formatInvalidTooltip(Map<String, String> invalid) {
|
||||
return invalid.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
protected String formatInvalidTooltip(java.util.List<DeckValidatorError> sortedErrorsList) {
|
||||
return sortedErrorsList.stream()
|
||||
.reduce("<html><body><p>Deck is <span style='color:#BF544A;font-weight:bold;'>INVALID</span></p><u>The following problems have been found:</u><br><table>",
|
||||
(str, entry) -> String.format("%s<tr><td><b>%s</b></td><td>%s</td></tr>", str, escapeHtml(entry.getKey()), escapeHtml(entry.getValue())), String::concat)
|
||||
(str, error) -> String.format("%s<tr><td><b>%s</b></td><td>%s</td></tr>", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat)
|
||||
+ "</table></body></html>";
|
||||
}
|
||||
|
||||
protected String formatPartlyValidTooltip(java.util.List<DeckValidatorError> sortedErrorsList) {
|
||||
return sortedErrorsList.stream()
|
||||
.reduce("<html><body><p>Deck is <span style='color:#b8860b;font-weight:bold;'>PARTLY VALID</span></p><u>The following problems have been found:</u><br><table>",
|
||||
(str, error) -> String.format("%s<tr><td><b>%s</b></td><td>%s</td></tr>", str, escapeHtml(error.getGroup()), escapeHtml(error.getMessage())), String::concat)
|
||||
+ "</table></body></html>";
|
||||
}
|
||||
|
||||
|
@ -139,6 +146,10 @@ public class LegalityLabel extends JLabel {
|
|||
showState(COLOR_LEGAL, tooltip);
|
||||
}
|
||||
|
||||
public void showStatePartlyLegal(String tooltip) {
|
||||
showState(COLOR_PARTLY_LEGAL, tooltip);
|
||||
}
|
||||
|
||||
public void showStateNotLegal(String tooltip) {
|
||||
showState(COLOR_NOT_LEGAL, tooltip);
|
||||
}
|
||||
|
@ -157,8 +168,10 @@ public class LegalityLabel extends JLabel {
|
|||
try {
|
||||
if (validator.validate(deck)) {
|
||||
showStateLegal("<html><body>Deck is <span style='color:green;font-weight:bold;'>VALID</span></body></html>");
|
||||
} else if (validator.isPartlyValid()) {
|
||||
showStatePartlyLegal(formatPartlyValidTooltip(validator.getErrorsListSorted()));
|
||||
} else {
|
||||
showStateNotLegal(formatInvalidTooltip(validator.getInvalid()));
|
||||
showStateNotLegal(formatInvalidTooltip(validator.getErrorsListSorted()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
showStateUnknown(String.format("<html><body><b>Deck could not be validated!</b><br>The following error occurred while validating this deck:<br>%s</body></html>", escapeHtml(e.getMessage())));
|
||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -92,14 +93,14 @@ public class AusHighlander extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
if (deck.getSideboard().size() > 15) {
|
||||
invalid.put("Sideboard", "Must contain at most 15 singleton cards: has " + (deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Sideboard", "Must contain at most 15 singleton cards: has " + (deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -139,12 +140,12 @@ public class AusHighlander extends Constructed {
|
|||
String cn = entry.getKey();
|
||||
if (pointMap.containsKey(cn)) {
|
||||
totalPoints += pointMap.get(cn);
|
||||
invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
}
|
||||
}
|
||||
if (totalPoints > 7) {
|
||||
invalid.put("Total points too high", "Your calculated point total was " + totalPoints);
|
||||
invalid.put("Only you can see this!", "Your opponents will not be able to see this message or what cards are in your deck!");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Total points too high", "Your calculated point total was " + totalPoints);
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Only you can see this!", "Your opponents will not be able to see this message or what cards are in your deck!");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
|
|
|
@ -6,6 +6,7 @@ import mage.abilities.keyword.CompanionAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
|
@ -40,7 +41,7 @@ public class Brawl extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
Card brawler = null;
|
||||
Card companion = null;
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
|
@ -60,32 +61,32 @@ public class Brawl extends Constructed {
|
|||
companion = card2;
|
||||
brawler = card1;
|
||||
} else {
|
||||
invalid.put("Brawl", "Sideboard must contain only the brawler and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Sideboard must contain only the brawler and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Brawl", "Sideboard must contain only the brawler and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Sideboard must contain only the brawler and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (brawler != null) {
|
||||
ManaUtil.collectColorIdentity(colorIdentity, brawler.getColorIdentity());
|
||||
if (bannedCommander.contains(brawler.getName())) {
|
||||
invalid.put("Brawl", "Brawler banned (" + brawler.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Brawler banned (" + brawler.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
if (!((brawler.isCreature() && brawler.isLegendary())
|
||||
|| brawler.isPlaneswalker() || brawler.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||
invalid.put("Brawl", "Invalid Brawler (" + brawler.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Invalid Brawler (" + brawler.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + 1) {
|
||||
invalid.put("Deck", "Must contain " + (getDeckMinSize() + 1) + " cards (companion doesn't count in deck size requirement): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + (getDeckMinSize() + 1) + " cards (companion doesn't count in deck size requirement): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -96,7 +97,7 @@ public class Brawl extends Constructed {
|
|||
|
||||
for (String bannedCard : banned) {
|
||||
if (counts.containsKey(bannedCard)) {
|
||||
invalid.put(bannedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +115,7 @@ public class Brawl extends Constructed {
|
|||
&& !(colorIdentity.isColorless()
|
||||
&& basicsInDeck.size() == 1
|
||||
&& basicsInDeck.contains(card.getName()))) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -123,14 +124,14 @@ public class Brawl extends Constructed {
|
|||
&& !(colorIdentity.isColorless()
|
||||
&& basicsInDeck.size() == 1
|
||||
&& basicsInDeck.contains(card.getName()))) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +139,7 @@ public class Brawl extends Constructed {
|
|||
for (Card card : deck.getSideboard()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ public class Brawl extends Constructed {
|
|||
if (ability instanceof CompanionAbility) {
|
||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -74,15 +75,15 @@ public class CanadianHighlander extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
if (deck.getCards().size() < 100) {
|
||||
invalid.put("Deck", "Must contain 100 or more singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain 100 or more singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!deck.getSideboard().isEmpty()) {
|
||||
invalid.put("Deck", "Sideboard can't contain any cards: has " + (deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Sideboard can't contain any cards: has " + (deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -97,11 +98,11 @@ public class CanadianHighlander extends Constructed {
|
|||
String cn = entry.getKey();
|
||||
if (pointMap.containsKey(cn)) {
|
||||
totalPoints += pointMap.get(cn);
|
||||
invalid.put(entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
addError(DeckValidatorErrorType.OTHER, entry.getKey(), " " + pointMap.get(cn) + " point " + cn);
|
||||
}
|
||||
}
|
||||
if (totalPoints > allowedPoints) {
|
||||
invalid.put("Total points too high", "Your calculated point total was " + totalPoints);
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Total points too high", "Your calculated point total was " + totalPoints);
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
|
|
|
@ -12,6 +12,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
|
@ -97,7 +98,7 @@ public class Commander extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
Set<Card> commanders = new HashSet<>();
|
||||
Card companion = null;
|
||||
|
@ -136,19 +137,19 @@ public class Commander extends Constructed {
|
|||
commanders.add(card1);
|
||||
commanders.add(card2);
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
||||
invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -159,7 +160,7 @@ public class Commander extends Constructed {
|
|||
|
||||
for (String bannedCard : banned) {
|
||||
if (counts.containsKey(bannedCard)) {
|
||||
invalid.put(bannedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -170,18 +171,18 @@ public class Commander extends Constructed {
|
|||
}
|
||||
for (Card commander : commanders) {
|
||||
if (bannedCommander.contains(commander.getName())) {
|
||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
if ((!commander.isCreature() || !commander.isLegendary())
|
||||
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||
invalid.put("Commander", "Commander invalid (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
if (commanders.size() == 2) {
|
||||
if (commander.getAbilities().contains(PartnerAbility.getInstance())) {
|
||||
if (bannedPartner.contains(commander.getName())) {
|
||||
invalid.put("Commander", "Partner banned (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Partner banned (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
|
@ -192,7 +193,7 @@ public class Commander extends Constructed {
|
|||
.map(PartnerWithAbility::getPartnerName)
|
||||
.anyMatch(commanderNames::contains);
|
||||
if (!partnersWith) {
|
||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -207,20 +208,20 @@ public class Commander extends Constructed {
|
|||
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getSideboard()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ public class Commander extends Constructed {
|
|||
for (Card card : deck.getSideboard()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +242,7 @@ public class Commander extends Constructed {
|
|||
if (ability instanceof CompanionAbility) {
|
||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -2,6 +2,7 @@ package mage.deck;
|
|||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
||||
/**
|
||||
* @author fireshoes
|
||||
|
@ -33,10 +34,10 @@ public class Freeform extends DeckValidator {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
// http://magic.wizards.com/en/gameinfo/gameplay/formats/freeform
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
|
|
|
@ -9,6 +9,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
|
@ -53,7 +54,7 @@ public class FreeformCommander extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
Set<Card> commanders = new HashSet<>();
|
||||
Card companion = null;
|
||||
|
@ -92,19 +93,19 @@ public class FreeformCommander extends Constructed {
|
|||
commanders.add(card1);
|
||||
commanders.add(card2);
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
||||
invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -119,7 +120,7 @@ public class FreeformCommander extends Constructed {
|
|||
}
|
||||
for (Card commander : commanders) {
|
||||
if (!commander.isCreature() || !commander.isLegendary()) {
|
||||
invalid.put("Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName());
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "For Freeform Commander, the commander must be a creature or be legendary. Yours was: " + commander.getName());
|
||||
valid = false;
|
||||
}
|
||||
if (commanders.size() == 2) {
|
||||
|
@ -131,7 +132,7 @@ public class FreeformCommander extends Constructed {
|
|||
.map(PartnerWithAbility::getPartnerName)
|
||||
.anyMatch(commanderNames::contains);
|
||||
if (!partnersWith) {
|
||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -146,13 +147,13 @@ public class FreeformCommander extends Constructed {
|
|||
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getSideboard()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ public class FreeformCommander extends Constructed {
|
|||
if (ability instanceof CompanionAbility) {
|
||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorError;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -104,10 +105,10 @@ public class HistoricalType2 extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
|
||||
Map<String, String> leastInvalid = null;
|
||||
List<DeckValidatorError> leastInvalid = null;
|
||||
|
||||
boolean valid = false;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// first, check whether misty and batterskull are in the same deck.
|
||||
Map<String, Integer> counts = new HashMap<>();
|
||||
|
@ -125,7 +126,7 @@ public class HistoricalType2 extends Constructed {
|
|||
for (String[] sets : standards) {
|
||||
|
||||
// clear the invalid list
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// add the sets to the setCodes.
|
||||
setCodes = new ArrayList<>(Arrays.asList(sets));
|
||||
|
@ -139,15 +140,15 @@ public class HistoricalType2 extends Constructed {
|
|||
// if the map holding the invalid cards is empty, set it to a
|
||||
// copy of the current invalid list.
|
||||
if (leastInvalid == null) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
continue;
|
||||
}
|
||||
|
||||
// see how many invalid cards there are. if there are less invalid
|
||||
// cards than the stored invalid list, assign the current invalid
|
||||
// to leastInvalid.
|
||||
if (leastInvalid.size() > this.getInvalid().size()) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +166,7 @@ public class HistoricalType2 extends Constructed {
|
|||
|
||||
// clear the invalid list and set codes.
|
||||
setCodes.clear();
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// increment the start and end dates.
|
||||
start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1);
|
||||
|
@ -183,7 +184,7 @@ public class HistoricalType2 extends Constructed {
|
|||
|
||||
// validate it. If it validates, clear the invalid cards and break.
|
||||
if (super.validate(deck)) {
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
@ -192,17 +193,16 @@ public class HistoricalType2 extends Constructed {
|
|||
// cards than the stored invalid list, assign the current invalid
|
||||
// to leastInvalid.
|
||||
if (leastInvalid == null) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
|
||||
} else if (leastInvalid.size() > this.getInvalid().size()) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
} else if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
}
|
||||
}
|
||||
|
||||
// if no standard environment is valid, set the invalid to the
|
||||
// invalid that had the least errors.
|
||||
if (!valid) {
|
||||
this.invalid = new HashMap<>(leastInvalid);
|
||||
this.errorsList = new ArrayList<>(leastInvalid);
|
||||
}
|
||||
|
||||
// return the validity.
|
||||
|
|
|
@ -3,6 +3,7 @@ package mage.deck;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -30,17 +31,17 @@ public class Momir extends DeckValidator {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
List<String> basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes"));
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!basicLandNames.contains(card.getName())) {
|
||||
invalid.put(card.getName(), "Only basic lands are allowed");
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Only basic lands are allowed");
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import mage.abilities.keyword.PartnerAbility;
|
|||
import mage.abilities.keyword.PartnerWithAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
|
@ -82,10 +83,10 @@ public class Oathbreaker extends Vintage {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != 60) {
|
||||
invalid.put("Deck", "Must contain " + 60 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 60 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ public class Oathbreaker extends Vintage {
|
|||
|
||||
for (String bannedCard : banned) {
|
||||
if (counts.containsKey(bannedCard)) {
|
||||
invalid.put(bannedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ public class Oathbreaker extends Vintage {
|
|||
Set<String> signatureSpells = new HashSet<>();
|
||||
FilterMana allCommandersColor = new FilterMana();
|
||||
if (deck.getSideboard().size() < 2 || deck.getSideboard().size() > 4) {
|
||||
invalid.put("Oathbreaker", "Sideboard must contain only 2 or 4 cards (oathbreaker + signature spell)");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contain only 2 or 4 cards (oathbreaker + signature spell)");
|
||||
valid = false;
|
||||
} else {
|
||||
// collect data
|
||||
|
@ -120,7 +121,7 @@ public class Oathbreaker extends Vintage {
|
|||
// color identity from commanders only, not spell
|
||||
ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity());
|
||||
} else {
|
||||
invalid.put("Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName());
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Only planeswalker can be Oathbreaker, not " + commander.getName());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -128,15 +129,15 @@ public class Oathbreaker extends Vintage {
|
|||
|
||||
// check size (1+1 or 2+2 allows)
|
||||
if (commanderNames.isEmpty() || commanderNames.size() > 2) {
|
||||
invalid.put("Oathbreaker", "Sideboard must contains 1 or 2 oathbreakers, but found: " + commanderNames.size());
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contains 1 or 2 oathbreakers, but found: " + commanderNames.size());
|
||||
valid = false;
|
||||
}
|
||||
if (signatureSpells.isEmpty() || signatureSpells.size() > 2) {
|
||||
invalid.put("Signature Spell", "Sideboard must contains 1 or 2 signature spells, but found: " + signatureSpells.size());
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Signature Spell", "Sideboard must contains 1 or 2 signature spells, but found: " + signatureSpells.size());
|
||||
valid = false;
|
||||
}
|
||||
if (signatureSpells.size() != commanderNames.size()) {
|
||||
invalid.put("Oathbreaker", "Sideboard must contains 1 + 1 or 2 + 2 cards, but found: " + commanderNames.size() + " + " + signatureSpells.size());
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Sideboard must contains 1 + 1 or 2 + 2 cards, but found: " + commanderNames.size() + " + " + signatureSpells.size());
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -153,7 +154,7 @@ public class Oathbreaker extends Vintage {
|
|||
}
|
||||
}
|
||||
if (!partnersWith) {
|
||||
invalid.put("Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +176,7 @@ public class Oathbreaker extends Vintage {
|
|||
}
|
||||
}
|
||||
if (!haveSameColor) {
|
||||
invalid.put("Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Signature Spell", "Can't find oathbreaker with compatible color identity (" + spell.getName() + " - " + spellColor + ")");
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ public class Oathbreaker extends Vintage {
|
|||
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(allCommandersColor, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + card.getColorIdentity() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + card.getColorIdentity() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +198,7 @@ public class Oathbreaker extends Vintage {
|
|||
for (Card card : deck.getSideboard()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.cards.decks.PennyDreadfulLegalityUtil;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.util.ManaUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* @author spjspj
|
||||
|
@ -47,7 +47,7 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
Set<Card> commanders = new HashSet<>();
|
||||
Card companion = null;
|
||||
|
@ -86,19 +86,19 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
commanders.add(card1);
|
||||
commanders.add(card2);
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
||||
invalid.put("Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
|
||||
for (String wantedCard : counts.keySet()) {
|
||||
if (!(pdAllowed.containsKey(wantedCard))) {
|
||||
invalid.put(wantedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", wantedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -124,12 +124,12 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
}
|
||||
for (Card commander : commanders) {
|
||||
if (bannedCommander.contains(commander.getName())) {
|
||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
if ((!commander.isCreature() || !commander.isLegendary())
|
||||
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||
invalid.put("Commander", "Commander invalid (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
if (commanders.size() == 2) {
|
||||
|
@ -141,7 +141,7 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
.map(PartnerWithAbility::getPartnerName)
|
||||
.anyMatch(commanderNames::contains);
|
||||
if (!partnersWith) {
|
||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -156,20 +156,20 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getSideboard()) {
|
||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
for (Card card : deck.getSideboard()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
if (ability instanceof CompanionAbility) {
|
||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
||||
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||
valid = false;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
|||
import mage.cards.Sets;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorError;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -77,10 +78,10 @@ public class SuperType2 extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
|
||||
Map<String, String> leastInvalid = null;
|
||||
List<DeckValidatorError> leastInvalid = null;
|
||||
|
||||
boolean valid = false;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// first, check whether misty and batterskull are in the same deck.
|
||||
Map<String, Integer> counts = new HashMap<>();
|
||||
|
@ -98,7 +99,7 @@ public class SuperType2 extends Constructed {
|
|||
for (String[] sets : standards) {
|
||||
|
||||
// clear the invalid list
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// add the sets to the setCodes.
|
||||
setCodes = new ArrayList<>(Arrays.asList(sets));
|
||||
|
@ -120,15 +121,15 @@ public class SuperType2 extends Constructed {
|
|||
// if the map holding the invalid cards is empty, set it to a
|
||||
// copy of the current invalid list.
|
||||
if (leastInvalid == null) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
continue;
|
||||
}
|
||||
|
||||
// see how many invalid cards there are. if there are less invalid
|
||||
// cards than the stored invalid list, assign the current invalid
|
||||
// to leastInvalid.
|
||||
if (leastInvalid.size() > this.getInvalid().size()) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +147,7 @@ public class SuperType2 extends Constructed {
|
|||
|
||||
// clear the invalid list and set codes.
|
||||
setCodes.clear();
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
// increment the start and end dates.
|
||||
start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1);
|
||||
|
@ -172,7 +173,7 @@ public class SuperType2 extends Constructed {
|
|||
|
||||
// validate it. If it validates, clear the invalid cards and break.
|
||||
if (super.validate(deck)) {
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
@ -181,17 +182,17 @@ public class SuperType2 extends Constructed {
|
|||
// cards than the stored invalid list, assign the current invalid
|
||||
// to leastInvalid.
|
||||
if (leastInvalid == null) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
|
||||
} else if (leastInvalid.size() > this.getInvalid().size()) {
|
||||
leastInvalid = new HashMap<>(this.getInvalid());
|
||||
} else if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||
}
|
||||
}
|
||||
|
||||
// if no standard environment is valid, set the invalid to the
|
||||
// invalid that had the least errors.
|
||||
if (!valid) {
|
||||
this.invalid = new HashMap<>(leastInvalid);
|
||||
this.errorsList = new ArrayList<>(leastInvalid);
|
||||
}
|
||||
|
||||
// return the validity.
|
||||
|
|
|
@ -6,6 +6,7 @@ import mage.cards.Sets;
|
|||
import mage.cards.SplitCard;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
import mage.filter.FilterMana;
|
||||
import mage.game.GameTinyLeadersImpl;
|
||||
|
||||
|
@ -103,10 +104,10 @@ public class TinyLeaders extends Constructed {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,7 @@ public class TinyLeaders extends Constructed {
|
|||
|
||||
for (String bannedCard : banned) {
|
||||
if (counts.containsKey(bannedCard)) {
|
||||
invalid.put(bannedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -135,16 +136,16 @@ public class TinyLeaders extends Constructed {
|
|||
if (commander == null || commander.getManaCost().convertedManaCost() > 3) {
|
||||
if (commander == null) {
|
||||
if (deck.getName() == null) {
|
||||
invalid.put("Leader", "You have to save your deck with the leader card name entered to the DECK NAME field of the DECK EDITOR (top left) so that XMage knows your leader."
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Leader", "You have to save your deck with the leader card name entered to the DECK NAME field of the DECK EDITOR (top left) so that XMage knows your leader."
|
||||
+ "(You can use the \"Sultai\" for a UBG (3/3) default Commander or \"Glass\" for a colorless 3/3 default Commander.)");
|
||||
} else {
|
||||
invalid.put("Leader", "Leader [" + deck.getName() + "] not found. You have to enter the name of the leader card into the DECK NAME field of the DECK EDITOR (top left). Check your spelling "
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Leader", "Leader [" + deck.getName() + "] not found. You have to enter the name of the leader card into the DECK NAME field of the DECK EDITOR (top left). Check your spelling "
|
||||
+ "(use the \"Sultai\" for a UBG (3/3) default Commander or \"Glass\" for a colorless (3/3) default Commander)");
|
||||
|
||||
}
|
||||
}
|
||||
if (commander != null && commander.getManaCost().convertedManaCost() > 3) {
|
||||
invalid.put("Leader", "Commanders converted mana cost is greater than 3");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Leader", "Commanders converted mana cost is greater than 3");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -162,21 +163,21 @@ public class TinyLeaders extends Constructed {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Commander invalide (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalide (" + commander.getName() + ')');
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
invalid.put("Commander", "Sideboard must contain only a maximum of 10 sideboard cards (the Tiny Leader name must be written to the deck name)");
|
||||
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only a maximum of 10 sideboard cards (the Tiny Leader name must be written to the deck name)");
|
||||
valid = false;
|
||||
}
|
||||
for (Card card : deck.getCards()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +185,7 @@ public class TinyLeaders extends Constructed {
|
|||
for (Card card : deck.getSideboard()) {
|
||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||
if (!legalSets(card)) {
|
||||
invalid.put(card.getName(), "Not allowed Set " + card.getExpansionSetCode());
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set " + card.getExpansionSetCode());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -194,22 +195,22 @@ public class TinyLeaders extends Constructed {
|
|||
|
||||
private boolean isCardFormatValid(Card card, Card commander, FilterMana color) {
|
||||
if (!cardHasValideColor(color, card)) {
|
||||
invalid.put(card.getName(), "Invalid color (" + commander.getName() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + commander.getName() + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
//905.5b - Converted mana cost must be 3 or less
|
||||
if (card instanceof SplitCard) {
|
||||
if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) {
|
||||
invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')');
|
||||
return false;
|
||||
}
|
||||
if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) {
|
||||
invalid.put(card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')');
|
||||
return false;
|
||||
}
|
||||
} else if (card.getManaCost().convertedManaCost() > 3) {
|
||||
invalid.put(card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')');
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -2,6 +2,7 @@ package mage.deck;
|
|||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -28,17 +29,17 @@ public class Limited extends DeckValidator {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
//20091005 - 100.2b
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
Map<String, Integer> counts = new HashMap<>();
|
||||
countCards(counts, deck.getCards());
|
||||
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
|
||||
if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) {
|
||||
invalid.put(entry.getKey(), "Too many: " + entry.getValue());
|
||||
addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package mage.server;
|
|||
import mage.MageException;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.cards.decks.DeckValidatorError;
|
||||
import mage.cards.decks.DeckValidatorFactory;
|
||||
import mage.constants.RangeOfInfluence;
|
||||
import mage.constants.TableState;
|
||||
|
@ -32,11 +33,8 @@ import mage.server.util.ThreadExecutor;
|
|||
import mage.view.ChatMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
@ -150,9 +148,10 @@ public class TableController {
|
|||
}
|
||||
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
|
||||
StringBuilder sb = new StringBuilder("You (").append(name).append(") have an invalid deck for the selected ").append(table.getValidator().getName()).append(" Format. \n\n");
|
||||
for (Map.Entry<String, String> entry : table.getValidator().getInvalid().entrySet()) {
|
||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
||||
}
|
||||
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||
errorsList.stream().forEach(error -> {
|
||||
sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n");
|
||||
});
|
||||
sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!");
|
||||
user.showUserMessage("Join Table", sb.toString());
|
||||
if (isOwner(userId)) {
|
||||
|
@ -267,9 +266,10 @@ public class TableController {
|
|||
|
||||
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
|
||||
StringBuilder sb = new StringBuilder("You (").append(name).append(") have an invalid deck for the selected ").append(table.getValidator().getName()).append(" Format. \n\n");
|
||||
for (Map.Entry<String, String> entry : table.getValidator().getInvalid().entrySet()) {
|
||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
||||
}
|
||||
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||
errorsList.stream().forEach(error -> {
|
||||
sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n");
|
||||
});
|
||||
sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!");
|
||||
user.showUserMessage("Join Table", sb.toString());
|
||||
if (isOwner(userId)) {
|
||||
|
@ -425,9 +425,10 @@ public class TableController {
|
|||
return false;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder("Invalid deck for the selected ").append(table.getValidator().getName()).append(" format. \n\n");
|
||||
for (Map.Entry<String, String> entry : table.getValidator().getInvalid().entrySet()) {
|
||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
||||
}
|
||||
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||
errorsList.stream().forEach(error -> {
|
||||
sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n");
|
||||
});
|
||||
sb.append("\n\nAdd enough cards and try again!");
|
||||
_user.get().showUserMessage("Submit deck", sb.toString());
|
||||
return false;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
package org.mage.test.serverside.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.repository.CardInfo;
|
||||
|
@ -14,8 +11,10 @@ import org.junit.Assert;
|
|||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.MageTestBase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class DeckValidatorTest extends MageTestBase {
|
||||
|
@ -65,7 +64,7 @@ public class DeckValidatorTest extends MageTestBase {
|
|||
|
||||
DeckValidator validator = new Standard();
|
||||
boolean validationSuccessful = testDeckValid(validator, deck);
|
||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
||||
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -79,7 +78,7 @@ public class DeckValidatorTest extends MageTestBase {
|
|||
DeckValidator validator = new Standard();
|
||||
testDeckValid(validator, deck, sideboard);
|
||||
Assert.assertEquals("invalid message not correct",
|
||||
"{Sideboard=Must contain no more than 15 cards : has 16 cards, Deck=Must contain at least 60 cards: has only 59 cards}", validator.getInvalid().toString());
|
||||
"Deck=Must contain at least 60 cards: has only 59 cards, Sideboard=Must contain no more than 15 cards : has 16 cards", validator.getErrorsListInfo());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -229,119 +228,119 @@ public class DeckValidatorTest extends MageTestBase {
|
|||
deckList.add(new CardNameAmount("Ancestral Vision", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
boolean validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Ancient Den", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.add(new CardNameAmount("Birthing Pod", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Blazing Shoal", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Bloodbraid Elf", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Chrome Mox", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Cloudpost", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Dark Depths", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Deathrite Shaman", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Dig Through Time", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Dread Return", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Glimpse of Nature", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Great Furnace", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Green Sun's Zenith", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Hypergenesis", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Jace, the Mind Sculptor", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
|
||||
deckList.clear();
|
||||
deckList.add(new CardNameAmount("Mental Misstep", 4));
|
||||
deckList.add(new CardNameAmount("Mountain", 56));
|
||||
validationSuccessful = testDeckValid(validator, deckList);
|
||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
||||
validator.getInvalid().clear();
|
||||
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||
validator.getErrorsList().clear();
|
||||
}
|
||||
|
||||
private boolean testDeckValid(DeckValidator validator, List<CardNameAmount> cards) {
|
||||
|
|
|
@ -58,15 +58,15 @@ public class Constructed extends DeckValidator {
|
|||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
invalid.clear();
|
||||
errorsList.clear();
|
||||
//20091005 - 100.2a
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
//20130713 - 100.4a
|
||||
if (deck.getSideboard().size() > 15) {
|
||||
invalid.put("Sideboard", "Must contain no more than 15 cards : has " + deck.getSideboard().size() + " cards");
|
||||
addError(DeckValidatorErrorType.DECK_SIZE, "Sideboard", "Must contain no more than 15 cards : has " + deck.getSideboard().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class Constructed extends DeckValidator {
|
|||
|
||||
for (String bannedCard : banned) {
|
||||
if (counts.containsKey(bannedCard)) {
|
||||
invalid.put(bannedCard, "Banned");
|
||||
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class Constructed extends DeckValidator {
|
|||
if (counts.containsKey(restrictedCard)) {
|
||||
int count = counts.get(restrictedCard);
|
||||
if (count > 1) {
|
||||
invalid.put(restrictedCard, "Restricted: " + count);
|
||||
addError(DeckValidatorErrorType.OTHER, restrictedCard, "Restricted amount: " + count);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -142,8 +142,8 @@ public class Constructed extends DeckValidator {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!legal && !invalid.containsKey(card.getName())) {
|
||||
invalid.put(card.getName(), "Invalid rarity: " + card.getRarity());
|
||||
if (!legal && !errorsListContainsGroup(card.getName())) {
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid rarity: " + card.getRarity());
|
||||
}
|
||||
return legal;
|
||||
}
|
||||
|
@ -180,8 +180,8 @@ public class Constructed extends DeckValidator {
|
|||
legal = true;
|
||||
}
|
||||
|
||||
if (!legal && !invalid.containsKey(card.getName())) {
|
||||
invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode());
|
||||
if (!legal && !errorsListContainsGroup(card.getName())) {
|
||||
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Invalid set: " + card.getExpansionSetCode());
|
||||
}
|
||||
return legal;
|
||||
}
|
||||
|
@ -192,11 +192,11 @@ public class Constructed extends DeckValidator {
|
|||
if (entry.getValue() > maxCopies
|
||||
&& !basicLandNames.contains(entry.getKey())
|
||||
&& !anyNumberCardsAllowed.contains(entry.getKey())) {
|
||||
invalid.put(entry.getKey(), "Too many: " + entry.getValue());
|
||||
addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue());
|
||||
valid = false;
|
||||
}
|
||||
if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) {
|
||||
invalid.put(entry.getKey(), "Too many: " + entry.getValue());
|
||||
addError(DeckValidatorErrorType.OTHER, entry.getKey(), "Too many: " + entry.getValue());
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,8 @@ package mage.cards.decks;
|
|||
import mage.cards.Card;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -14,8 +13,7 @@ public abstract class DeckValidator implements Serializable {
|
|||
|
||||
protected String name;
|
||||
protected String shortName;
|
||||
|
||||
protected Map<String, String> invalid = new HashMap<>();
|
||||
protected List<DeckValidatorError> errorsList = new ArrayList<>();
|
||||
|
||||
public DeckValidator(String name) {
|
||||
setName(name);
|
||||
|
@ -49,8 +47,62 @@ public abstract class DeckValidator implements Serializable {
|
|||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public Map<String, String> getInvalid() {
|
||||
return invalid;
|
||||
public List<DeckValidatorError> getErrorsList() {
|
||||
return this.errorsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get errors list sorted by error type and texts
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<DeckValidatorError> getErrorsListSorted() {
|
||||
List<DeckValidatorError> list = new ArrayList<>(this.getErrorsList());
|
||||
|
||||
Collections.sort(list, new Comparator<DeckValidatorError>() {
|
||||
@Override
|
||||
public int compare(DeckValidatorError e1, DeckValidatorError e2) {
|
||||
int res = 0;
|
||||
|
||||
// sort by error type
|
||||
Integer order1 = e1.getErrorType().getSortOrder();
|
||||
Integer order2 = e2.getErrorType().getSortOrder();
|
||||
res = order2.compareTo(order1);
|
||||
|
||||
// sort by group
|
||||
if (res != 0) {
|
||||
res = e2.getGroup().compareTo(e1.getGroup());
|
||||
}
|
||||
|
||||
// sort by message
|
||||
if (res != 0) {
|
||||
res = e2.getMessage().compareTo(e1.getMessage());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public String getErrorsListInfo() {
|
||||
// for tests
|
||||
return this.errorsList.stream()
|
||||
.map(e -> e.getGroup() + "=" + e.getMessage())
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
public void addError(DeckValidatorErrorType errorType, String group, String message) {
|
||||
this.errorsList.add(new DeckValidatorError(errorType, group, message));
|
||||
}
|
||||
|
||||
public boolean errorsListContainsGroup(String group) {
|
||||
return this.errorsList.stream().anyMatch(e -> e.getGroup().equals(group));
|
||||
}
|
||||
|
||||
public boolean isPartlyValid() {
|
||||
return errorsList.size() == 0 || !errorsList.stream().anyMatch(e -> !e.getErrorType().isPartlyLegal());
|
||||
}
|
||||
|
||||
protected void countCards(Map<String, Integer> counts, Collection<Card> cards) {
|
||||
|
|
29
Mage/src/main/java/mage/cards/decks/DeckValidatorError.java
Normal file
29
Mage/src/main/java/mage/cards/decks/DeckValidatorError.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package mage.cards.decks;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class DeckValidatorError {
|
||||
|
||||
private final DeckValidatorErrorType errorType;
|
||||
private final String group;
|
||||
private final String message;
|
||||
|
||||
public DeckValidatorError(DeckValidatorErrorType errorType, String group, String message) {
|
||||
this.errorType = errorType;
|
||||
this.group = group;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public DeckValidatorErrorType getErrorType() {
|
||||
return this.errorType;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return this.group;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package mage.cards.decks;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum DeckValidatorErrorType {
|
||||
|
||||
PRIMARY(false, 10), // first errors to show (e.g. missing commander)
|
||||
DECK_SIZE(true, 20), // wrong deck size (deck must be legal while building)
|
||||
BANNED(false, 30),
|
||||
WRONG_SET(false, 40),
|
||||
OTHER(false, 50);
|
||||
|
||||
private final boolean partlyLegal; // for deck legality panel: is it partly legal (e.g. show deck legal even without full deck size)
|
||||
private final int sortOrder; // errors list sort order from small to big
|
||||
|
||||
DeckValidatorErrorType(boolean partlyLegal, int sortOrder) {
|
||||
this.partlyLegal = partlyLegal;
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public boolean isPartlyLegal() {
|
||||
return this.partlyLegal;
|
||||
}
|
||||
|
||||
public int getSortOrder() {
|
||||
return this.sortOrder;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue