mirror of
https://github.com/correl/mage.git
synced 2025-04-12 09:11:05 -09:00
* Sideboarding: fixed that it possible to auto-submit 40 cards deck instead 60 in constructed formats (#5579);
Sideboarding: fixed that cheated deck with sideboard can be used instead lose the game;
This commit is contained in:
parent
3dd6836559
commit
de4befb9c2
22 changed files with 204 additions and 124 deletions
Mage.Server.Plugins
Mage.Deck.Constructed/src/mage/deck
AusHighlander.javaBrawl.javaCommander.javaFreeform.javaFreeformCommander.javaMomir.javaPennyDreadfulCommander.javaTinyLeaders.java
Mage.Deck.Limited/src/mage/deck
Mage.Player.AI/src/main/java/mage/player/ai
Mage.Server/src/main/java/mage/server
Mage.Tests/src/test/java/org/mage/test
Mage/src/main/java/mage
cards/decks
game
|
@ -95,8 +95,8 @@ public class AusHighlander extends Constructed {
|
|||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
|
||||
if (deck.getCards().size() != 60) {
|
||||
invalid.put("Deck", "Must contain 60 singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " singleton cards: has " + (deck.getCards().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
if (deck.getSideboard().size() > 15) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package mage.deck;
|
||||
|
||||
import java.util.*;
|
||||
import mage.abilities.common.CanBeYourCommanderAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.filter.FilterMana;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public class Brawl extends Constructed {
|
||||
|
@ -30,13 +30,18 @@ public class Brawl extends Constructed {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != 60) {
|
||||
invalid.put("Deck", "Must contain 60 cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,13 +74,23 @@ public class Commander extends Constructed {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 99;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain 100 cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + getSideboardMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + getSideboardMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public class Freeform extends DeckValidator {
|
||||
|
@ -14,12 +12,22 @@ public class Freeform extends DeckValidator {
|
|||
super("Constructed - Freeform");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 40;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
// http://magic.wizards.com/en/gameinfo/gameplay/formats/freeform
|
||||
if (deck.getCards().size() < 40) {
|
||||
invalid.put("Deck", "Must contain at least 40 cards: has only " + deck.getCards().size() + " cards");
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.*;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.keyword.PartnerAbility;
|
||||
import mage.abilities.keyword.PartnerWithAbility;
|
||||
|
@ -12,8 +10,9 @@ import mage.cards.decks.Constructed;
|
|||
import mage.cards.decks.Deck;
|
||||
import mage.filter.FilterMana;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author spjspj
|
||||
*/
|
||||
public class FreeformCommander extends Constructed {
|
||||
|
@ -35,13 +34,23 @@ public class FreeformCommander extends Constructed {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 99;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain 100 cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + getSideboardMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + getSideboardMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
|
||||
package mage.deck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author nigelzor
|
||||
*/
|
||||
public class Momir extends DeckValidator {
|
||||
|
@ -22,12 +21,22 @@ public class Momir extends DeckValidator {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
|
||||
if (deck.getCards().size() != 60) {
|
||||
invalid.put("Deck", "Must contain 60 cards: has " + deck.getCards().size() + " cards");
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,23 @@ public class PennyDreadfulCommander extends Constructed {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 99;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
FilterMana colorIdentity = new FilterMana();
|
||||
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != 100) {
|
||||
invalid.put("Deck", "Must contain 100 cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
if (deck.getCards().size() + deck.getSideboard().size() != getDeckMinSize() + getSideboardMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + +getSideboardMinSize() + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,16 @@ public class TinyLeaders extends Constructed {
|
|||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 49; // commander gives from deck name
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deck
|
||||
* @return - True if deck is valid
|
||||
|
@ -90,8 +100,8 @@ public class TinyLeaders extends Constructed {
|
|||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
|
||||
if (deck.getCards().size() != 49) {
|
||||
invalid.put("Deck", "Must contain 49 cards: has " + deck.getCards().size() + " cards");
|
||||
if (deck.getCards().size() != getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain " + getDeckMinSize() + " cards: has " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
|
||||
package mage.deck;
|
||||
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class Limited extends DeckValidator {
|
||||
|
@ -15,12 +12,22 @@ public class Limited extends DeckValidator {
|
|||
super("Limited");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 40;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
boolean valid = true;
|
||||
//20091005 - 100.2b
|
||||
if (deck.getCards().size() < 40) {
|
||||
invalid.put("Deck", "Must contain at least 40 cards: has only " + deck.getCards().size() + " cards");
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import mage.cards.Card;
|
|||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.cards.decks.DeckValidatorFactory;
|
||||
import mage.cards.repository.CardCriteria;
|
||||
import mage.cards.repository.CardInfo;
|
||||
import mage.cards.repository.CardRepository;
|
||||
|
@ -200,7 +202,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
if (((TargetPermanent) target).canTarget(abilityControllerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) {
|
||||
if (target.canTarget(abilityControllerId, permanent.getId(), null, game) && !target.getTargets().contains(permanent.getId())) {
|
||||
// stop to add targets if not needed and outcome is no advantage for AI player
|
||||
if (target.getNumberOfTargets() == target.getTargets().size()) {
|
||||
if (outcome.isGood() && hasOpponent(permanent.getControllerId(), game)) {
|
||||
|
@ -487,7 +489,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
Collections.reverse(targets);
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
if (((TargetControlledPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
target.addTarget(permanent.getId(), source, game);
|
||||
if (target.getNumberOfTargets() <= target.getTargets().size() && (!outcome.isGood() || target.getMaxNumberOfTargets() <= target.getTargets().size())) {
|
||||
return true;
|
||||
|
@ -516,7 +518,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
targets = game.getBattlefield().getActivePermanents(t.getFilter(), playerId, game);
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
if (((TargetPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
target.addTarget(permanent.getId(), source, game);
|
||||
if (!outcomeTargets || target.getMaxNumberOfTargets() <= target.getTargets().size()) {
|
||||
return true;
|
||||
|
@ -740,7 +742,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
outcomeTargets = false;
|
||||
}
|
||||
for (Permanent permanent : targets) {
|
||||
if (((TargetSpellOrPermanent) target).canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
if (target.canTarget(abilityControllerId, permanent.getId(), source, game)) {
|
||||
target.addTarget(permanent.getId(), source, game);
|
||||
if (!outcomeTargets || target.getMaxNumberOfTargets() <= target.getTargets().size()) {
|
||||
return true;
|
||||
|
@ -750,7 +752,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
if (!game.getStack().isEmpty()) {
|
||||
for (StackObject stackObject : game.getStack()) {
|
||||
if (stackObject instanceof Spell && source != null && !source.getId().equals(stackObject.getStackAbility().getId())) {
|
||||
if (((TargetSpellOrPermanent) target).getFilter().match(stackObject, game)) {
|
||||
if (target.getFilter().match(stackObject, game)) {
|
||||
return tryAddTarget(target, stackObject.getId(), source, game);
|
||||
}
|
||||
}
|
||||
|
@ -812,7 +814,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
if (target.getOriginalTarget() instanceof TargetCardInExile) {
|
||||
List<Card> cards = new ArrayList<>();
|
||||
for (UUID uuid : ((TargetCardInExile) target).possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
||||
for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
||||
Card card = game.getCard(uuid);
|
||||
if (card != null) {
|
||||
cards.add(card);
|
||||
|
@ -829,7 +831,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
if (target.getOriginalTarget() instanceof TargetActivatedAbility) {
|
||||
List<StackObject> stackObjects = new ArrayList<>();
|
||||
for (UUID uuid : ((TargetActivatedAbility) target).possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
||||
for (UUID uuid : target.possibleTargets(source.getSourceId(), source.getControllerId(), game)) {
|
||||
StackObject stackObject = game.getStack().getStackObject(uuid);
|
||||
if (stackObject != null) {
|
||||
stackObjects.add(stackObject);
|
||||
|
@ -1358,9 +1360,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
// pay phyrexian life costs
|
||||
if (cost instanceof PhyrexianManaCost) {
|
||||
if (cost.pay(null, game, null, playerId, false, null) || permittingObject != null) {
|
||||
return true;
|
||||
}
|
||||
return cost.pay(null, game, null, playerId, false, null) || permittingObject != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1828,22 +1828,22 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
public static Deck buildDeck(List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
return buildDeck(cardPool, colors, false);
|
||||
public static Deck buildDeck(int deckMinSize, List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
return buildDeck(deckMinSize, cardPool, colors, false);
|
||||
}
|
||||
|
||||
public static Deck buildDeck(List<Card> cardPool, final List<ColoredManaSymbol> colors, boolean onlyBasicLands) {
|
||||
public static Deck buildDeck(int deckMinSize, List<Card> cardPool, final List<ColoredManaSymbol> colors, boolean onlyBasicLands) {
|
||||
if (onlyBasicLands) {
|
||||
return buildDeckWithOnlyBasicLands(cardPool);
|
||||
return buildDeckWithOnlyBasicLands(deckMinSize, cardPool);
|
||||
} else {
|
||||
return buildDeckWithNormalCards(cardPool, colors);
|
||||
return buildDeckWithNormalCards(deckMinSize, cardPool, colors);
|
||||
}
|
||||
}
|
||||
|
||||
public static Deck buildDeckWithOnlyBasicLands(List<Card> cardPool) {
|
||||
public static Deck buildDeckWithOnlyBasicLands(int deckMinSize, List<Card> cardPool) {
|
||||
// random cards from card pool
|
||||
Deck deck = new Deck();
|
||||
final int DECK_SIZE = 40;
|
||||
final int DECK_SIZE = deckMinSize != 0 ? deckMinSize : 40;
|
||||
|
||||
List<Card> sortedCards = new ArrayList<>(cardPool);
|
||||
if (sortedCards.size() > 0) {
|
||||
|
@ -1857,11 +1857,11 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
public static Deck buildDeckWithNormalCards(List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
public static Deck buildDeckWithNormalCards(int deckMinSize, List<Card> cardPool, final List<ColoredManaSymbol> colors) {
|
||||
// top 23 cards plus basic lands until 40 deck size
|
||||
Deck deck = new Deck();
|
||||
final int DECK_SIZE = 40;
|
||||
final int DECK_CARDS_COUNT = 23;
|
||||
final int DECK_SIZE = deckMinSize != 0 ? deckMinSize : 40;
|
||||
final int DECK_CARDS_COUNT = Math.floorDiv(deckMinSize * 23, 40); // 23 from 40
|
||||
final int DECK_LANDS_COUNT = DECK_SIZE - DECK_CARDS_COUNT;
|
||||
|
||||
// sort card pool by top score
|
||||
|
@ -1946,15 +1946,17 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
|
||||
@Override
|
||||
public void construct(Tournament tournament, Deck deck) {
|
||||
if (deck != null && deck.getCards().size() < 40 && !deck.getSideboard().isEmpty()) {
|
||||
//pick the top 23 cards
|
||||
DeckValidator deckValidator = DeckValidatorFactory.instance.createDeckValidator(tournament.getOptions().getMatchOptions().getDeckType());
|
||||
int deckMinSize = deckValidator != null ? deckValidator.getDeckMinSize() : 0;
|
||||
|
||||
if (deck != null && deck.getCards().size() < deckMinSize && !deck.getSideboard().isEmpty()) {
|
||||
if (chosenColors == null) {
|
||||
for (Card card : deck.getSideboard()) {
|
||||
rememberPick(card, RateCard.rateCard(card, null));
|
||||
}
|
||||
chosenColors = chooseDeckColorsIfPossible();
|
||||
}
|
||||
deck = buildDeck(new ArrayList<>(deck.getSideboard()), chosenColors);
|
||||
deck = buildDeck(deckMinSize, new ArrayList<>(deck.getSideboard()), chosenColors);
|
||||
}
|
||||
tournament.submitDeck(playerId, deck);
|
||||
}
|
||||
|
@ -2430,21 +2432,21 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
private boolean setTargetPlayer(Outcome outcome, Target target, Ability source, UUID sourceId, UUID abilityControllerId, UUID randomOpponentId, Game game) {
|
||||
if (target.getOriginalTarget() instanceof TargetOpponent) {
|
||||
if (source == null) {
|
||||
if (((TargetOpponent) target).canTarget(randomOpponentId, game)) {
|
||||
if (target.canTarget(randomOpponentId, game)) {
|
||||
target.add(randomOpponentId, game);
|
||||
return true;
|
||||
}
|
||||
} else if (((TargetOpponent) target).canTarget(randomOpponentId, source, game)) {
|
||||
} else if (target.canTarget(randomOpponentId, source, game)) {
|
||||
target.add(randomOpponentId, game);
|
||||
return true;
|
||||
}
|
||||
for (UUID currentId : game.getOpponents(abilityControllerId)) {
|
||||
if (source == null) {
|
||||
if (((TargetOpponent) target).canTarget(currentId, game)) {
|
||||
if (target.canTarget(currentId, game)) {
|
||||
target.add(currentId, game);
|
||||
return true;
|
||||
}
|
||||
} else if (((TargetOpponent) target).canTarget(currentId, source, game)) {
|
||||
} else if (target.canTarget(currentId, source, game)) {
|
||||
target.add(currentId, game);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package mage.server;
|
|||
|
||||
import mage.MageException;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.cards.decks.DeckValidatorFactory;
|
||||
import mage.cards.repository.CardInfo;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.cards.repository.ExpansionInfo;
|
||||
|
@ -142,7 +143,7 @@ public class MageServerImpl implements MageServer {
|
|||
return SessionManager.instance.connectUser(sessionId, userName, password, userIdStr);
|
||||
} catch (MageException ex) {
|
||||
if (ex instanceof MageVersionException) {
|
||||
throw (MageVersionException) ex;
|
||||
throw ex;
|
||||
}
|
||||
handleException(ex);
|
||||
}
|
||||
|
@ -268,7 +269,7 @@ public class MageServerImpl implements MageServer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean joinTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException {
|
||||
public boolean joinTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException {
|
||||
return executeWithResult("joinTable", sessionId, new ActionWithBooleanResult() {
|
||||
@Override
|
||||
public Boolean execute() throws MageException {
|
||||
|
@ -293,7 +294,7 @@ public class MageServerImpl implements MageServer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean joinTournamentTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException, GameException {
|
||||
public boolean joinTournamentTable(final String sessionId, final UUID roomId, final UUID tableId, final String name, final PlayerType playerType, final int skill, final DeckCardLists deckList, final String password) throws MageException {
|
||||
return executeWithResult("joinTournamentTable", sessionId, new ActionWithBooleanResult() {
|
||||
@Override
|
||||
public Boolean execute() throws MageException {
|
||||
|
@ -321,7 +322,7 @@ public class MageServerImpl implements MageServer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean submitDeck(final String sessionId, final UUID tableId, final DeckCardLists deckList) throws MageException, GameException {
|
||||
public boolean submitDeck(final String sessionId, final UUID tableId, final DeckCardLists deckList) throws MageException {
|
||||
return executeWithResult("submitDeck", sessionId, new ActionWithBooleanResult() {
|
||||
@Override
|
||||
public Boolean execute() throws MageException {
|
||||
|
@ -339,7 +340,7 @@ public class MageServerImpl implements MageServer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateDeck(final String sessionId, final UUID tableId, final DeckCardLists deckList) throws MageException, GameException {
|
||||
public void updateDeck(final String sessionId, final UUID tableId, final DeckCardLists deckList) throws MageException {
|
||||
execute("updateDeck", sessionId, () -> {
|
||||
Optional<Session> session = SessionManager.instance.getSession(sessionId);
|
||||
if (!session.isPresent()) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package mage.server;
|
|||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.decks.DeckValidatorFactory;
|
||||
import mage.cards.repository.CardScanner;
|
||||
import mage.cards.repository.PluginClassloaderRegistery;
|
||||
import mage.cards.repository.RepositoryUtil;
|
||||
|
@ -11,7 +12,6 @@ import mage.game.tournament.TournamentType;
|
|||
import mage.interfaces.MageServer;
|
||||
import mage.remote.Connection;
|
||||
import mage.server.draft.CubeFactory;
|
||||
import mage.server.game.DeckValidatorFactory;
|
||||
import mage.server.game.GameFactory;
|
||||
import mage.server.game.PlayerFactory;
|
||||
import mage.server.record.UserStatsRepository;
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
package mage.server;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import mage.MageException;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckCardLists;
|
||||
import mage.cards.decks.DeckValidatorFactory;
|
||||
import mage.constants.RangeOfInfluence;
|
||||
import mage.constants.TableState;
|
||||
import mage.game.*;
|
||||
|
@ -28,12 +20,10 @@ import mage.game.tournament.TournamentPlayer;
|
|||
import mage.players.Player;
|
||||
import mage.players.PlayerType;
|
||||
import mage.server.draft.DraftManager;
|
||||
import mage.server.game.DeckValidatorFactory;
|
||||
import mage.server.game.GameFactory;
|
||||
import mage.server.game.GameManager;
|
||||
import mage.server.game.PlayerFactory;
|
||||
import mage.server.record.TableRecorderImpl;
|
||||
import mage.server.tournament.TournamentController;
|
||||
import mage.server.tournament.TournamentFactory;
|
||||
import mage.server.tournament.TournamentManager;
|
||||
import mage.server.util.ConfigSettings;
|
||||
|
@ -42,6 +32,16 @@ import mage.server.util.ThreadExecutor;
|
|||
import mage.view.ChatMessage;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -876,7 +876,7 @@ public class TableController {
|
|||
private void autoSideboard() {
|
||||
for (MatchPlayer player : match.getPlayers()) {
|
||||
if (!player.isDoneSideboarding()) {
|
||||
match.submitDeck(player.getPlayer().getId(), player.generateDeck());
|
||||
match.submitDeck(player.getPlayer().getId(), player.generateDeck(table.getValidator()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -927,9 +927,9 @@ public class TableController {
|
|||
public boolean isTournamentStillValid() {
|
||||
if (table.getTournament() != null) {
|
||||
if (table.getState() != TableState.WAITING && table.getState() != TableState.READY_TO_START && table.getState() != TableState.STARTING) {
|
||||
return TournamentManager.instance.getTournamentController(table.getTournament().getId())
|
||||
.map(tc -> tc.isTournamentStillValid(table.getState()))
|
||||
.orElse(false);
|
||||
return TournamentManager.instance.getTournamentController(table.getTournament().getId())
|
||||
.map(tc -> tc.isTournamentStillValid(table.getState()))
|
||||
.orElse(false);
|
||||
|
||||
} else {
|
||||
// check if table creator is still a valid user, if not removeUserFromAllTablesAndChat table
|
||||
|
|
|
@ -31,6 +31,7 @@ import java.util.Locale;
|
|||
public class PlayGameTest extends MageTestBase {
|
||||
|
||||
private static final List<String> colorChoices = new ArrayList<>(Arrays.asList("bu", "bg", "br", "bw", "ug", "ur", "uw", "gr", "gw", "rw", "bur", "buw", "bug", "brg", "brw", "bgw", "wur", "wug", "wrg", "rgu"));
|
||||
private static final int DECK_SIZE = 40;
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
|
@ -42,8 +43,8 @@ public class PlayGameTest extends MageTestBase {
|
|||
// Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
Deck deck = generateRandomDeck();
|
||||
|
||||
if (deck.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck.getCards().size());
|
||||
if (deck.getCards().size() < DECK_SIZE) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size = " + deck.getCards().size() + ", but must be " + DECK_SIZE);
|
||||
}
|
||||
game.addPlayer(computerA, deck);
|
||||
game.loadCards(deck.getCards(), computerA.getId());
|
||||
|
@ -52,8 +53,8 @@ public class PlayGameTest extends MageTestBase {
|
|||
// Player playerB = createPlayer("ComputerB", "Computer - mad");
|
||||
// Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
Deck deck2 = generateRandomDeck();
|
||||
if (deck2.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck2.getCards().size());
|
||||
if (deck2.getCards().size() < DECK_SIZE) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size = " + deck2.getCards().size() + ", but must be " + DECK_SIZE);
|
||||
}
|
||||
game.addPlayer(computerB, deck2);
|
||||
game.loadCards(deck2.getCards(), computerB.getId());
|
||||
|
@ -89,6 +90,6 @@ public class PlayGameTest extends MageTestBase {
|
|||
allowedColors.add(ColoredManaSymbol.lookup(c));
|
||||
}
|
||||
List<Card> cardPool = Sets.generateRandomCardPool(45, allowedColors);
|
||||
return ComputerPlayer.buildDeck(cardPool, allowedColors);
|
||||
return ComputerPlayer.buildDeck(DECK_SIZE, cardPool, allowedColors);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.util.Locale;
|
|||
public class TestPlayRandomGame extends MageTestBase {
|
||||
|
||||
private static final List<String> colorChoices = new ArrayList<>(Arrays.asList("bu", "bg", "br", "bw", "ug", "ur", "uw", "gr", "gw", "rw", "bur", "buw", "bug", "brg", "brw", "bgw", "wur", "wug", "wrg", "rgu"));
|
||||
private static final int DECK_SIZE = 40;
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
|
@ -46,16 +47,16 @@ public class TestPlayRandomGame extends MageTestBase {
|
|||
Player computerA = createRandomPlayer("ComputerA");
|
||||
Deck deck = generateRandomDeck();
|
||||
|
||||
if (deck.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck.getCards().size());
|
||||
if (deck.getCards().size() < DECK_SIZE) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size = " + deck.getCards().size() + ", but must be " + DECK_SIZE);
|
||||
}
|
||||
game.addPlayer(computerA, deck);
|
||||
game.loadCards(deck.getCards(), computerA.getId());
|
||||
|
||||
Player computerB = createRandomPlayer("ComputerB");
|
||||
Deck deck2 = generateRandomDeck();
|
||||
if (deck2.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck2.getCards().size());
|
||||
if (deck2.getCards().size() < DECK_SIZE) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck2.getCards().size() + ", but must be " + DECK_SIZE);
|
||||
}
|
||||
game.addPlayer(computerB, deck2);
|
||||
game.loadCards(deck2.getCards(), computerB.getId());
|
||||
|
@ -80,6 +81,6 @@ public class TestPlayRandomGame extends MageTestBase {
|
|||
allowedColors.add(ColoredManaSymbol.lookup(c));
|
||||
}
|
||||
List<Card> cardPool = Sets.generateRandomCardPool(45, allowedColors);
|
||||
return ComputerPlayer.buildDeck(cardPool, allowedColors);
|
||||
return ComputerPlayer.buildDeck(DECK_SIZE, cardPool, allowedColors);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ import java.util.List;
|
|||
*/
|
||||
public class DeckTestUtils {
|
||||
|
||||
private static final int DECK_SIZE = 40;
|
||||
|
||||
public static Deck buildRandomDeck(String colors, boolean onlyBasicLands) {
|
||||
return buildRandomDeck(colors, onlyBasicLands, "");
|
||||
}
|
||||
|
@ -41,7 +43,7 @@ public class DeckTestUtils {
|
|||
}
|
||||
|
||||
List<Card> cardPool = Sets.generateRandomCardPool(45, allowedColors, onlyBasicLands, allowedList);
|
||||
return ComputerPlayer.buildDeck(cardPool, allowedColors, onlyBasicLands);
|
||||
return ComputerPlayer.buildDeck(DECK_SIZE, cardPool, allowedColors, onlyBasicLands);
|
||||
}
|
||||
|
||||
public static DeckCardLists buildRandomDeckAndInitCards(String colors, boolean onlyBasicLands) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.decks;
|
||||
|
||||
import mage.cards.Card;
|
||||
|
@ -41,12 +40,22 @@ public class Constructed extends DeckValidator {
|
|||
return setCodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeckMinSize() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSideboardMinSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate(Deck deck) {
|
||||
boolean valid = true;
|
||||
//20091005 - 100.2a
|
||||
if (deck.getCards().size() < 60) {
|
||||
invalid.put("Deck", "Must contain at least 60 cards: has only " + deck.getCards().size() + " cards");
|
||||
if (deck.getCards().size() < getDeckMinSize()) {
|
||||
invalid.put("Deck", "Must contain at least " + getDeckMinSize() + " cards: has only " + deck.getCards().size() + " cards");
|
||||
valid = false;
|
||||
}
|
||||
//20130713 - 100.4a
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
|
||||
package mage.cards.decks;
|
||||
|
||||
import mage.cards.Card;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import mage.cards.Card;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public abstract class DeckValidator implements Serializable {
|
||||
|
@ -32,11 +31,10 @@ public abstract class DeckValidator implements Serializable {
|
|||
}
|
||||
|
||||
protected void countCards(Map<String, Integer> counts, Collection<Card> cards) {
|
||||
for (Card card: cards) {
|
||||
for (Card card : cards) {
|
||||
if (counts.containsKey(card.getName())) {
|
||||
counts.put(card.getName(), counts.get(card.getName()) + 1);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
counts.put(card.getName(), 1);
|
||||
}
|
||||
}
|
||||
|
@ -45,4 +43,8 @@ public abstract class DeckValidator implements Serializable {
|
|||
public int getEdhPowerLevel(Deck deck) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public abstract int getDeckMinSize();
|
||||
|
||||
public abstract int getSideboardMinSize();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package mage.cards.decks;
|
||||
|
||||
|
||||
package mage.server.game;
|
||||
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
@ -11,7 +8,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public enum DeckValidatorFactory {
|
||||
|
@ -21,16 +17,12 @@ public enum DeckValidatorFactory {
|
|||
|
||||
private final Map<String, Class> deckTypes = new LinkedHashMap<>();
|
||||
|
||||
|
||||
|
||||
private DeckValidatorFactory() {}
|
||||
|
||||
public DeckValidator createDeckValidator(String deckType) {
|
||||
|
||||
DeckValidator validator;
|
||||
try {
|
||||
Constructor<?> con = deckTypes.get(deckType).getConstructor();
|
||||
validator = (DeckValidator)con.newInstance();
|
||||
validator = (DeckValidator) con.newInstance();
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("DeckValidatorFactory error", ex);
|
||||
return null;
|
|
@ -389,7 +389,9 @@ public abstract class MatchImpl implements Match {
|
|||
// Check if the cards included in the deck are the same as in the original deck
|
||||
validDeck = (player.getDeck().getDeckCompleteHashCode() == deck.getDeckCompleteHashCode());
|
||||
if (validDeck == false) {
|
||||
deck.getCards().clear(); // Clear the deck so the player cheating looses the game
|
||||
// clear the deck so the player cheating looses the game
|
||||
deck.getCards().clear();
|
||||
deck.getSideboard().clear();
|
||||
}
|
||||
player.updateDeck(deck);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
package mage.game.match;
|
||||
|
||||
import java.io.Serializable;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidator;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class MatchPlayer implements Serializable {
|
||||
|
@ -78,9 +78,9 @@ public class MatchPlayer implements Serializable {
|
|||
this.deck = deck;
|
||||
}
|
||||
|
||||
public Deck generateDeck() {
|
||||
//TODO: improve this
|
||||
while (deck.getCards().size() < 40 && !deck.getSideboard().isEmpty()) {
|
||||
public Deck generateDeck(DeckValidator deckValidator) {
|
||||
// auto complete deck
|
||||
while (deck.getCards().size() < deckValidator.getDeckMinSize() && !deck.getSideboard().isEmpty()) {
|
||||
Card card = deck.getSideboard().iterator().next();
|
||||
deck.getCards().add(card);
|
||||
deck.getSideboard().remove(card);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.game.tournament;
|
||||
|
||||
import java.util.Set;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.constants.TournamentPlayerState;
|
||||
import mage.game.result.ResultProtos.TourneyPlayerProto;
|
||||
|
@ -10,8 +8,9 @@ import mage.players.Player;
|
|||
import mage.players.PlayerType;
|
||||
import mage.util.TournamentUtil;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TournamentPlayer {
|
||||
|
@ -93,7 +92,9 @@ public class TournamentPlayer {
|
|||
// Check if the cards included in the deck are the same as in the original deck
|
||||
boolean validDeck = (getDeck().getDeckCompleteHashCode() == deck.getDeckCompleteHashCode());
|
||||
if (validDeck == false) {
|
||||
deck.getCards().clear(); // Clear the deck so the player cheating looses the game
|
||||
// Clear the deck so the player cheating looses the game
|
||||
deck.getCards().clear();
|
||||
deck.getSideboard().clear();
|
||||
}
|
||||
this.deck = deck;
|
||||
return validDeck;
|
||||
|
@ -177,7 +178,6 @@ public class TournamentPlayer {
|
|||
|
||||
/**
|
||||
* Free resources no longer needed if tournament has ended
|
||||
*
|
||||
*/
|
||||
public void cleanUpOnTournamentEnd() {
|
||||
this.deck = null;
|
||||
|
|
Loading…
Add table
Reference in a new issue