def play_card(self, card): if self.game_ended: raise GameException("The game has ended") if not card.can_use(self.current_player, self): raise GameException("That card cannot be used") card_index = self.current_player.hand.index(card) self.current_player.hand.pop(card_index) self.current_player.mana -= card.mana_cost(self.current_player) self._all_cards_played.append(card) card.target = None card.current_target = None if card.targetable and card.targets: card.target = self.current_player.agent.choose_target(card.targets) self.last_card = card if card.is_minion(): card._placeholder = Minion(0, 0) index = self.current_player.agent.choose_index(card, self.current_player) self.current_player.minions.insert(index, card._placeholder) card._placeholder.index = index self.current_player.trigger("card_played", card, card_index) if not card.cancel: card.use(self.current_player, self) card.unattach() self.current_player.trigger("card_used", card) self.current_player.cards_played += 1 self.check_delayed() card.current_target = None # overload is applied regardless of counterspell, but after the card is played self.current_player.overload += card.overload
def draw(self, game): if not self.can_draw(): raise GameException("Cannot draw more than 30 cards") card = game.random_draw(self.cards, lambda c: not c.drawn) card.drawn = True self.left -= 1 return card
def __init__(self, cards, hero): if len(cards) != 30: raise GameException("Deck must have exactly 30 cards in it") self.cards = cards self.hero = hero for card in cards: card.drawn = False self.left = 30
def play_card(self, card): if self.game_ended: raise GameException("The game has ended") if not card.can_use(self.current_player, self): raise GameException("That card cannot be used") # print("PLAYER HAND: ", self.current_player.hand) # print("PLAYER CARD: ", card) if card not in self.current_player.hand: print( "\n@@@@@ ERROR IS COMING @@@@@\n@@ CARD IS NOT IN PLAYER.HAND@@\n" ) card_index = self.current_player.hand.index(card) self.current_player.hand.pop(card_index) self.current_player.mana -= card.mana_cost() self._all_cards_played.append(card) card.target = None card.current_target = None if card.targetable and card.targets: card.target = self.current_player.agent.choose_target(card.targets) self.last_card = card if card.is_minion(): card._placeholder = Minion(0, 0) index = self.current_player.agent.choose_index( card, self.current_player) for minion in self.current_player.minions[index:]: minion.index += 1 self.current_player.minions.insert(index, card._placeholder) card._placeholder.index = index card._placeholder.card = card card._placeholder.player = self.current_player self.current_player.trigger("card_played", card, card_index) if not card.cancel: card.use(self.current_player, self) card.unattach() self.current_player.trigger("card_used", card) self.current_player.cards_played += 1 self.check_delayed() card.current_target = None # overload is applied regardless of counterspell, but after the card is played self.current_player.upcoming_overload += card.overload
def put_back(self, card): for deck_card in self.cards: if deck_card == card: if not card.drawn: raise GameException("Tried to put back a card that hadn't been used yet") deck_card.drawn = False self.left += 1 return self.cards.append(card) self.left += 1
def put_back(self, card): if not card: raise TypeError("Expected a card, not None") for deck_card in self.cards: if deck_card == card: if not card.drawn: raise GameException( "Tried to put back a card that hadn't been used yet") deck_card.drawn = False self.left += 1 return card.drawn = False self.cards.append(card) self.left += 1
def use(self, player, game): """ Adds this minion to the board for the given player, if the card is able to be played. The agent for the given player will be consulted about the location on the board of the played minion, about the target for the battlecry if necessary, and to choose an option for cards with choose. This method operates in the following order: 1. Battlecry target chosen (if needed) 2. Board placement chosen 3. Minion is placed on the board 4. minion_placed event 5. Battlecry activated (if needed) 6. minion_played event 7. minion_summoned_event 8. after_added event The precise ordering of events is necessary so that various tags (Sword of Justice, Knife Juggler, etc) trigger in the correct order, and to distinguish from :meth:`summon`, which is called when a minion is played as a side effect of of card (e.g. Feral Spirit) :param hearthbreaker.game_objects.Player player: The player who wants to play this card :param hearthbreaker.game_objects.Game game: The game this card will be played in. """ from hearthbreaker.tags.status import ChangeAttack from hearthbreaker.tags.base import Buff super().use(player, game) if (len(player.minions) >= 7 and not self._placeholder) or len(player.minions) >= 8: raise GameException( "Cannot place a minion on a board with more than 7 minons on it" ) minion = self.create_minion(player) minion.card = self minion.player = player minion.game = game # TODO Add a test to make sure that this is a valid index, or things shall explode if self._placeholder: minion.index = self._placeholder.index player.minions.remove(self._placeholder) for m in player.minions[minion.index:]: m.index -= 1 else: minion.index = player.agent.choose_index(self, player) minion.add_to_board(minion.index) card_attack = self.calculate_stat(ChangeAttack, 0) if card_attack: minion.add_buff(Buff(ChangeAttack(card_attack))) player.trigger("minion_placed", minion) if self.choices: choice = player.agent.choose_option(self.choices, player) choice.do(minion) if self.combo and player.cards_played > 0: self.combo.do(minion) else: for battlecry in self.battlecry: if not battlecry.do(minion, minion): break game.check_delayed() # In case the minion has been replaced by its battlecry (e.g. Faceless Manipulator) minion = minion.replaced_by if minion.replaced_by else minion if not minion.removed: player.trigger("minion_played", minion) player.trigger("minion_summoned", minion) player.trigger("after_added", minion)