def test_Militia(self): tu.print_test_header("test Militia") player2_discard_future = gen.Future() player3_discard_future = gen.Future() select_mock2 = unittest.mock.MagicMock(return_value=player2_discard_future) select_mock3 = unittest.mock.MagicMock(return_value=player3_discard_future) discard_mock2 =unittest.mock.Mock() discard_mock3 =unittest.mock.Mock() self.player2.select = select_mock2 self.player3.select = select_mock3 self.player2.discard = gen.coroutine(discard_mock2) self.player3.discard = gen.coroutine(discard_mock3) base.Militia(self.game, self.player1).play() self.assertTrue(select_mock2.called) self.assertTrue(select_mock3.called) select_mock2.assert_called_with(unittest.mock.ANY, unittest.mock.ANY, crd.card_list_to_titles(self.player2.hand.card_array()), unittest.mock.ANY) player2_selection = crd.card_list_to_titles(self.player2.hand.card_array())[:2] player2_discard_future.set_result(player2_selection) yield gen.moment discard_mock2.assert_called_once_with(player2_selection, self.player2.discard_pile) self.assertTrue(self.player1.last_mode["mode"] == "wait") player3_selection = ["Copper", "Copper"] player3_discard_future.set_result(player3_selection) yield gen.moment discard_mock3.assert_called_once_with(player3_selection, self.player3.discard_pile)
def fire(self, player): if crd.AttackCard.fire(self, player): revealed_cards = [player.topdeck(), player.topdeck()] revealed_cards = [x for x in revealed_cards if x is not None] if not revealed_cards: self.game.announce(player.name_string() + " has no cards to Oracle.") yield self.get_next(player) return reveal_string = " and ".join( crd.card_list_log_strings(revealed_cards)) revealed_cards_titles = crd.card_list_to_titles(revealed_cards) selection = yield self.played_by.select( 1, 1, ["discard", "keep"], "{} reveals {}".format(player.name, " and ".join(revealed_cards_titles))) if selection[0] == "discard": self.game.announce("{} discards {} from {}'s deck".format( self.played_by.name_string(), reveal_string, player.name_string())) yield player.discard_floating(revealed_cards) else: player.deck += revealed_cards player.update_deck_size() self.game.announce("{} leaves {} on {}'s deck".format( self.played_by.name_string(), reveal_string, player.name_string())) yield self.get_next(player)
def fire(self, player): if crd.AttackCard.fire(self, player): revealed_cards = [player.topdeck(), player.topdeck()] if not any(revealed_cards): self.game.announce(player.name_string() + " has no cards to Thieve.") yield crd.AttackCard.get_next(self, player) return revealed_treasure = [x for x in revealed_cards if "Treasure" in x.type] self.game.announce(player.name_string() + " revealed " + ", ".join([x.log_string() for x in revealed_cards])) if len(revealed_treasure) > 0: if len(revealed_treasure) == 1 or revealed_treasure[0].title == revealed_treasure[1].title: self.game.trash_pile.append(revealed_treasure[0]) self.game.update_trash_pile() if revealed_cards[0] == revealed_treasure[0]: yield player.discard_floating(revealed_cards[1]) else: yield player.discard_floating(revealed_cards[0]) self.game.announce(player.name_string() + " trashes " + revealed_treasure[0].log_string()) steal_trashed = yield self.played_by.select(1, 1, ["Yes", "No"], "Gain " + revealed_treasure[0].title + "?") yield self.post_select_gain(steal_trashed, player, revealed_treasure[0].title) else: select_trash = yield self.played_by.select(1, 1, crd.card_list_to_titles(revealed_treasure), "Choose " + player.name + "'s Treasure to trash") yield self.post_select_trash(select_trash, player, revealed_treasure) else: #if no treasure, add the revealed cards to the discard yield player.discard_floating(revealed_cards) yield crd.AttackCard.get_next(self, player)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), 'select a card to develop') if selection: self.played_by.update_resources() yield self.played_by.discard(selection, self.game.trash_pile) card_trashed = self.game.card_from_title(selection[0]) self.game.announce(self.played_by.name_string() + ' trashes ' + card_trashed.log_string()) self.game.announce('-- gaining a card costing one more than ' + card_trashed.log_string()) gain_plus_one = yield self.played_by.select_from_supply( 'Select a card costing exactly one more than ' + card_trashed.title, lambda x: x.get_price() == card_trashed.get_price() + 1) if gain_plus_one: yield self.played_by.gain(gain_plus_one[0]) self.game.announce('-- gaining a card costing one less than ' + card_trashed.log_string()) gain_minus_one = yield self.played_by.select_from_supply( 'Select a card costing exactly one less than ' + card_trashed.title, lambda x: x.get_price() == card_trashed.get_price() - 1) if gain_minus_one: yield self.played_by.gain(gain_minus_one[0]) crd.Card.on_finished(self, False, False) else: crd.Card.on_finished(self)
def fire(self, player): # need to know which card was passed to them so we can know which card to NOT show user and remove from card_array() card = player.hand.extract(self.passed_card) player.opponents_wait("to pass") im_passing = yield player.select(1, 1, crd.card_list_to_titles(player.hand.card_array()), "Select a card to pass to player on your left") # add back card to hand after displaying cards to pass selection if card is not None: player.hand.add(card) left_opponent = player.get_left_opponent() player.announce_self("-- you pass {}".format(self.game.log_string_from_title(im_passing[0]) if im_passing else "nothing")) # logging what we received after we pass our card if self.passed_card != "": player.announce_self("-- you received " + self.game.log_string_from_title(self.passed_card)) if im_passing: self.passed_card = im_passing[0] card = player.hand.extract(im_passing[0]) card.played_by = left_opponent left_opponent.hand.add(card) player.update_hand() # if we are last, update the first person's receive log if left_opponent == self.played_by: self.played_by.announce_self("-- you received " + self.game.log_string_from_title(im_passing[0])) self.played_by.update_hand() yield self.get_next(player)
def fire(self, player): if crd.AttackCard.fire(self, player): player.opponents_wait("to choose", True) selection = yield player.select( 1, 1, ["Discard 2 cards", "Gain a Curse"], "Choose one:") if selection[0] == 'Gain a Curse': yield player.gain_to_hand('Curse') else: discard_selection = player.hand.auto_select(2, True) if discard_selection: yield player.discard(discard_selection, player.discard_pile) self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards") elif len(player.hand) > 0: player.opponents_wait("to discard", locked=False) discard_selection = yield player.select( 2, 2, crd.card_list_to_titles(player.hand.card_array()), "Discard two cards from hand") self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards") yield player.discard(discard_selection, player.discard_pile) player.update_wait(True) for i in self.game.players: if not i.is_waiting(): i.update_mode() yield crd.AttackCard.get_next(self, player)
def end_turn(self): self.phase = "cleanup" yield self.discard(crd.card_list_to_titles(self.hand.card_array()), self.discard_pile) # cleanup before game ends unique_cards_played = {} for x in self.played_cards: unique_cards_played[x.title] = x # only call cleanup function once for each card even if a card was played multiple times for card_played in unique_cards_played.values(): yield gen.maybe_future(card_played.cleanup()) self.discard_pile = self.discard_pile + self.played_cards self.played_cards = [] self.waiter.remove_afk_timer() if self.game.detect_end(): return self.actions = 0 self.buys = 0 self.balance = 0 self.played_inclusive = [] self.has_bought_cards = False self.bought_cards = [] self.banned = [] self.draw(self.hand_size) self.game.reset_prices() self.update_discard_size() self.update_deck_size() self.phase = None yield self.game.change_turn()
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select( 1, 1, ["+$2", "+2 Cards", "Trash 2 cards from hand"], "Choose One:") if "+$2" in selection: self.played_by.balance += 2 self.game.announce("-- gaining +$2") crd.Card.on_finished(self, False) elif "+2 Cards" in selection: drawn = self.played_by.draw(2) self.game.announce("-- drawing " + drawn) crd.Card.on_finished(self) elif "Trash 2 cards from hand" in selection: self.game.announce("-- choosing to trash 2 cards from hand") if len(self.played_by.hand ) > 2 and not self.played_by.hand.is_homogeneous(): to_trash = yield self.played_by.select( 2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to trash") yield self.trash_select(to_trash) else: card_selection = self.played_by.hand.auto_select(2, True) yield self.trash_select(card_selection)
def play(self, skip=False): crd.Card.play(self, skip) action_cards = self.played_by.hand.get_cards_by_type("Action") self.played_by.update_resources() selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(action_cards), "select card for Throne Room") if not selection: self.game.announce(" -- but has no action cards") crd.Card.on_finished(self, False, False) else: selected_card = self.played_by.hand.extract(selection[0]) throne_room_str = self.played_by.name_string() + " " + self.log_string(True) + " " + selected_card.log_string() on_duration = "Duration" in selected_card.type if "Duration" in selected_card.type: if self not in self.played_by.durations: self.played_by.played_cards.pop() self.played_by.durations.append(self) self.played_by.durations.append(selected_card) self.played_by.duration_cbs.append(lambda x=selected_card : self.active_duration(x)) self.game.update_duration_mat() else: self.played_by.played_cards.append(selected_card) for i in range(0, 2): self.game.announce(throne_room_str) yield gen.maybe_future(selected_card.play(True)) self.played_by.update_resources() self.played_by.update_hand() crd.Card.on_finished(self, False, False)
def attack(self): for i in self.played_by.get_opponents(): if not crd.AttackCard.is_blocked(self, i): i_victory_cards = i.hand.get_cards_by_type("Victory") if len(i_victory_cards) == 0: self.game.announce(i.name_string() + " has no Victory cards & reveals " + i.hand.reveal_string()) elif len(set(map(lambda x: x.title, i_victory_cards))) == 1: self.game.announce(i.name_string() + " puts " + i_victory_cards[0].log_string() + " back on top of the deck") yield i.discard([i_victory_cards[0].title], i.deck) else: self.played_by.wait("to choose a Victory card to put back", i) order_selection = yield i.select( 1, 1, crd.card_list_to_titles(i_victory_cards), "select Victory card to put back") yield i.discard(order_selection, i.deck) self.game.announce(i.name_string() + " puts " + self.game.card_from_title( order_selection[0]).log_string() + " back on top of the deck") if not self.played_by.is_waiting(): crd.Card.on_finished(self, False, False) if not self.played_by.is_waiting(): crd.Card.on_finished(self, False, False)
def fire(self, player): # need to know which card was passed to them so we can know which card to NOT show user and remove from card_array() card = player.hand.extract(self.passed_card) player.opponents_wait("to pass") im_passing = yield player.select( 1, 1, crd.card_list_to_titles(player.hand.card_array()), "Select a card to pass to player on your left") # add back card to hand after displaying cards to pass selection if card is not None: player.hand.add(card) left_opponent = player.get_left_opponent() player.announce_self("-- you pass {}".format( self.game.log_string_from_title(im_passing[0] ) if im_passing else "nothing")) # logging what we received after we pass our card if self.passed_card != "": player.announce_self( "-- you received " + self.game.log_string_from_title(self.passed_card)) if im_passing: self.passed_card = im_passing[0] card = player.hand.extract(im_passing[0]) card.played_by = left_opponent left_opponent.hand.add(card) player.update_hand() # if we are last, update the first person's receive log if left_opponent == self.played_by: self.played_by.announce_self( "-- you received " + self.game.log_string_from_title(im_passing[0])) self.played_by.update_hand() yield self.get_next(player)
def play(self, skip=False): crd.Card.play(self, skip) action_cards = self.played_by.hand.get_cards_by_type("Action") self.played_by.update_resources() selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(action_cards), "select card for Throne Room") if not selection: self.game.announce(" -- but has no action cards") crd.Card.on_finished(self, False, False) else: selected_card = self.played_by.hand.extract(selection[0]) throne_room_str = self.played_by.name_string( ) + " " + self.log_string(True) + " " + selected_card.log_string() on_duration = "Duration" in selected_card.type if "Duration" in selected_card.type: if self not in self.played_by.durations: self.played_by.played_cards.pop() self.played_by.durations.append(self) self.played_by.durations.append(selected_card) self.played_by.duration_cbs.append( lambda x=selected_card: self.active_duration(x)) self.game.update_duration_mat() else: self.played_by.played_cards.append(selected_card) for i in range(0, 2): self.game.announce(throne_room_str) yield gen.maybe_future(selected_card.play(True)) self.played_by.update_resources() self.played_by.update_hand() crd.Card.on_finished(self, False, False)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.wait_modeless("", self.played_by, True) forge_selection = yield self.played_by.select( None, len(self.played_by.hand.card_array()), crd.card_list_to_titles(self.played_by.hand.card_array()), "Trash any number of cards") trash_sum = 0 if forge_selection: for card in forge_selection: trash_card = self.played_by.hand.extract(card) trash_sum += trash_card.get_price() self.game.trash_pile.append(trash_card) announce_string = list( map(lambda x: self.game.card_from_title(x).log_string(), forge_selection)) self.game.announce(self.played_by.name_string() + " trashes " + ", ".join(announce_string) + " to gain a card with cost " + str(trash_sum)) else: self.game.announce( "{} trashes nothing to gain a card with cost 0".format( self.played_by.name_string())) self.game.update_trash_pile() gained = yield self.played_by.select_from_supply( "Gain a card from the forge", lambda x: x.get_price() == trash_sum, optional=False) if gained: yield self.played_by.gain(gained[0]) self.played_by.update_wait(True) crd.Card.on_finished(self)
def on_gain(self): action_cards_in_discard = [ x for x in self.played_by.discard_pile if "Action" in x.type ] to_reshuffle = yield self.played_by.select( None, len(action_cards_in_discard), crd.card_list_to_titles(action_cards_in_discard), "Select action cards from discard to reshuffle into your deck") revealed = ", ".join( map(lambda x: self.game.log_string_from_title(x), to_reshuffle)) if to_reshuffle: self.game.announce( "-- removing {} from their discard to their deck".format( revealed)) for i in to_reshuffle: for c in self.played_by.discard_pile: if c.title == i: self.played_by.discard_pile.remove(c) self.played_by.deck.append(c) break self.played_by.update_deck_size() self.played_by.update_discard_size() random.shuffle(self.played_by.deck) self.game.announce("<i>{} shuffles their deck</i>".format( self.played_by.name_string()))
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select(None, None, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to discard") yield self.played_by.discard(selection, self.played_by.discard_pile) self.played_by.balance += len(selection) self.game.announce(self.played_by.name_string() + " discarding " + str(len(selection)) + " gaining +$" + str(len(selection)) + ".") crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) auto_select = self.played_by.hand.auto_select(2, True) if auto_select: self.post_select(auto_select) else: selection = yield self.played_by.select(2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "Trash 2 cards from your hand") yield self.post_select(selection)
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(5) self.game.announce("-- drawing {}".format(drawn)) to_discard = yield self.played_by.select( 3, 3, crd.card_list_to_titles(self.played_by.hand.card_array()), "Discard 3 cards") self.game.announce("-- discarding {} cards".format(len(to_discard))) yield self.played_by.discard(to_discard, self.played_by.discard_pile) crd.Card.on_finished(self, True, False)
def attack(self): for i in self.played_by.get_opponents(): if not crd.AttackCard.is_blocked(self, i): if len(i.hand) >= 5: self.game.announce("-- " + i.name_string() + " discards hand and draws 4") yield i.discard(crd.card_list_to_titles(i.hand.card_array()), i.discard_pile) i.draw(4) else: self.game.announce("-- " + i.name_string() + " has less than 5 cards in hand") crd.Card.on_finished(self, False, False)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.actions += 2 drawn = self.played_by.draw(2) self.game.announce("-- gaining 2 actions and drawing {}".format(drawn)) to_discard = yield self.played_by.select( 2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "Discard 2 cards") yield self.played_by.discard(to_discard, self.played_by.discard_pile) self.game.announce("-- discarding {} cards".format(len(to_discard))) crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) auto_select = self.played_by.hand.auto_select(2, True) if auto_select: self.post_select(auto_select) else: selection = yield self.played_by.select( 2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "Trash 2 cards from your hand") yield self.post_select(selection)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select(None, 4, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to trash") selection_string = list(map(lambda x: self.game.card_from_title(x).log_string(), selection)) if len(selection_string) > 0: self.game.announce(self.played_by.name_string() + " trashes " + ", ".join(selection_string)) else: self.game.announce(self.played_by.name_string() + " trashes nothing") yield self.played_by.discard(selection, self.game.trash_pile) crd.Card.on_finished(self, True, False, False)
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(3) self.played_by.actions += 1 self.game.announce("-- gaining 1 action and drawing " + drawn) to_discard = yield self.played_by.select(3, 3, crd.card_list_to_titles(self.played_by.hand.card_array()), "Discard 3 cards") yield self.played_by.discard(to_discard, self.played_by.discard_pile) self.game.announce("-- discarding {} cards".format(len(to_discard))) crd.Card.on_finished(self)
def select_from_supply(self, msg, constraint=lambda x: True, allow_empty=False, optional=False): avail = self.game.supply.has_selectable(constraint, allow_empty) if allow_empty or avail: self.write_json(command="updateMode", mode="selectSupply", msg=msg, select_from=crd.card_list_to_titles(avail), optional=optional) future = tornado.concurrent.Future() self.cb = future return future else: self.game.announce("-- but there is nothing available in supply") return []
def react(self): selection = yield self.played_by.select(1, 1, ["Reveal", "Hide"], "Reveal " + self.title + " to draw 2 and place 2 back to deck?") if selection[0] == "Reveal": self.game.announce(self.played_by.name_string() + " reveals " + self.log_string()) drawn_cards = self.played_by.draw(2, False) put_back = yield self.played_by.select(2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "Put two cards to the top of your deck (#1 is on top)", True) if put_back: drawn_cards = yield self.post_react_draw_select(put_back, drawn_cards) return drawn_cards
def get_next(self, player): next_player_index = (self.game.players.index(player) + 1) % len(self.game.players) if self.game.players[next_player_index] != self.played_by: yield self.fire(self.game.players[next_player_index]) else: #everyone finished passing, trash trash_selection = yield self.played_by.select(None, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Select a card to trash") if len(trash_selection) > 0: self.game.announce("-- " + self.played_by.name_string() + " trashes " + self.played_by.hand.get_card(trash_selection[0]).log_string()) yield self.played_by.discard([trash_selection[0]], self.game.trash_pile) self.passed_card = "" crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(3) self.game.announce("-- drawing " + drawn) self.played_by.update_resources() selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to put back on top of your deck.") if selection: self.game.announce("-- " + self.game.log_string_from_title(selection[0]) + " is placed on top of the deck.") yield self.played_by.discard(selection, self.played_by.deck) self.played_by.update_deck_size() crd.Card.on_finished(self, True, False)
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(3) self.played_by.actions += 1 self.game.announce("-- gaining 1 action and drawing " + drawn) to_discard = yield self.played_by.select( 3, 3, crd.card_list_to_titles(self.played_by.hand.card_array()), "Discard 3 cards") yield self.played_by.discard(to_discard, self.played_by.discard_pile) self.game.announce("-- discarding {} cards".format(len(to_discard))) crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select( None, None, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to discard") yield self.played_by.discard(selection, self.played_by.discard_pile) self.played_by.balance += len(selection) self.game.announce(self.played_by.name_string() + " discarding " + str(len(selection)) + " gaining +$" + str(len(selection)) + ".") crd.Card.on_finished(self)
def discard_2_for_1(self, selection, player): if selection[0] == "Yes": discard_selection = yield player.select(min(len(player.hand.card_array()), 2), 2, crd.card_list_to_titles(player.hand.card_array()), "Discard up to 2") yield player.discard(discard_selection, player.discard_pile) drawn = "nothing" if len(discard_selection) >= 2: drawn = player.draw(1) self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards and draws " + drawn) player.update_wait(True) if not self.played_by.is_waiting(): self.played_by.update_mode() crd.Card.on_finished(self, False, True)
def play(self, skip=False): # checks to see if Tactician is the only card in hand, if so call duration super play(), otherwise call card super play() if len(self.played_by.hand) > 1: crd.Duration.play(self, skip) yield self.played_by.discard(crd.card_list_to_titles(self.played_by.hand.card_array()), self.played_by.discard_pile) self.game.announce("-- discarding their hand") self.duration = self.active_duration else: crd.Card.play(self, skip) self.game.announce("-- but there was nothing to discard") self.duration = lambda : None crd.Duration.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.balance += 3 self.game.announce("-- gaining +$3") top_select = self.played_by.hand.auto_select(1, False) if top_select: yield self.post_select(top_select) else: selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Select card to put back on top of your deck") yield self.post_select(selection)
def play(self, skip=False): crd.Card.play(self, skip) mat_value = len(self.game.mat["Trade Route Mat"]) self.played_by.balance += mat_value self.played_by.buys += 1 self.game.announce("-- gaining a buy and $" + str(mat_value)) selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to trash") if selection: trashed = self.played_by.hand.extract(selection[0]) self.game.announce("-- trashing " + trashed.log_string()) self.game.trash_pile.append(trashed) self.game.update_trash_pile() crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.actions += 1 self.played_by.draw(1) self.game.announce("-- gaining +1 action and drawing a card.") auto_select = self.played_by.hand.auto_select(1, False) if auto_select: yield self.trash_select(auto_select) else: selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to trash:") yield self.trash_select(selection)
def fire(self, player, from_buy=False): if crd.AttackCard.fire(self, player) or from_buy: revealed_cards = [player.topdeck(), player.topdeck()] if not any(revealed_cards): self.game.announce(player.name_string() + " has no cards to Noble Brigand.") yield crd.AttackCard.get_next(self, player) return revealed_cards_titles = crd.card_list_to_titles(revealed_cards) reveal_string = " & ".join( crd.card_list_log_strings(revealed_cards)) revealed_treasures = [ x for x in revealed_cards if "Treasure" in x.type ] revealed_gold_or_silver = [ x for x in revealed_cards_titles if x == "Gold" or x == "Silver" ] if revealed_gold_or_silver: self.game.announce("-- {} reveals {}".format( player.name_string(), reveal_string)) trash_selection = yield self.played_by.select( None, 1, list(set(revealed_gold_or_silver)), "Trash and gain {}'s revealed Gold or Silver?".format( player.name)) if trash_selection: self.game.announce( "-- {} trashes {} from {}'s deck".format( self.played_by.name_string(), self.game.log_string_from_title( trash_selection[0]), player.name_string())) to_trash = revealed_cards.pop(0) if revealed_cards[ 0].title == trash_selection[0] else revealed_cards.pop( 1) yield self.played_by.gain( to_trash.title, from_supply=False, custom_announce="-- {} gains {}".format( self.played_by.name_string(), to_trash.log_string())) else: self.game.announce("-- {} reveals and discards {}".format( player.name_string(), reveal_string)) yield player.discard_floating(revealed_cards) if not revealed_treasures: yield player.gain("Copper") if from_buy: yield self.get_next(player) yield crd.AttackCard.get_next(self, player)
def attack(self): for i in self.played_by.get_opponents(): if not crd.AttackCard.is_blocked(self, i): if len(i.hand) >= 5: self.game.announce("-- " + i.name_string() + " discards hand and draws 4") yield i.discard( crd.card_list_to_titles(i.hand.card_array()), i.discard_pile) i.draw(4) else: self.game.announce("-- " + i.name_string() + " has less than 5 cards in hand") crd.Card.on_finished(self, False, False)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.actions += 1 selection = yield self.played_by.select(None, None, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to discard") if len(selection) > 0: self.played_by.announce_self("-- you discard " + " , ".join(list(map(lambda x: self.game.card_from_title(x).log_string(), selection)))) else: self.played_by.announce_self("-- you discard nothing") self.played_by.announce_opponents("-- discarding and drawing " + str(len(selection)) + " cards") yield self.played_by.discard(selection, self.played_by.discard_pile) self.played_by.draw(len(selection)) crd.Card.on_finished(self)
def test_Militia(self): tu.print_test_header("test Militia") player2_discard_future = gen.Future() player3_discard_future = gen.Future() select_mock2 = unittest.mock.MagicMock( return_value=player2_discard_future) select_mock3 = unittest.mock.MagicMock( return_value=player3_discard_future) discard_mock2 = unittest.mock.Mock() discard_mock3 = unittest.mock.Mock() self.player2.select = select_mock2 self.player3.select = select_mock3 self.player2.discard = gen.coroutine(discard_mock2) self.player3.discard = gen.coroutine(discard_mock3) base.Militia(self.game, self.player1).play() self.assertTrue(select_mock2.called) self.assertTrue(select_mock3.called) select_mock2.assert_called_with( unittest.mock.ANY, unittest.mock.ANY, crd.card_list_to_titles(self.player2.hand.card_array()), unittest.mock.ANY) player2_selection = crd.card_list_to_titles( self.player2.hand.card_array())[:2] player2_discard_future.set_result(player2_selection) yield gen.moment discard_mock2.assert_called_once_with(player2_selection, self.player2.discard_pile) self.assertTrue(self.player1.last_mode["mode"] == "wait") player3_selection = ["Copper", "Copper"] player3_discard_future.set_result(player3_selection) yield gen.moment discard_mock3.assert_called_once_with(player3_selection, self.player3.discard_pile)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.actions += 1 self.played_by.update_resources() self.game.announce("-- gaining 1 action") selection = yield self.played_by.select(1, 1, ["+$2", "discard hand and draw 4 cards"], "Choose one:") if "+$2" in selection[0]: self.played_by.balance += 2 self.game.announce("-- gaining $2") crd.Card.on_finished(self, False, True) else: yield self.played_by.discard(crd.card_list_to_titles(self.played_by.hand.card_array()), self.played_by.discard_pile) drawn = self.played_by.draw(4) self.game.announce("-- drawing " + drawn) yield crd.AttackCard.check_reactions(self, self.played_by.get_opponents())
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.buys += 1 self.game.announce("-- gaining +1 Buy") selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Select a card to salvage") selected_card = self.game.card_from_title(selection[0]) selected_card_cost = selected_card.get_price() yield self.played_by.discard(selection, self.game.trash_pile) self.played_by.balance += selected_card_cost self.game.announce('-- trashing {}, gaining +${}'.format(selected_card.log_string(), selected_card_cost)) crd.Card.on_finished(self)
def get_next(self, player): next_player_index = (self.game.players.index(player) + 1) % len(self.game.players) next_player = self.game.players[next_player_index] if next_player == self.played_by: crd.Card.on_finished(self) else: selection = yield next_player.select(1, 1, crd.card_list_to_titles(next_player.hand.card_array()) + ["None"], "Choose a card to trash") if selection[0] != "None": trash = next_player.hand.extract(selection[0]) self.game.trash_pile.append(trash) self.game.update_trash_pile() next_player.update_hand() self.game.announce("-- " + next_player.name + " trashes " + trash.log_string()) yield self.get_next(next_player)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.actions += 1 self.played_by.draw(1) self.game.announce("-- gaining +1 action and drawing a card.") auto_select = self.played_by.hand.auto_select(1, False) if auto_select: yield self.trash_select(auto_select) else: selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to trash:") yield self.trash_select(selection)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "select card to expand") if selection: yield self.played_by.discard(selection, self.game.trash_pile) card_trashed = self.game.card_from_title(selection[0]) self.game.announce(self.played_by.name_string() + " trashes " + card_trashed.log_string()) selected = yield self.played_by.select_from_supply("Choose the expanded card", lambda x : x.get_price() <= card_trashed.get_price() + 3) if selected: yield self.played_by.gain(selected[0]) crd.Card.on_finished(self, False, False) else: self.game.announce("-- but has nothing to expand.") self.played_by.update_resources()
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(3) self.game.announce("-- drawing " + drawn) self.played_by.update_resources() selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to put back on top of your deck.") if selection: self.game.announce("-- " + self.game.log_string_from_title(selection[0]) + " is placed on top of the deck.") yield self.played_by.discard(selection, self.played_by.deck) self.played_by.update_deck_size() crd.Card.on_finished(self, True, False)
def on_buy(self): selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "select card to trash") if selection: yield self.played_by.discard(selection, self.game.trash_pile) card_trashed = self.game.card_from_title(selection[0]) self.game.announce(self.played_by.name_string() + " trashes " + card_trashed.log_string()) selected = yield self.played_by.select_from_supply( "Choose the a card to gain", lambda x: x.get_price() == card_trashed.get_price() + 2) if selected: yield self.played_by.gain(selected[0]) crd.Card.on_finished(self, False, False)
def play(self, skip=False): # checks to see if Tactician is the only card in hand, if so call duration super play(), otherwise call card super play() if len(self.played_by.hand) > 1: crd.Duration.play(self, skip) yield self.played_by.discard( crd.card_list_to_titles(self.played_by.hand.card_array()), self.played_by.discard_pile) self.game.announce("-- discarding their hand") self.duration = self.active_duration else: crd.Card.play(self, skip) self.game.announce("-- but there was nothing to discard") self.duration = lambda: None crd.Duration.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(1) self.played_by.actions += 1 self.played_by.balance += 1 self.played_by.update_resources() self.game.announce( "-- drawing {} and gaining +1 action, +$1".format(drawn)) selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), 'Select a card to discard') yield self.played_by.discard(selection, self.played_by.discard_pile) self.game.announce("-- discarding {}".format( self.game.log_string_from_title(selection[0]))) crd.Card.on_finished(self, False, False)
def play(self, skip=False): crd.Card.play(self, skip) mat_value = len(self.game.mat["Trade Route Mat"]) self.played_by.balance += mat_value self.played_by.buys += 1 self.game.announce("-- gaining a buy and $" + str(mat_value)) selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to trash") if selection: trashed = self.played_by.hand.extract(selection[0]) self.game.announce("-- trashing " + trashed.log_string()) self.game.trash_pile.append(trashed) self.game.update_trash_pile() crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "select card to remodel") if selection: self.played_by.update_resources() yield self.played_by.discard(selection, self.game.trash_pile) card_trashed = self.game.card_from_title(selection[0]) self.game.announce(self.played_by.name_string() + " trashes " + card_trashed.log_string()) gain_list = yield self.played_by.select_from_supply("Select a card to gain from Remodel", lambda x : x.get_price() <= card_trashed.get_price() + 2) if gain_list: yield self.played_by.gain(gain_list[0]) crd.Card.on_finished(self, False, False) else: crd.Card.on_finished(self)
def play(self, skip=False): crd.Card.play(self, skip) selection = yield self.played_by.select( None, 4, crd.card_list_to_titles(self.played_by.hand.card_array()), "select cards to trash") selection_string = list( map(lambda x: self.game.card_from_title(x).log_string(), selection)) if len(selection_string) > 0: self.game.announce(self.played_by.name_string() + " trashes " + ", ".join(selection_string)) else: self.game.announce(self.played_by.name_string() + " trashes nothing") yield self.played_by.discard(selection, self.game.trash_pile) crd.Card.on_finished(self, True, False, False)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.buys += 1 self.game.announce("-- gaining +1 Buy") selection = yield self.played_by.select( 1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Select a card to salvage") selected_card = self.game.card_from_title(selection[0]) selected_card_cost = selected_card.get_price() yield self.played_by.discard(selection, self.game.trash_pile) self.played_by.balance += selected_card_cost self.game.announce('-- trashing {}, gaining +${}'.format( selected_card.log_string(), selected_card_cost)) crd.Card.on_finished(self)
def discard_2_for_1(self, selection, player): if selection[0] == "Yes": discard_selection = yield player.select( min(len(player.hand.card_array()), 2), 2, crd.card_list_to_titles(player.hand.card_array()), "Discard up to 2") yield player.discard(discard_selection, player.discard_pile) drawn = "nothing" if len(discard_selection) >= 2: drawn = player.draw(1) self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards and draws " + drawn) player.update_wait(True) if not self.played_by.is_waiting(): self.played_by.update_mode() crd.Card.on_finished(self, False, True)
def react(self): selection = yield self.played_by.select( 1, 1, ["Reveal", "Hide"], "Reveal " + self.title + " to draw 2 and place 2 back to deck?") if selection[0] == "Reveal": self.game.announce(self.played_by.name_string() + " reveals " + self.log_string()) drawn_cards = self.played_by.draw(2, False) put_back = yield self.played_by.select( 2, 2, crd.card_list_to_titles(self.played_by.hand.card_array()), "Put two cards to the top of your deck (#1 is on top)", True) if put_back: drawn_cards = yield self.post_react_draw_select( put_back, drawn_cards) return drawn_cards
def play(self, skip=False): crd.Card.play(self, skip) drawn = self.played_by.draw(2) self.game.announce("-- drawing " + drawn) selection = yield self.played_by.select(None, len(self.played_by.hand.card_array()), crd.card_list_to_titles(self.played_by.hand.card_array()), "Discard any number of cards") yield self.played_by.discard(selection, self.played_by.discard_pile) self.played_by.balance += len(selection) self.game.announce("-- discarding " + str(len(selection)) + ", gaining +$" + str(len(selection))) self.played_by.wait_many("to discard", self.played_by.get_opponents(), True) #ask opponents to discard 2 to draw 1 opponents = self.played_by.get_opponents() yield crd.parallel_selects(map(lambda x: x.select(1, 1, ["Yes", "No"], "Discard 2 cards to draw 1?"), opponents), opponents, self.discard_2_for_1)
def play(self, skip=False): crd.Card.play(self, skip) treasure_cards = self.played_by.hand.get_cards_by_type("Treasure") if len(treasure_cards) > 0: selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(treasure_cards), "select treasure to trash") if selection: yield self.played_by.discard(selection, self.game.trash_pile) card_trashed = self.game.card_from_title(selection[0]) self.game.announce(self.played_by.name_string() + " trashes " + card_trashed.log_string()) gain_treasure = yield self.played_by.select_from_supply("Select a treasure to gain", lambda x : x.get_price() <= card_trashed.get_price() + 3 and "Treasure" in x.type) if gain_treasure: yield self.played_by.gain_to_hand(gain_treasure[0]) crd.Card.on_finished(self, False, False) else: self.game.announce("-- but has no treasure cards to trash") crd.Card.on_finished(self)
def test_Cellar(self): tu.print_test_header("test Cellar") selection_future = gen.Future() select_mock = unittest.mock.MagicMock(return_value=selection_future) draw_mock = unittest.mock.Mock() discard_mock = unittest.mock.Mock() self.player1.select = select_mock self.player1.draw = draw_mock self.player1.discard = gen.coroutine(discard_mock) base.Cellar(self.game, self.player1).play() self.assertTrue(select_mock.called) to_discard = crd.card_list_to_titles(self.player1.hand.card_array()) selection_future.set_result(to_discard) yield gen.moment discard_mock.assert_any_call(to_discard, self.player1.discard_pile) draw_mock.assert_called_once_with(5)
def attack(self): for i in self.played_by.get_opponents(): if not crd.AttackCard.is_blocked(self, i): i_victory_cards = i.hand.get_cards_by_type("Victory") if len(i_victory_cards) == 0: self.game.announce(i.name_string() + " has no Victory cards & reveals " + i.hand.reveal_string()) elif len(set(map(lambda x: x.title, i_victory_cards))) == 1: self.game.announce(i.name_string() + " puts " + i_victory_cards[0].log_string() + " back on top of the deck") yield i.discard([i_victory_cards[0].title], i.deck) else: self.played_by.wait("to choose a Victory card to put back", i) order_selection = yield i.select(1, 1, crd.card_list_to_titles(i_victory_cards), "select Victory card to put back") yield i.discard(order_selection, i.deck) self.game.announce(i.name_string() + " puts " + self.game.card_from_title(order_selection[0]).log_string() + " back on top of the deck") if not self.played_by.is_waiting(): crd.Card.on_finished(self, False, False) if not self.played_by.is_waiting(): crd.Card.on_finished(self, False, False)
def play(self, skip=False): crd.Card.play(self, skip) self.played_by.balance += 1 self.played_by.vp += 1 self.game.announce("-- gaining +$1 and +1 VP") selection = yield self.played_by.select(1, 1, crd.card_list_to_titles(self.played_by.hand.card_array()), "Choose a card to trash") if selection: trash = self.played_by.hand.extract(selection[0]) half_vp = math.floor(trash.get_price() / 2) self.played_by.vp += half_vp self.game.trash_pile.append(trash) self.game.update_trash_pile() self.played_by.update_hand() self.game.announce("-- trashing " + trash.log_string() + " gaining " + str(half_vp) + " VP") self.played_by.wait_many("to trash", self.played_by.get_opponents()) yield self.get_next(self.played_by)
def fire(self, player): if crd.AttackCard.fire(self, player): player.opponents_wait("to choose", True) selection = yield player.select(1, 1, ["Discard 2 cards", "Gain a Curse"], "Choose one:") if selection[0] == 'Gain a Curse': yield player.gain_to_hand('Curse') else: discard_selection = player.hand.auto_select(2, True) if discard_selection: yield player.discard(discard_selection, player.discard_pile) self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards") elif len(player.hand) > 0: player.opponents_wait("to discard", locked=False) discard_selection = yield player.select(2, 2, crd.card_list_to_titles(player.hand.card_array()), "Discard two cards from hand") self.game.announce(player.name_string() + " discards " + str(len(discard_selection)) + " cards") yield player.discard(discard_selection, player.discard_pile) player.update_wait(True) for i in self.game.players: if not i.is_waiting(): i.update_mode() yield crd.AttackCard.get_next(self, player)