mirror of
https://github.com/correl/mage.git
synced 2024-11-15 03:00:16 +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.Deck;
|
||||||
import mage.cards.decks.DeckValidator;
|
import mage.cards.decks.DeckValidator;
|
||||||
|
import mage.cards.decks.DeckValidatorError;
|
||||||
import mage.cards.decks.importer.DeckImporter;
|
import mage.cards.decks.importer.DeckImporter;
|
||||||
import org.unbescape.html.HtmlEscape;
|
import org.unbescape.html.HtmlEscape;
|
||||||
import org.unbescape.html.HtmlEscapeLevel;
|
import org.unbescape.html.HtmlEscapeLevel;
|
||||||
|
@ -10,7 +11,6 @@ import org.unbescape.html.HtmlEscapeType;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Elandril
|
* @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_UNKNOWN = new Color(174, 174, 174);
|
||||||
protected static final Color COLOR_LEGAL = new Color(117, 152, 110);
|
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_NOT_LEGAL = new Color(191, 84, 74);
|
||||||
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
|
protected static final Color COLOR_TEXT = new Color(255, 255, 255);
|
||||||
protected static final Dimension DIM_MINIMUM = new Dimension(75, 25);
|
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);
|
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) {
|
protected String formatInvalidTooltip(java.util.List<DeckValidatorError> sortedErrorsList) {
|
||||||
return invalid.entrySet().stream()
|
return sortedErrorsList.stream()
|
||||||
.sorted(Map.Entry.comparingByKey())
|
|
||||||
.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>",
|
.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>";
|
+ "</table></body></html>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,6 +146,10 @@ public class LegalityLabel extends JLabel {
|
||||||
showState(COLOR_LEGAL, tooltip);
|
showState(COLOR_LEGAL, tooltip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showStatePartlyLegal(String tooltip) {
|
||||||
|
showState(COLOR_PARTLY_LEGAL, tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
public void showStateNotLegal(String tooltip) {
|
public void showStateNotLegal(String tooltip) {
|
||||||
showState(COLOR_NOT_LEGAL, tooltip);
|
showState(COLOR_NOT_LEGAL, tooltip);
|
||||||
}
|
}
|
||||||
|
@ -157,8 +168,10 @@ public class LegalityLabel extends JLabel {
|
||||||
try {
|
try {
|
||||||
if (validator.validate(deck)) {
|
if (validator.validate(deck)) {
|
||||||
showStateLegal("<html><body>Deck is <span style='color:green;font-weight:bold;'>VALID</span></body></html>");
|
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 {
|
} else {
|
||||||
showStateNotLegal(formatInvalidTooltip(validator.getInvalid()));
|
showStateNotLegal(formatInvalidTooltip(validator.getErrorsListSorted()));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} 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())));
|
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.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -92,14 +93,14 @@ public class AusHighlander extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
if (deck.getCards().size() != getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (deck.getSideboard().size() > 15) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,12 +140,12 @@ public class AusHighlander extends Constructed {
|
||||||
String cn = entry.getKey();
|
String cn = entry.getKey();
|
||||||
if (pointMap.containsKey(cn)) {
|
if (pointMap.containsKey(cn)) {
|
||||||
totalPoints += pointMap.get(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) {
|
if (totalPoints > 7) {
|
||||||
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);
|
||||||
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, "Only you can see this!", "Your opponents will not be able to see this message or what cards are in your deck!");
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import mage.abilities.keyword.CompanionAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ public class Brawl extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
Card brawler = null;
|
Card brawler = null;
|
||||||
Card companion = null;
|
Card companion = null;
|
||||||
FilterMana colorIdentity = new FilterMana();
|
FilterMana colorIdentity = new FilterMana();
|
||||||
|
@ -60,32 +61,32 @@ public class Brawl extends Constructed {
|
||||||
companion = card2;
|
companion = card2;
|
||||||
brawler = card1;
|
brawler = card1;
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (brawler != null) {
|
if (brawler != null) {
|
||||||
ManaUtil.collectColorIdentity(colorIdentity, brawler.getColorIdentity());
|
ManaUtil.collectColorIdentity(colorIdentity, brawler.getColorIdentity());
|
||||||
if (bannedCommander.contains(brawler.getName())) {
|
if (bannedCommander.contains(brawler.getName())) {
|
||||||
invalid.put("Brawl", "Brawler banned (" + brawler.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Brawler banned (" + brawler.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (!((brawler.isCreature() && brawler.isLegendary())
|
if (!((brawler.isCreature() && brawler.isLegendary())
|
||||||
|| brawler.isPlaneswalker() || brawler.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
|| brawler.isPlaneswalker() || brawler.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||||
invalid.put("Brawl", "Invalid Brawler (" + brawler.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Brawl", "Invalid Brawler (" + brawler.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + 1) {
|
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;
|
valid = false;
|
||||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize()) {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ public class Brawl extends Constructed {
|
||||||
|
|
||||||
for (String bannedCard : banned) {
|
for (String bannedCard : banned) {
|
||||||
if (counts.containsKey(bannedCard)) {
|
if (counts.containsKey(bannedCard)) {
|
||||||
invalid.put(bannedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +115,7 @@ public class Brawl extends Constructed {
|
||||||
&& !(colorIdentity.isColorless()
|
&& !(colorIdentity.isColorless()
|
||||||
&& basicsInDeck.size() == 1
|
&& basicsInDeck.size() == 1
|
||||||
&& basicsInDeck.contains(card.getName()))) {
|
&& basicsInDeck.contains(card.getName()))) {
|
||||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,14 +124,14 @@ public class Brawl extends Constructed {
|
||||||
&& !(colorIdentity.isColorless()
|
&& !(colorIdentity.isColorless()
|
||||||
&& basicsInDeck.size() == 1
|
&& basicsInDeck.size() == 1
|
||||||
&& basicsInDeck.contains(card.getName()))) {
|
&& basicsInDeck.contains(card.getName()))) {
|
||||||
invalid.put(card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +139,7 @@ public class Brawl extends Constructed {
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +152,7 @@ public class Brawl extends Constructed {
|
||||||
if (ability instanceof CompanionAbility) {
|
if (ability instanceof CompanionAbility) {
|
||||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -74,15 +75,15 @@ public class CanadianHighlander extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
if (deck.getCards().size() < 100) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!deck.getSideboard().isEmpty()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +98,11 @@ public class CanadianHighlander extends Constructed {
|
||||||
String cn = entry.getKey();
|
String cn = entry.getKey();
|
||||||
if (pointMap.containsKey(cn)) {
|
if (pointMap.containsKey(cn)) {
|
||||||
totalPoints += pointMap.get(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) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
|
|
||||||
|
@ -97,7 +98,7 @@ public class Commander extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
FilterMana colorIdentity = new FilterMana();
|
FilterMana colorIdentity = new FilterMana();
|
||||||
Set<Card> commanders = new HashSet<>();
|
Set<Card> commanders = new HashSet<>();
|
||||||
Card companion = null;
|
Card companion = null;
|
||||||
|
@ -136,19 +137,19 @@ public class Commander extends Constructed {
|
||||||
commanders.add(card1);
|
commanders.add(card1);
|
||||||
commanders.add(card2);
|
commanders.add(card2);
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
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;
|
valid = false;
|
||||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ public class Commander extends Constructed {
|
||||||
|
|
||||||
for (String bannedCard : banned) {
|
for (String bannedCard : banned) {
|
||||||
if (counts.containsKey(bannedCard)) {
|
if (counts.containsKey(bannedCard)) {
|
||||||
invalid.put(bannedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,18 +171,18 @@ public class Commander extends Constructed {
|
||||||
}
|
}
|
||||||
for (Card commander : commanders) {
|
for (Card commander : commanders) {
|
||||||
if (bannedCommander.contains(commander.getName())) {
|
if (bannedCommander.contains(commander.getName())) {
|
||||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if ((!commander.isCreature() || !commander.isLegendary())
|
if ((!commander.isCreature() || !commander.isLegendary())
|
||||||
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||||
invalid.put("Commander", "Commander invalid (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (commanders.size() == 2) {
|
if (commanders.size() == 2) {
|
||||||
if (commander.getAbilities().contains(PartnerAbility.getInstance())) {
|
if (commander.getAbilities().contains(PartnerAbility.getInstance())) {
|
||||||
if (bannedPartner.contains(commander.getName())) {
|
if (bannedPartner.contains(commander.getName())) {
|
||||||
invalid.put("Commander", "Partner banned (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Partner banned (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -192,7 +193,7 @@ public class Commander extends Constructed {
|
||||||
.map(PartnerWithAbility::getPartnerName)
|
.map(PartnerWithAbility::getPartnerName)
|
||||||
.anyMatch(commanderNames::contains);
|
.anyMatch(commanderNames::contains);
|
||||||
if (!partnersWith) {
|
if (!partnersWith) {
|
||||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,20 +208,20 @@ public class Commander extends Constructed {
|
||||||
|
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +229,7 @@ public class Commander extends Constructed {
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +242,7 @@ public class Commander extends Constructed {
|
||||||
if (ability instanceof CompanionAbility) {
|
if (ability instanceof CompanionAbility) {
|
||||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mage.deck;
|
||||||
|
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckValidator;
|
import mage.cards.decks.DeckValidator;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author fireshoes
|
* @author fireshoes
|
||||||
|
@ -33,10 +34,10 @@ public class Freeform extends DeckValidator {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
// http://magic.wizards.com/en/gameinfo/gameplay/formats/freeform
|
// http://magic.wizards.com/en/gameinfo/gameplay/formats/freeform
|
||||||
if (deck.getCards().size() < getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ public class FreeformCommander extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
FilterMana colorIdentity = new FilterMana();
|
FilterMana colorIdentity = new FilterMana();
|
||||||
Set<Card> commanders = new HashSet<>();
|
Set<Card> commanders = new HashSet<>();
|
||||||
Card companion = null;
|
Card companion = null;
|
||||||
|
@ -92,19 +93,19 @@ public class FreeformCommander extends Constructed {
|
||||||
commanders.add(card1);
|
commanders.add(card1);
|
||||||
commanders.add(card2);
|
commanders.add(card2);
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
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;
|
valid = false;
|
||||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ public class FreeformCommander extends Constructed {
|
||||||
}
|
}
|
||||||
for (Card commander : commanders) {
|
for (Card commander : commanders) {
|
||||||
if (!commander.isCreature() || !commander.isLegendary()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (commanders.size() == 2) {
|
if (commanders.size() == 2) {
|
||||||
|
@ -131,7 +132,7 @@ public class FreeformCommander extends Constructed {
|
||||||
.map(PartnerWithAbility::getPartnerName)
|
.map(PartnerWithAbility::getPartnerName)
|
||||||
.anyMatch(commanderNames::contains);
|
.anyMatch(commanderNames::contains);
|
||||||
if (!partnersWith) {
|
if (!partnersWith) {
|
||||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,13 +147,13 @@ public class FreeformCommander extends Constructed {
|
||||||
|
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,7 +165,7 @@ public class FreeformCommander extends Constructed {
|
||||||
if (ability instanceof CompanionAbility) {
|
if (ability instanceof CompanionAbility) {
|
||||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorError;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -104,10 +105,10 @@ public class HistoricalType2 extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
|
|
||||||
Map<String, String> leastInvalid = null;
|
List<DeckValidatorError> leastInvalid = null;
|
||||||
|
|
||||||
boolean valid = false;
|
boolean valid = false;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// first, check whether misty and batterskull are in the same deck.
|
// first, check whether misty and batterskull are in the same deck.
|
||||||
Map<String, Integer> counts = new HashMap<>();
|
Map<String, Integer> counts = new HashMap<>();
|
||||||
|
@ -125,7 +126,7 @@ public class HistoricalType2 extends Constructed {
|
||||||
for (String[] sets : standards) {
|
for (String[] sets : standards) {
|
||||||
|
|
||||||
// clear the invalid list
|
// clear the invalid list
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// add the sets to the setCodes.
|
// add the sets to the setCodes.
|
||||||
setCodes = new ArrayList<>(Arrays.asList(sets));
|
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
|
// if the map holding the invalid cards is empty, set it to a
|
||||||
// copy of the current invalid list.
|
// copy of the current invalid list.
|
||||||
if (leastInvalid == null) {
|
if (leastInvalid == null) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see how many invalid cards there are. if there are less invalid
|
// see how many invalid cards there are. if there are less invalid
|
||||||
// cards than the stored invalid list, assign the current invalid
|
// cards than the stored invalid list, assign the current invalid
|
||||||
// to leastInvalid.
|
// to leastInvalid.
|
||||||
if (leastInvalid.size() > this.getInvalid().size()) {
|
if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ public class HistoricalType2 extends Constructed {
|
||||||
|
|
||||||
// clear the invalid list and set codes.
|
// clear the invalid list and set codes.
|
||||||
setCodes.clear();
|
setCodes.clear();
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// increment the start and end dates.
|
// increment the start and end dates.
|
||||||
start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1);
|
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.
|
// validate it. If it validates, clear the invalid cards and break.
|
||||||
if (super.validate(deck)) {
|
if (super.validate(deck)) {
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -192,17 +193,16 @@ public class HistoricalType2 extends Constructed {
|
||||||
// cards than the stored invalid list, assign the current invalid
|
// cards than the stored invalid list, assign the current invalid
|
||||||
// to leastInvalid.
|
// to leastInvalid.
|
||||||
if (leastInvalid == null) {
|
if (leastInvalid == null) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
|
} else if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||||
} else if (leastInvalid.size() > this.getInvalid().size()) {
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no standard environment is valid, set the invalid to the
|
// if no standard environment is valid, set the invalid to the
|
||||||
// invalid that had the least errors.
|
// invalid that had the least errors.
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.invalid = new HashMap<>(leastInvalid);
|
this.errorsList = new ArrayList<>(leastInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the validity.
|
// return the validity.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package mage.deck;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckValidator;
|
import mage.cards.decks.DeckValidator;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -30,17 +31,17 @@ public class Momir extends DeckValidator {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
if (deck.getCards().size() != getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes"));
|
List<String> basicLandNames = new ArrayList<>(Arrays.asList("Forest", "Island", "Mountain", "Swamp", "Plains", "Wastes"));
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!basicLandNames.contains(card.getName())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import mage.abilities.keyword.PartnerAbility;
|
||||||
import mage.abilities.keyword.PartnerWithAbility;
|
import mage.abilities.keyword.PartnerWithAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
|
|
||||||
|
@ -82,10 +83,10 @@ public class Oathbreaker extends Vintage {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
if (deck.getCards().size() + deck.getSideboard().size() != 60) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ public class Oathbreaker extends Vintage {
|
||||||
|
|
||||||
for (String bannedCard : banned) {
|
for (String bannedCard : banned) {
|
||||||
if (counts.containsKey(bannedCard)) {
|
if (counts.containsKey(bannedCard)) {
|
||||||
invalid.put(bannedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +107,7 @@ public class Oathbreaker extends Vintage {
|
||||||
Set<String> signatureSpells = new HashSet<>();
|
Set<String> signatureSpells = new HashSet<>();
|
||||||
FilterMana allCommandersColor = new FilterMana();
|
FilterMana allCommandersColor = new FilterMana();
|
||||||
if (deck.getSideboard().size() < 2 || deck.getSideboard().size() > 4) {
|
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;
|
valid = false;
|
||||||
} else {
|
} else {
|
||||||
// collect data
|
// collect data
|
||||||
|
@ -120,7 +121,7 @@ public class Oathbreaker extends Vintage {
|
||||||
// color identity from commanders only, not spell
|
// color identity from commanders only, not spell
|
||||||
ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity());
|
ManaUtil.collectColorIdentity(allCommandersColor, commander.getColorIdentity());
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,15 +129,15 @@ public class Oathbreaker extends Vintage {
|
||||||
|
|
||||||
// check size (1+1 or 2+2 allows)
|
// check size (1+1 or 2+2 allows)
|
||||||
if (commanderNames.isEmpty() || commanderNames.size() > 2) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (signatureSpells.isEmpty() || signatureSpells.size() > 2) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (signatureSpells.size() != commanderNames.size()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +154,7 @@ public class Oathbreaker extends Vintage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!partnersWith) {
|
if (!partnersWith) {
|
||||||
invalid.put("Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Oathbreaker", "Oathbreaker without Partner (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +176,7 @@ public class Oathbreaker extends Vintage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!haveSameColor) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,7 +190,7 @@ public class Oathbreaker extends Vintage {
|
||||||
|
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(allCommandersColor, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +198,7 @@ public class Oathbreaker extends Vintage {
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.cards.decks.PennyDreadfulLegalityUtil;
|
import mage.cards.decks.PennyDreadfulLegalityUtil;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.util.ManaUtil;
|
import mage.util.ManaUtil;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author spjspj
|
* @author spjspj
|
||||||
|
@ -47,7 +47,7 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
FilterMana colorIdentity = new FilterMana();
|
FilterMana colorIdentity = new FilterMana();
|
||||||
Set<Card> commanders = new HashSet<>();
|
Set<Card> commanders = new HashSet<>();
|
||||||
Card companion = null;
|
Card companion = null;
|
||||||
|
@ -86,19 +86,19 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
commanders.add(card1);
|
commanders.add(card1);
|
||||||
commanders.add(card2);
|
commanders.add(card2);
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
|
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;
|
valid = false;
|
||||||
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
|
|
||||||
for (String wantedCard : counts.keySet()) {
|
for (String wantedCard : counts.keySet()) {
|
||||||
if (!(pdAllowed.containsKey(wantedCard))) {
|
if (!(pdAllowed.containsKey(wantedCard))) {
|
||||||
invalid.put(wantedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", wantedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,12 +124,12 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
}
|
}
|
||||||
for (Card commander : commanders) {
|
for (Card commander : commanders) {
|
||||||
if (bannedCommander.contains(commander.getName())) {
|
if (bannedCommander.contains(commander.getName())) {
|
||||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if ((!commander.isCreature() || !commander.isLegendary())
|
if ((!commander.isCreature() || !commander.isLegendary())
|
||||||
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
&& (!commander.isPlaneswalker() || !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance()))) {
|
||||||
invalid.put("Commander", "Commander invalid (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalid (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (commanders.size() == 2) {
|
if (commanders.size() == 2) {
|
||||||
|
@ -141,7 +141,7 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
.map(PartnerWithAbility::getPartnerName)
|
.map(PartnerWithAbility::getPartnerName)
|
||||||
.anyMatch(commanderNames::contains);
|
.anyMatch(commanderNames::contains);
|
||||||
if (!partnersWith) {
|
if (!partnersWith) {
|
||||||
invalid.put("Commander", "Commander without Partner (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander without Partner (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,20 +156,20 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
|
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ public class PennyDreadfulCommander extends Constructed {
|
||||||
if (ability instanceof CompanionAbility) {
|
if (ability instanceof CompanionAbility) {
|
||||||
CompanionAbility companionAbility = (CompanionAbility) ability;
|
CompanionAbility companionAbility = (CompanionAbility) ability;
|
||||||
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
|
||||||
invalid.put(companion.getName(), "Deck invalid for companion");
|
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Deck invalid for companion");
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
|
||||||
import mage.cards.Sets;
|
import mage.cards.Sets;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorError;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -77,10 +78,10 @@ public class SuperType2 extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
|
|
||||||
Map<String, String> leastInvalid = null;
|
List<DeckValidatorError> leastInvalid = null;
|
||||||
|
|
||||||
boolean valid = false;
|
boolean valid = false;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// first, check whether misty and batterskull are in the same deck.
|
// first, check whether misty and batterskull are in the same deck.
|
||||||
Map<String, Integer> counts = new HashMap<>();
|
Map<String, Integer> counts = new HashMap<>();
|
||||||
|
@ -98,7 +99,7 @@ public class SuperType2 extends Constructed {
|
||||||
for (String[] sets : standards) {
|
for (String[] sets : standards) {
|
||||||
|
|
||||||
// clear the invalid list
|
// clear the invalid list
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// add the sets to the setCodes.
|
// add the sets to the setCodes.
|
||||||
setCodes = new ArrayList<>(Arrays.asList(sets));
|
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
|
// if the map holding the invalid cards is empty, set it to a
|
||||||
// copy of the current invalid list.
|
// copy of the current invalid list.
|
||||||
if (leastInvalid == null) {
|
if (leastInvalid == null) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// see how many invalid cards there are. if there are less invalid
|
// see how many invalid cards there are. if there are less invalid
|
||||||
// cards than the stored invalid list, assign the current invalid
|
// cards than the stored invalid list, assign the current invalid
|
||||||
// to leastInvalid.
|
// to leastInvalid.
|
||||||
if (leastInvalid.size() > this.getInvalid().size()) {
|
if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +147,7 @@ public class SuperType2 extends Constructed {
|
||||||
|
|
||||||
// clear the invalid list and set codes.
|
// clear the invalid list and set codes.
|
||||||
setCodes.clear();
|
setCodes.clear();
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
// increment the start and end dates.
|
// increment the start and end dates.
|
||||||
start.set(Calendar.YEAR, start.get(Calendar.YEAR) + 1);
|
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.
|
// validate it. If it validates, clear the invalid cards and break.
|
||||||
if (super.validate(deck)) {
|
if (super.validate(deck)) {
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -181,17 +182,17 @@ public class SuperType2 extends Constructed {
|
||||||
// cards than the stored invalid list, assign the current invalid
|
// cards than the stored invalid list, assign the current invalid
|
||||||
// to leastInvalid.
|
// to leastInvalid.
|
||||||
if (leastInvalid == null) {
|
if (leastInvalid == null) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
|
|
||||||
} else if (leastInvalid.size() > this.getInvalid().size()) {
|
} else if (leastInvalid.size() > this.getErrorsList().size()) {
|
||||||
leastInvalid = new HashMap<>(this.getInvalid());
|
leastInvalid = new ArrayList<>(this.getErrorsList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no standard environment is valid, set the invalid to the
|
// if no standard environment is valid, set the invalid to the
|
||||||
// invalid that had the least errors.
|
// invalid that had the least errors.
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
this.invalid = new HashMap<>(leastInvalid);
|
this.errorsList = new ArrayList<>(leastInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the validity.
|
// return the validity.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import mage.cards.Sets;
|
||||||
import mage.cards.SplitCard;
|
import mage.cards.SplitCard;
|
||||||
import mage.cards.decks.Constructed;
|
import mage.cards.decks.Constructed;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
import mage.filter.FilterMana;
|
import mage.filter.FilterMana;
|
||||||
import mage.game.GameTinyLeadersImpl;
|
import mage.game.GameTinyLeadersImpl;
|
||||||
|
|
||||||
|
@ -103,10 +104,10 @@ public class TinyLeaders extends Constructed {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
|
|
||||||
if (deck.getCards().size() != getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ public class TinyLeaders extends Constructed {
|
||||||
|
|
||||||
for (String bannedCard : banned) {
|
for (String bannedCard : banned) {
|
||||||
if (counts.containsKey(bannedCard)) {
|
if (counts.containsKey(bannedCard)) {
|
||||||
invalid.put(bannedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,16 +136,16 @@ public class TinyLeaders extends Constructed {
|
||||||
if (commander == null || commander.getManaCost().convertedManaCost() > 3) {
|
if (commander == null || commander.getManaCost().convertedManaCost() > 3) {
|
||||||
if (commander == null) {
|
if (commander == null) {
|
||||||
if (deck.getName() == 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.)");
|
+ "(You can use the \"Sultai\" for a UBG (3/3) default Commander or \"Glass\" for a colorless 3/3 default Commander.)");
|
||||||
} else {
|
} 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)");
|
+ "(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) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -162,21 +163,21 @@ public class TinyLeaders extends Constructed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalid.put("Commander", "Commander banned (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander banned (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
invalid.put("Commander", "Commander invalide (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Commander invalide (" + commander.getName() + ')');
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
valid = false;
|
||||||
}
|
}
|
||||||
for (Card card : deck.getCards()) {
|
for (Card card : deck.getCards()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +185,7 @@ public class TinyLeaders extends Constructed {
|
||||||
for (Card card : deck.getSideboard()) {
|
for (Card card : deck.getSideboard()) {
|
||||||
if (!isSetAllowed(card.getExpansionSetCode())) {
|
if (!isSetAllowed(card.getExpansionSetCode())) {
|
||||||
if (!legalSets(card)) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,22 +195,22 @@ public class TinyLeaders extends Constructed {
|
||||||
|
|
||||||
private boolean isCardFormatValid(Card card, Card commander, FilterMana color) {
|
private boolean isCardFormatValid(Card card, Card commander, FilterMana color) {
|
||||||
if (!cardHasValideColor(color, card)) {
|
if (!cardHasValideColor(color, card)) {
|
||||||
invalid.put(card.getName(), "Invalid color (" + commander.getName() + ')');
|
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + commander.getName() + ')');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//905.5b - Converted mana cost must be 3 or less
|
//905.5b - Converted mana cost must be 3 or less
|
||||||
if (card instanceof SplitCard) {
|
if (card instanceof SplitCard) {
|
||||||
if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (card.getManaCost().convertedManaCost() > 3) {
|
} 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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mage.deck;
|
||||||
|
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckValidator;
|
import mage.cards.decks.DeckValidator;
|
||||||
|
import mage.cards.decks.DeckValidatorErrorType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -28,17 +29,17 @@ public class Limited extends DeckValidator {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
//20091005 - 100.2b
|
//20091005 - 100.2b
|
||||||
if (deck.getCards().size() < getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
Map<String, Integer> counts = new HashMap<>();
|
Map<String, Integer> counts = new HashMap<>();
|
||||||
countCards(counts, deck.getCards());
|
countCards(counts, deck.getCards());
|
||||||
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
|
for (Map.Entry<String, Integer> entry : counts.entrySet()) {
|
||||||
if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package mage.server;
|
||||||
import mage.MageException;
|
import mage.MageException;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckCardLists;
|
import mage.cards.decks.DeckCardLists;
|
||||||
|
import mage.cards.decks.DeckValidatorError;
|
||||||
import mage.cards.decks.DeckValidatorFactory;
|
import mage.cards.decks.DeckValidatorFactory;
|
||||||
import mage.constants.RangeOfInfluence;
|
import mage.constants.RangeOfInfluence;
|
||||||
import mage.constants.TableState;
|
import mage.constants.TableState;
|
||||||
|
@ -32,11 +33,8 @@ import mage.server.util.ThreadExecutor;
|
||||||
import mage.view.ChatMessage;
|
import mage.view.ChatMessage;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
@ -150,9 +148,10 @@ public class TableController {
|
||||||
}
|
}
|
||||||
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
|
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");
|
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()) {
|
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
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!");
|
sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!");
|
||||||
user.showUserMessage("Join Table", sb.toString());
|
user.showUserMessage("Join Table", sb.toString());
|
||||||
if (isOwner(userId)) {
|
if (isOwner(userId)) {
|
||||||
|
@ -267,9 +266,10 @@ public class TableController {
|
||||||
|
|
||||||
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
|
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");
|
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()) {
|
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
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!");
|
sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!");
|
||||||
user.showUserMessage("Join Table", sb.toString());
|
user.showUserMessage("Join Table", sb.toString());
|
||||||
if (isOwner(userId)) {
|
if (isOwner(userId)) {
|
||||||
|
@ -425,9 +425,10 @@ public class TableController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder("Invalid deck for the selected ").append(table.getValidator().getName()).append(" format. \n\n");
|
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()) {
|
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
|
||||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append('\n');
|
errorsList.stream().forEach(error -> {
|
||||||
}
|
sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n");
|
||||||
|
});
|
||||||
sb.append("\n\nAdd enough cards and try again!");
|
sb.append("\n\nAdd enough cards and try again!");
|
||||||
_user.get().showUserMessage("Submit deck", sb.toString());
|
_user.get().showUserMessage("Submit deck", sb.toString());
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
|
|
||||||
package org.mage.test.serverside.deck;
|
package org.mage.test.serverside.deck;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.decks.DeckValidator;
|
import mage.cards.decks.DeckValidator;
|
||||||
import mage.cards.repository.CardInfo;
|
import mage.cards.repository.CardInfo;
|
||||||
|
@ -14,8 +11,10 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.MageTestBase;
|
import org.mage.test.serverside.base.MageTestBase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public class DeckValidatorTest extends MageTestBase {
|
public class DeckValidatorTest extends MageTestBase {
|
||||||
|
@ -65,7 +64,7 @@ public class DeckValidatorTest extends MageTestBase {
|
||||||
|
|
||||||
DeckValidator validator = new Standard();
|
DeckValidator validator = new Standard();
|
||||||
boolean validationSuccessful = testDeckValid(validator, deck);
|
boolean validationSuccessful = testDeckValid(validator, deck);
|
||||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -79,7 +78,7 @@ public class DeckValidatorTest extends MageTestBase {
|
||||||
DeckValidator validator = new Standard();
|
DeckValidator validator = new Standard();
|
||||||
testDeckValid(validator, deck, sideboard);
|
testDeckValid(validator, deck, sideboard);
|
||||||
Assert.assertEquals("invalid message not correct",
|
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
|
@Test
|
||||||
|
@ -229,119 +228,119 @@ public class DeckValidatorTest extends MageTestBase {
|
||||||
deckList.add(new CardNameAmount("Ancestral Vision", 4));
|
deckList.add(new CardNameAmount("Ancestral Vision", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
boolean validationSuccessful = testDeckValid(validator, deckList);
|
boolean validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Ancient Den", 4));
|
deckList.add(new CardNameAmount("Ancient Den", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.add(new CardNameAmount("Birthing Pod", 4));
|
deckList.add(new CardNameAmount("Birthing Pod", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Blazing Shoal", 4));
|
deckList.add(new CardNameAmount("Blazing Shoal", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Bloodbraid Elf", 4));
|
deckList.add(new CardNameAmount("Bloodbraid Elf", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Chrome Mox", 4));
|
deckList.add(new CardNameAmount("Chrome Mox", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Cloudpost", 4));
|
deckList.add(new CardNameAmount("Cloudpost", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Dark Depths", 4));
|
deckList.add(new CardNameAmount("Dark Depths", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Deathrite Shaman", 4));
|
deckList.add(new CardNameAmount("Deathrite Shaman", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Dig Through Time", 4));
|
deckList.add(new CardNameAmount("Dig Through Time", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Dread Return", 4));
|
deckList.add(new CardNameAmount("Dread Return", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Glimpse of Nature", 4));
|
deckList.add(new CardNameAmount("Glimpse of Nature", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Great Furnace", 4));
|
deckList.add(new CardNameAmount("Great Furnace", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Green Sun's Zenith", 4));
|
deckList.add(new CardNameAmount("Green Sun's Zenith", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Hypergenesis", 4));
|
deckList.add(new CardNameAmount("Hypergenesis", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Jace, the Mind Sculptor", 4));
|
deckList.add(new CardNameAmount("Jace, the Mind Sculptor", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertTrue(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertTrue(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
|
|
||||||
deckList.clear();
|
deckList.clear();
|
||||||
deckList.add(new CardNameAmount("Mental Misstep", 4));
|
deckList.add(new CardNameAmount("Mental Misstep", 4));
|
||||||
deckList.add(new CardNameAmount("Mountain", 56));
|
deckList.add(new CardNameAmount("Mountain", 56));
|
||||||
validationSuccessful = testDeckValid(validator, deckList);
|
validationSuccessful = testDeckValid(validator, deckList);
|
||||||
Assert.assertFalse(validator.getInvalid().toString(), validationSuccessful);
|
Assert.assertFalse(validator.getErrorsListInfo(), validationSuccessful);
|
||||||
validator.getInvalid().clear();
|
validator.getErrorsList().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean testDeckValid(DeckValidator validator, List<CardNameAmount> cards) {
|
private boolean testDeckValid(DeckValidator validator, List<CardNameAmount> cards) {
|
||||||
|
|
|
@ -58,15 +58,15 @@ public class Constructed extends DeckValidator {
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(Deck deck) {
|
public boolean validate(Deck deck) {
|
||||||
boolean valid = true;
|
boolean valid = true;
|
||||||
invalid.clear();
|
errorsList.clear();
|
||||||
//20091005 - 100.2a
|
//20091005 - 100.2a
|
||||||
if (deck.getCards().size() < getDeckMinSize()) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
//20130713 - 100.4a
|
//20130713 - 100.4a
|
||||||
if (deck.getSideboard().size() > 15) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public class Constructed extends DeckValidator {
|
||||||
|
|
||||||
for (String bannedCard : banned) {
|
for (String bannedCard : banned) {
|
||||||
if (counts.containsKey(bannedCard)) {
|
if (counts.containsKey(bannedCard)) {
|
||||||
invalid.put(bannedCard, "Banned");
|
addError(DeckValidatorErrorType.BANNED, "Banned", bannedCard);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ public class Constructed extends DeckValidator {
|
||||||
if (counts.containsKey(restrictedCard)) {
|
if (counts.containsKey(restrictedCard)) {
|
||||||
int count = counts.get(restrictedCard);
|
int count = counts.get(restrictedCard);
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
invalid.put(restrictedCard, "Restricted: " + count);
|
addError(DeckValidatorErrorType.OTHER, restrictedCard, "Restricted amount: " + count);
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,8 +142,8 @@ public class Constructed extends DeckValidator {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!legal && !invalid.containsKey(card.getName())) {
|
if (!legal && !errorsListContainsGroup(card.getName())) {
|
||||||
invalid.put(card.getName(), "Invalid rarity: " + card.getRarity());
|
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid rarity: " + card.getRarity());
|
||||||
}
|
}
|
||||||
return legal;
|
return legal;
|
||||||
}
|
}
|
||||||
|
@ -180,8 +180,8 @@ public class Constructed extends DeckValidator {
|
||||||
legal = true;
|
legal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!legal && !invalid.containsKey(card.getName())) {
|
if (!legal && !errorsListContainsGroup(card.getName())) {
|
||||||
invalid.put(card.getName(), "Invalid set: " + card.getExpansionSetCode());
|
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Invalid set: " + card.getExpansionSetCode());
|
||||||
}
|
}
|
||||||
return legal;
|
return legal;
|
||||||
}
|
}
|
||||||
|
@ -192,11 +192,11 @@ public class Constructed extends DeckValidator {
|
||||||
if (entry.getValue() > maxCopies
|
if (entry.getValue() > maxCopies
|
||||||
&& !basicLandNames.contains(entry.getKey())
|
&& !basicLandNames.contains(entry.getKey())
|
||||||
&& !anyNumberCardsAllowed.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;
|
valid = false;
|
||||||
}
|
}
|
||||||
if (entry.getValue() > 7 && entry.getKey().equals("Seven Dwarves")) {
|
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;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,8 @@ package mage.cards.decks;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com
|
||||||
|
@ -14,8 +13,7 @@ public abstract class DeckValidator implements Serializable {
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String shortName;
|
protected String shortName;
|
||||||
|
protected List<DeckValidatorError> errorsList = new ArrayList<>();
|
||||||
protected Map<String, String> invalid = new HashMap<>();
|
|
||||||
|
|
||||||
public DeckValidator(String name) {
|
public DeckValidator(String name) {
|
||||||
setName(name);
|
setName(name);
|
||||||
|
@ -49,8 +47,62 @@ public abstract class DeckValidator implements Serializable {
|
||||||
this.shortName = shortName;
|
this.shortName = shortName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getInvalid() {
|
public List<DeckValidatorError> getErrorsList() {
|
||||||
return invalid;
|
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) {
|
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