package com.vdom.core; import java.util.ArrayList; import java.util.HashSet; import com.vdom.api.Card; import com.vdom.api.GameEvent; import com.vdom.api.TreasureCard; import com.vdom.api.VictoryCard; public class TreasureCardImpl extends CardImpl implements TreasureCard { int value; boolean providePotion; public TreasureCardImpl(Cards.Type type, int cost, int value) { super(type, cost); this.value = value; } public TreasureCardImpl(Builder builder) { super(builder); value = builder.value; providePotion = builder.providePotion; } public static class Builder extends CardImpl.Builder { protected int value; protected boolean providePotion = false; public Builder(Cards.Type type, int cost, int value) { super(type, cost); this.value = value; } public Builder providePotion() { providePotion = true; return this; } public TreasureCardImpl build() { return new TreasureCardImpl(this); } } protected TreasureCardImpl() { } public TreasureCardImpl(String name, int cost, int value2, boolean costPotion, boolean b) { } public int getValue() { return value; } @Override public CardImpl instantiate() { checkInstantiateOK(); TreasureCardImpl c = new TreasureCardImpl(); copyValues(c); return c; } public boolean providePotion() { return providePotion; } protected void copyValues(TreasureCardImpl c) { super.copyValues(c); c.value = value; c.providePotion = providePotion; } @Override // return true if Treasure cards should be re-evaluated since might affect // coin play order public boolean playTreasure(MoveContext context) { return playTreasure(context, false); } public boolean playTreasure(MoveContext context, boolean isClone) { boolean reevaluateTreasures = false; Player player = context.player; Game game = context.game; GameEvent event = new GameEvent(GameEvent.Type.PlayingCoin, (MoveContext) context); event.card = this; game.broadcastEvent(event); if (this.numberTimesAlreadyPlayed == 0) { player.playedCards.add(player.hand.removeCard(this)); } if (!isClone) { context.treasuresPlayedSoFar++; } context.gold += getValue(); if (providePotion()) { context.potions++; } // Special cards if (equals(Cards.foolsGold)) { foolsGold(context); } else if (equals(Cards.philosophersStone)) { context.gold += (player.getDeckSize() + player.getDiscardSize()) / 5; } else if (equals(Cards.diadem)) { context.gold += context.getActionsLeft(); } else if (equals(Cards.copper)) { context.gold += context.coppersmithsPlayed; } else if (equals(Cards.bank)) { context.gold += context.treasuresPlayedSoFar; } else if (equals(Cards.contraband)) { reevaluateTreasures = contraband(context, game, reevaluateTreasures); } else if (equals(Cards.loan) || equals(Cards.venture)) { reevaluateTreasures = loanVenture(context, player, game, reevaluateTreasures); } else if (equals(Cards.hornOfPlenty)) { hornOfPlenty(context, player, game); } else if (equals(Cards.illGottenGains)) { reevaluateTreasures = illGottenGains(context, player, reevaluateTreasures); } else if (equals(Cards.counterfeit)) { reevaluateTreasures = counterfeit(context, game, reevaluateTreasures, player); } else if (equals(Cards.spoils)) { if (!isClone) { // Return to the spoils pile AbstractCardPile pile = game.getPile(this); pile.addCard(player.playedCards.remove(player.playedCards.indexOf(this.getId()))); } } return reevaluateTreasures; } protected void foolsGold(MoveContext context) { context.foolsGoldPlayed++; if (context.foolsGoldPlayed > 1) { context.gold += 3; } } protected boolean contraband(MoveContext context, Game game, boolean reevaluateTreasures) { context.buys++; Card cantBuyCard = game.getNextPlayer().controlPlayer.contraband_cardPlayerCantBuy(context); if (cantBuyCard != null && !context.cantBuy.contains(cantBuyCard)) { context.cantBuy.add(cantBuyCard); GameEvent e = new GameEvent(GameEvent.Type.CantBuy, (MoveContext) context); game.broadcastEvent(e); } return true; } protected boolean loanVenture(MoveContext context, Player player, Game game, boolean reevaluateTreasures) { ArrayList<Card> toDiscard = new ArrayList<Card>(); TreasureCard treasureCardFound = null; GameEvent event = null; while (treasureCardFound == null) { Card draw = game.draw(player); if (draw == null) { break; } event = new GameEvent(GameEvent.Type.CardRevealed, context); event.card = draw; game.broadcastEvent(event); if (draw instanceof TreasureCard) { treasureCardFound = (TreasureCard) draw; } else { toDiscard.add(draw); } } if (treasureCardFound != null) { if (equals(Cards.loan)) { if (player.controlPlayer.loan_shouldTrashTreasure(context, treasureCardFound)) { player.trash(treasureCardFound, this, context); } else { player.discard(treasureCardFound, this, null); } } else if (equals(Cards.venture)) { player.hand.add(treasureCardFound); treasureCardFound.playTreasure(context); reevaluateTreasures = true; } } while (!toDiscard.isEmpty()) { player.discard(toDiscard.remove(0), this, null); } return reevaluateTreasures; } protected boolean illGottenGains(MoveContext context, Player player, boolean reevaluateTreasures) { if (context.getCardsLeftInPile(Cards.copper) > 0) { if (player.controlPlayer.illGottenGains_gainCopper(context)) { player.gainNewCard(Cards.copper, this, context); reevaluateTreasures = true; } } return reevaluateTreasures; } protected void hornOfPlenty(MoveContext context, Player player, Game game) { GameEvent event; int maxCost = context.countUniqueCardsInPlayThisTurn(); Card toObtain = player.controlPlayer.hornOfPlenty_cardToObtain(context, maxCost); if (toObtain != null) { // check cost if (toObtain.getCost(context) <= maxCost) { toObtain = game.takeFromPile(toObtain); // could still be null here if the pile is empty. if (toObtain != null) { event = new GameEvent(GameEvent.Type.CardObtained, context); event.card = toObtain; event.responsible = this; game.broadcastEvent(event); if (toObtain instanceof VictoryCard) { player.playedCards.remove(this); player.trash(this, toObtain, context); event = new GameEvent(GameEvent.Type.CardTrashed, context); event.card = this; game.broadcastEvent(event); } } } } } protected boolean counterfeit(MoveContext context, Game game, boolean reevaluateTreasures, Player currentPlayer) { context.buys++; TreasureCard treasure = currentPlayer.controlPlayer.counterfeit_cardToPlay(context); if (treasure != null) { TreasureCardImpl cardToPlay = (TreasureCardImpl) treasure; cardToPlay.cloneCount = 2; for (int i = 0; i < cardToPlay.cloneCount;) { cardToPlay.numberTimesAlreadyPlayed = i++; cardToPlay.playTreasure(context, cardToPlay.numberTimesAlreadyPlayed == 0 ? false : true); } cardToPlay.cloneCount = 0; cardToPlay.numberTimesAlreadyPlayed = 0; // A counterfeited card will not count in the calculations of future cards that care about the number of treasures played (such as Bank) context.treasuresPlayedSoFar--; if (!treasure.equals(Cards.spoils)) { if (currentPlayer.playedCards.getLastCard().getId() == cardToPlay.getId()) { currentPlayer.trash(currentPlayer.playedCards.removeLastCard(), this, context); } } } return true; } @Override public void isBought(MoveContext context) { switch (this.controlCard.getType()) { case Masterpiece: masterpiece(context); break; default: break; } } public void masterpiece(MoveContext context) { for (int i = 0; i < context.overpayAmount; ++i) { if(!context.getPlayer().gainNewCard(Cards.silver, this.controlCard, context)) { break; } } } }