def sentry_fn(state, player): drawn_cards = draw(state, player, 2, draw_event=False) # Choose trash. trash_cards = dec.choose_cards(state, player, num_select=len(drawn_cards), prompt="You may trash cards with Sentry.", optional=True, card_container=drawn_cards) for card in trash_cards: trash(state, player, card, container=drawn_cards) # Choose discard. discard_cards = dec.choose_cards(state, player, num_select=len(drawn_cards), prompt="You may discard cards with Sentry.", optional=True, card_container=drawn_cards) for card in discard_cards: discard(state, player, card, container=drawn_cards) # Choose order to topdeck. topdeck_cards = dec.choose_cards(state, player, num_select=len(drawn_cards), prompt="You may put cards back in any order with Sentry. Cards are topdecked in " "order, so the card listed last is placed on top.", optional=False, card_container=drawn_cards) for card in topdeck_cards: topdeck(state, player, card, container=drawn_cards)
def bureaucrat_fn(state, player): gain_card_to_topdeck(state, player, state.supply_piles["Silver"]) # Attack code. for opp in state.other_players(player): if opp.immune_to_attack: opp.immune_to_attack=False continue victory_card_count = 0 for card in opp.hand: if card.is_type(CardType.VICTORY): victory_card_count += 1 if victory_card_count > 0: topdeck_card = dec.choose_cards( state, player=opp, num_select=1, prompt="Choose a Victory Card to topdeck.", filter_func=lambda card: card.is_type(CardType.VICTORY), optional=False ) if topdeck_card: topdeck(state, opp, topdeck_card[0], opp.hand) else: for card in opp.hand: reveal(state, opp, card)
def harbinger_fn(state, player): cards = dec.choose_cards( state, player, num_select=1, prompt="You may topdeck a card from your discard pile.", optional=True, card_container=player.discard_pile, ) if cards: topdeck(state, player, cards[0], player.discard_pile)
def poacher_fn(state, player): pileout_count = len(state.empty_piles()) if pileout_count > 0: cards = dec.choose_cards( state, player, num_select=2, prompt=f"You must discard {pileout_count} card(s).", filter_func=lambda card: card.name == "Copper", optional=False, card_container=player.hand, ) for card in cards: player_discard_card_from_hand(state, player, card)
def moneylender_fn(state, player): cards = dec.choose_cards( state, player, num_select=1, prompt="Trash a copper to gain +3 coins. Choose none to skip.", filter_func=lambda card: card.name == "Copper", optional=True, card_container=player.hand, ) if cards: trash(state, player, cards[0], player.hand) player.coins += 3
def run(self, state, player): prompt = f"Discard down to {self.num_cards_downto} cards." num_to_discard = len(player.hand) - self.num_cards_downto cards = dec.choose_cards( state=state, player=player, num_select=num_to_discard, prompt=prompt, filter_func=None, optional=False, ) for card in cards: player_discard_card_from_hand(state, player, card)
def artisan_fn(state, player): ChoosePileToGainToHandEffect( filter_func=lambda pile: (pile.card.cost <= 5) ).run(state, player) # Topdeck a card. cards = dec.choose_cards(state, player, num_select=1, prompt="Choose a card to topdeck.", filter_func=None, optional=False) if cards: topdeck(state, player, cards[0], player.hand)
def cellar_fn(state, player): chosen_cards = dec.choose_cards( state, player, num_select=len(player.hand), prompt="Discard as many cards as you would like to draw.", filter_func=None, optional=True, card_container=player.hand, ) num_discarded = len(chosen_cards) for card in chosen_cards: player_discard_card_from_hand(state, player, card) draw_into_hand(state, player, num_discarded)
def run(self, state, player): if self.optional: prompt = f"Discard up to {self.num_cards} cards." else: prompt = f"Discard exactly {self.num_cards} cards." cards = dec.choose_cards( state=state, player=player, num_select=self.num_cards, prompt=prompt, filter_func=self.filter_func, optional=self.optional, ) for card in cards: player_discard_card_from_hand(state, player, card)
def mine_fn(state, player): trashed_card = dec.choose_cards( state, player, num_select=1, prompt="Choose a Treasure to upgrade.", filter_func=lambda card: card.is_type(CardType.TREASURE), optional=True, card_container=player.hand, ) if trashed_card: trashed_card = trashed_card[0] card_cost = trashed_card.cost player_trash_card_from_hand(state, player, trashed_card) ChoosePileToGainToHandEffect( filter_func=lambda pile: pile.card.is_type(CardType.TREASURE) and pile.card.cost <= card_cost + 3 ).run(state, player)
def throne_fn(state, player): cards = dec.choose_cards( state, player, num_select=1, prompt="Select a card to play twice.", filter_func=lambda _card: _card.is_type(CardType.ACTION), optional=True, card_container=player.hand, ) if cards: card = cards[0] # Refactor the moving of one container to another. card_idx = player.hand.index(card) player.hand.pop(card_idx) player.play_area.append(card) play_inplace(state, player, card) play_inplace(state, player, card)
def bandit_attack_fn(state, player): # Attack fn for opp in state.other_players(player): if opp.immune_to_attack: opp.immune_to_attack=False continue top_two_cards = draw(state, opp, 2, draw_event=False) treasures = [] non_treasures = [] for card in top_two_cards: if card.is_type(CardType.TREASURE) and card.name != "Copper": treasures.append(card) else: non_treasures.append(card) # If there are two treasures: if len(treasures) == 2: cards = dec.choose_cards( state=state, player=opp, num_select=1, prompt="Select a card to trash from enemy Bandit.", filter_func=None, optional=False, card_container=treasures, ) trash(state, opp, cards[0], treasures) discard(state, opp, treasures[0], treasures) assert (len(treasures) == 0) elif len(treasures) == 1: trash(state, player, treasures[0], treasures) assert (len(treasures) == 0) for card in non_treasures.copy(): discard(state, opp, card, non_treasures)
def run(self, state, player): cards = dec.choose_cards( state=state, player=player, num_select=1, prompt=f"Choose a card to trash.", filter_func=None, optional=False ) assert (len(cards) == 1) trashed_card = cards[0] player_trash_card_from_hand(state, player, trashed_card) filter_function = lambda pile: pile.card.cost <= trashed_card.cost + self.add_cost if self.gain_exact_cost: filter_function = lambda pile: pile.card.cost == trashed_card.cost + self.add_cost ChoosePileToGainEffect( filter_func=filter_function ).run(state, player)