use of mage.cards.decks.Deck in project mage by magefree.
the class Commander method validate.
@Override
public boolean validate(Deck deck) {
boolean valid = true;
errorsList.clear();
FilterMana colorIdentity = new FilterMana();
Set<Card> commanders = new HashSet<>();
Card companion;
int sbsize = deck.getSideboard().size();
Card card1;
Card card2;
Card card3;
Iterator<Card> iter;
switch(deck.getSideboard().size()) {
case 1:
companion = null;
commanders.add(deck.getSideboard().iterator().next());
break;
case 2:
iter = deck.getSideboard().iterator();
card1 = iter.next();
card2 = iter.next();
if (card1.getAbilities().stream().anyMatch(CompanionAbility.class::isInstance)) {
companion = card1;
commanders.add(card2);
} else if (card2.getAbilities().stream().anyMatch(CompanionAbility.class::isInstance)) {
companion = card2;
commanders.add(card1);
} else {
companion = null;
commanders.add(card1);
commanders.add(card2);
}
break;
case 3:
iter = deck.getSideboard().iterator();
card1 = iter.next();
card2 = iter.next();
card3 = iter.next();
if (card1.getAbilities().stream().anyMatch(CompanionAbility.class::isInstance)) {
companion = card1;
commanders.add(card2);
commanders.add(card3);
} else if (card2.getAbilities().stream().anyMatch(CompanionAbility.class::isInstance)) {
companion = card2;
commanders.add(card1);
commanders.add(card3);
} else if (card3.getAbilities().stream().anyMatch(CompanionAbility.class::isInstance)) {
companion = card3;
commanders.add(card1);
commanders.add(card2);
} else {
companion = null;
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
valid = false;
}
break;
default:
companion = null;
addError(DeckValidatorErrorType.PRIMARY, "Commander", "Sideboard must contain only the commander(s) and up to 1 companion");
valid = false;
}
if (companion != null && deck.getCards().size() + deck.getSideboard().size() != 101) {
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 101 + " cards (companion doesn't count for deck size): has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
valid = false;
} else if (companion == null && deck.getCards().size() + deck.getSideboard().size() != 100) {
addError(DeckValidatorErrorType.DECK_SIZE, "Deck", "Must contain " + 100 + " cards: has " + (deck.getCards().size() + deck.getSideboard().size()) + " cards");
valid = false;
}
Map<String, Integer> counts = new HashMap<>();
countCards(counts, deck.getCards());
countCards(counts, deck.getSideboard());
valid = checkCounts(1, counts) && valid;
for (String bannedCard : banned) {
if (counts.containsKey(bannedCard)) {
addError(DeckValidatorErrorType.BANNED, bannedCard, "Banned", true);
valid = false;
}
}
Set<String> commanderNames = new HashSet<>();
for (Card commander : commanders) {
commanderNames.add(commander.getName());
}
if (commanders.size() == 2 && commanders.stream().map(MageObject::getAbilities).filter(abilities -> abilities.contains(PartnerAbility.getInstance())).count() != 2 && commanders.stream().map(MageObject::getAbilities).filter(abilities -> abilities.contains(FriendsForeverAbility.getInstance())).count() != 2 && !CardUtil.castStream(commanders.stream().map(MageObject::getAbilities), PartnerWithAbility.class).map(PartnerWithAbility::getPartnerName).allMatch(commanderNames::contains)) {
for (Card commander : commanders) {
addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander with invalid Partner (" + commander.getName() + ')', true);
valid = false;
}
}
for (Card commander : commanders) {
if (bannedCommander.contains(commander.getName())) {
addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander banned (" + commander.getName() + ')', true);
valid = false;
}
if ((!commander.hasCardTypeForDeckbuilding(CardType.CREATURE) || !commander.isLegendary()) && !commander.getAbilities().contains(CanBeYourCommanderAbility.getInstance())) {
addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander invalid (" + commander.getName() + ')', true);
valid = false;
}
if (commanders.size() == 2 && bannedPartner.contains(commander.getName())) {
addError(DeckValidatorErrorType.PRIMARY, commander.getName(), "Commander Partner banned (" + commander.getName() + ')', true);
valid = false;
}
ManaUtil.collectColorIdentity(colorIdentity, commander.getColorIdentity());
}
// no needs in cards check on wrong commanders
if (!valid) {
return false;
}
for (Card card : deck.getCards()) {
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true);
valid = false;
}
}
for (Card card : deck.getSideboard()) {
if (!ManaUtil.isColorIdentityCompatible(colorIdentity, card.getColorIdentity())) {
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid color (" + colorIdentity.toString() + ')', true);
valid = false;
}
}
for (Card card : deck.getCards()) {
if (!isSetAllowed(card.getExpansionSetCode())) {
if (!legalSets(card)) {
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true);
valid = false;
}
}
}
for (Card card : deck.getSideboard()) {
if (!isSetAllowed(card.getExpansionSetCode())) {
if (!legalSets(card)) {
addError(DeckValidatorErrorType.WRONG_SET, card.getName(), "Not allowed Set: " + card.getExpansionSetCode(), true);
valid = false;
}
}
}
// Check for companion legality
if (companion != null) {
Set<Card> cards = new HashSet<>(deck.getCards());
cards.addAll(commanders);
for (Ability ability : companion.getAbilities()) {
if (ability instanceof CompanionAbility) {
CompanionAbility companionAbility = (CompanionAbility) ability;
if (!companionAbility.isLegal(cards, getDeckMinSize())) {
addError(DeckValidatorErrorType.PRIMARY, companion.getName(), "Commander Companion (deck invalid for companion)", true);
valid = false;
}
break;
}
}
}
return valid;
}
use of mage.cards.decks.Deck in project mage by magefree.
the class DeckBuilder method buildDeck.
public static synchronized Deck buildDeck(List<Card> spellCardPool, List<ColoredManaSymbol> allowedColors, List<String> setsToUse, List<Card> landCardPool, int deckCardSize, RateCallback callback) {
deckSize = deckCardSize;
deck = new Deck();
final Collection<MageScoredCard> remainingCards = new ArrayList<>();
Set<String> names = new HashSet<>();
for (final Card card : spellCardPool) {
if (names.contains(card.getName())) {
continue;
}
remainingCards.add(new MageScoredCard(card, allowedColors, callback));
names.add(card.getName());
}
// prints score and manaScore to log
// for(MageScoredCard scoreCard :remainingCards) {
// Logger.getLogger(DeckBuilder.class).info(
// new StringBuilder("Score: ")
// .append(scoreCard.getScore())
// .append(" ManaScore: ")
// .append(scoreCard.getManaCostScore(scoreCard.getCard(), allowedColors))
// .append(" ")
// .append(scoreCard.getCard().getName())
// .append(" ")
// .append(scoreCard.getCard().getManaCost().getText()).toString()
// );
// }
int min = 0;
if (deckSize == 40) {
deckCount = DECK_COUNT40;
deckSpells = 23;
deckLands = 17;
} else {
deckCount = DECK_COUNT60;
deckSpells = 35;
deckLands = 25;
}
for (int index = 0; index < deckCount.length; index++) {
final int max = DECK_COST[index];
addCardsToDeck(remainingCards, min, max, deckCount[index]);
min = max + 1;
}
addCardsToDeck(remainingCards, 0, 4, deckSpells - deck.getCards().size());
addCardsToDeck(remainingCards, 5, 10, deckSpells - deck.getCards().size());
addLandsToDeck(allowedColors, setsToUse, landCardPool, callback);
Deck returnedDeck = deck;
deck = null;
return returnedDeck;
}
use of mage.cards.decks.Deck in project mage by magefree.
the class TableController method joinTournament.
public synchronized boolean joinTournament(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException {
if (table.getState() != TableState.WAITING) {
return false;
}
Seat seat = table.getNextAvailableSeat(playerType);
if (seat == null) {
throw new GameException("No available seats.");
}
Optional<User> _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
logger.fatal("couldn't get user " + name + " for join tournament userId = " + userId);
return false;
}
User user = _user.get();
// check password
if (!table.getTournament().getOptions().getPassword().isEmpty() && playerType == PlayerType.HUMAN) {
if (!table.getTournament().getOptions().getPassword().equals(password)) {
user.showUserMessage("Join Table", "Wrong password.");
return false;
}
}
if (userPlayerMap.containsKey(userId) && playerType == PlayerType.HUMAN) {
user.showUserMessage("Join Table", "You can join a table only one time.");
return false;
}
Deck deck = null;
if (!table.getTournament().getTournamentType().isLimited()) {
if (deckList != null) {
deck = Deck.load(deckList, false, false);
} else {
user.showUserMessage("Join Table", "No valid deck selected!");
return false;
}
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");
List<DeckValidatorError> errorsList = table.getValidator().getErrorsListSorted();
errorsList.stream().forEach(error -> {
sb.append(error.getGroup()).append(": ").append(error.getMessage()).append("\n");
});
sb.append("\n\nSelect a deck that is appropriate for the selected format and try again!");
user.showUserMessage("Join Table", sb.toString());
if (isOwner(userId)) {
logger.debug("New table removed because owner submitted invalid deck tableId " + table.getId());
managerFactory.tableManager().removeTable(table.getId());
}
return false;
}
}
// Check quit ratio.
int quitRatio = table.getTournament().getOptions().getQuitRatio();
if (quitRatio < user.getTourneyQuitRatio()) {
String message = new StringBuilder("Your quit ratio ").append(user.getTourneyQuitRatio()).append("% is higher than the table requirement ").append(quitRatio).append('%').toString();
user.showUserMessage("Join Table", message);
return false;
}
// Check minimum rating.
int minimumRating = table.getTournament().getOptions().getMinimumRating();
int userRating;
if (table.getTournament().getOptions().getMatchOptions().isLimited()) {
userRating = user.getUserData().getLimitedRating();
} else {
userRating = user.getUserData().getConstructedRating();
}
if (userRating < minimumRating) {
String message = new StringBuilder("Your rating ").append(userRating).append(" is lower than the table requirement ").append(minimumRating).toString();
user.showUserMessage("Join Table", message);
return false;
}
Optional<Player> playerOptional = createPlayer(name, seat.getPlayerType(), skill);
if (playerOptional.isPresent()) {
Player player = playerOptional.get();
if (!player.canJoinTable(table)) {
user.showUserMessage("Join Table", new StringBuilder("A ").append(seat.getPlayerType()).append(" player can't join this table.").toString());
return false;
}
tournament.addPlayer(player, seat.getPlayerType());
TournamentPlayer tournamentPlayer = tournament.getPlayer(player.getId());
if (deck != null && tournamentPlayer != null) {
tournamentPlayer.submitDeck(deck);
}
table.joinTable(player, seat);
logger.debug("Player " + player.getName() + " id: " + player.getId() + " joined tableId: " + table.getId());
// only inform human players and add them to sessionPlayerMap
if (seat.getPlayer().isHuman()) {
seat.getPlayer().setUserData(user.getUserData());
user.addTable(player.getId(), table);
user.ccJoinedTable(table.getRoomId(), table.getId(), true);
userPlayerMap.put(userId, player.getId());
}
return true;
} else {
throw new GameException("Playertype " + seat.getPlayerType() + " could not be created.");
}
}
use of mage.cards.decks.Deck in project mage by magefree.
the class TableController method updateDeck.
public void updateDeck(UUID userId, DeckCardLists deckList) throws MageException {
boolean validDeck;
UUID playerId = userPlayerMap.get(userId);
if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) {
return;
}
Deck deck = Deck.load(deckList, false, false);
validDeck = updateDeck(userId, playerId, deck);
if (!validDeck && getTableState() == TableState.SIDEBOARDING) {
logger.warn(" userId: " + userId + " - Modified deck card list!");
}
}
use of mage.cards.decks.Deck in project mage by magefree.
the class PlayGameTest method playOneGame.
@Ignore
@Test
public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException {
Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 20);
Player computerA = createPlayer("ComputerA", PlayerType.COMPUTER_MINIMAX_HYBRID);
// Player playerA = createPlayer("ComputerA", "Computer - mad");
// Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
Deck deck = generateRandomDeck();
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 = createPlayer("ComputerB", PlayerType.COMPUTER_MINIMAX_HYBRID);
// Player playerB = createPlayer("ComputerB", "Computer - mad");
// Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
Deck deck2 = generateRandomDeck();
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());
// parseScenario("scenario1.txt");
// game.cheat(playerA.getId(), commandsA);
// game.cheat(playerA.getId(), libraryCardsA, handCardsA, battlefieldCardsA, graveyardCardsA);
// game.cheat(playerB.getId(), commandsB);
// game.cheat(playerB.getId(), libraryCardsB, handCardsB, battlefieldCardsB, graveyardCardsB);
// boolean testMode = false;
boolean testMode = true;
long t1 = System.nanoTime();
GameOptions options = new GameOptions();
options.testMode = true;
game.setGameOptions(options);
game.start(computerA.getId());
long t2 = System.nanoTime();
logger.info("Winner: " + game.getWinner());
logger.info("Time: " + (t2 - t1) / 1000000 + " ms");
/*if (!game.getWinner().equals("Player ComputerA is the winner")) {
throw new RuntimeException("Lost :(");
}*/
}
Aggregations