Exemple #1
0
 def trigger(self,
             minion: Minion,
             own_board: PlayerBoard,
             opposing_board: PlayerBoard,
             macaw_trigger: Optional[bool] = False):
     triggers = 2 if minion.golden else 1
     for _ in range(triggers):
         for opposing_minion in opposing_board.get_living_minions():
             opposing_minion.receive_damage(1, opposing_board)
         for friendly_minion in own_board.get_living_minions():
             friendly_minion.receive_damage(1, own_board)
Exemple #2
0
 def trigger(self,
             minion: Minion,
             own_board: PlayerBoard,
             opposing_board: PlayerBoard,
             macaw_trigger: Optional[bool] = False):
     bonus = 2 if minion.golden else 1
     for other_minion in own_board.get_living_minions():
         other_minion.add_stats(bonus, bonus)
Exemple #3
0
 def trigger(self,
             minion: Minion,
             own_board: PlayerBoard,
             opposing_board: PlayerBoard,
             macaw_trigger: Optional[bool] = False):
     iterations = 2 if minion.golden else 1
     for _ in range(iterations):
         unshielded_minions = [
             minion for minion in own_board.get_living_minions()
             if not minion.divine_shield
         ]
         if len(unshielded_minions) > 0:
             unshielded_minions[random.randint(0,
                                               len(unshielded_minions) -
                                               1)].divine_shield = True
    def check_deaths(self, attacking_player_board: PlayerBoard,
                     defending_player_board: PlayerBoard):
        """Check deaths on both sides, collect death rattles, process them and resolve consequences (immediate attacks / reborn triggers)

        Arguments:
            attacking_player_board {PlayerBoard} -- Player board of attacking player
            defending_player_board {PlayerBoard} -- Player board of defending player
        """
        # General flow of resolving death states:
        # Resolve attacker deathrattles from left to right, multiplied by baron
        #     Resolve extra attacks after each deathrattle resolves (then recursively check deaths)
        # Resolve defender deathrattles from left to right, multiplied by baron
        #     Resolve extra attacks after each deathrattle resolves (then recursively check deaths)

        # There are some DRY vibes here but for now this is fine
        attacker_dead_minions = self.set_aside_dead_minions(
            attacking_player_board, defending_player_board)
        defender_dead_minions = self.set_aside_dead_minions(
            defending_player_board, attacking_player_board)

        if len(attacker_dead_minions) == 0 and len(defender_dead_minions) == 0 \
            and len(attacking_player_board.get_immediate_attack_minions()) == 0 \
            and len(defending_player_board.get_immediate_attack_minions()) == 0:
            return

        # Resolve death rattles and 'attacks immediately' triggers. Attacker first, then defender
        # TODO: immediate attacks on defender side resolve before attacks deathrattles?
        # TODO: Is there a consistent order to deathrattles??
        for minion in attacker_dead_minions:
            for deathrattle in minion.deathrattles:
                for _ in range(attacking_player_board.deathrattle_multiplier):
                    deathrattle.trigger(minion, attacking_player_board,
                                        defending_player_board)

        # Resolve "after a friendly minion dies" triggers. ie soul juggles after deathrattles
        # TODO: Refactor for performance
        for minion in attacking_player_board.get_living_minions():
            for dead_minion in attacker_dead_minions:
                minion.on_friendly_removal_after(dead_minion,
                                                 attacking_player_board,
                                                 defending_player_board)

        for minion in defender_dead_minions:
            for deathrattle in minion.deathrattles:
                for _ in range(defending_player_board.deathrattle_multiplier):
                    deathrattle.trigger(minion, defending_player_board,
                                        attacking_player_board)

        for minion in defending_player_board.get_living_minions():
            for dead_minion in defender_dead_minions:
                minion.on_friendly_removal_after(dead_minion,
                                                 defending_player_board,
                                                 attacking_player_board)

        # Process deaths here again to see if death rattles resulted in more deaths
        if len(attacking_player_board.select_dead()) > 0 or len(
                defending_player_board.select_dead()):
            self.check_deaths(attacking_player_board, defending_player_board)

        # Resolve reborns after deathrattles
        for minion in attacker_dead_minions:
            if minion.reborn and not minion.reborn_triggered:
                minion.trigger_reborn(attacking_player_board)

        for minion in defender_dead_minions:
            if minion.reborn and not minion.reborn_triggered:
                minion.trigger_reborn(defending_player_board)

        # Continue to resolve extra attacks until all are done
        while attacking_player_board.get_immediate_attack_minions(
        ) or defending_player_board.get_immediate_attack_minions():
            # TODO: Is there a priority for resolving pirate attacks on each other? Are they queued up?
            self.resolve_extra_attacks(attacking_player_board,
                                       defending_player_board)
            self.resolve_extra_attacks(defending_player_board,
                                       attacking_player_board)