Ejemplo n.º 1
0
class Board:
    def __init__(self, exit_on_game_over=False):
        self.actions = ActionFactory(self)
        self.deck1 = []
        self.deck2 = []
        self.players = []
        self.sides = [[], []]
        self.active_player = 0
        self.exit_on_game_over = exit_on_game_over
        self.winner = None

    def initialize_game(self):
        initializer = DeckInitializer()
        self.deck1 = initializer.make_std_deck()
        self.deck2 = initializer.make_std_deck()
        p1_starts = self._player1_starts()
        self.active_player = 0 if p1_starts else 1 
        self.players = [
            Player(id=1, deck=self.deck1, hand=Hand(self.deck1), starts=p1_starts),
            Player(id=2, deck=self.deck2, hand=Hand(self.deck2), starts=not p1_starts)
        ]
        self.sides = [[initializer.create_hero('jaina')], [initializer.create_hero('jaina')]]

    def _player1_starts(self):
        return random() < 0.5

    def play_minion(self, index):
        self.execute_action(self.actions.play_minion(index))

    def cast_spell(self, card_idx, target_idx, safe=False):
        self.execute_action(self.actions.cast_spell(card_idx, target_idx, safe))

    def end_turn(self, safe=False):
        self.execute_action(self.actions.end_turn(safe))

    def active_draw_card(self, card_idx):
        self.execute_action(self.actions.draw(card_idx))

    def attack(self, atk_idx, def_idx, safe=False):
        self.execute_action(self.actions.attack(atk_idx, def_idx, safe))

    def execute_action(self, action):
        action.execute()

    def change_active_player(self):
        self.active_player = self.get_other_idx()

    def get_active_hand(self):
        return self.get_active_player().hand

    def get_other_hand(self):
        return self.get_other_player().hand

    def get_active_deck(self):
        return self.get_active_player().deck

    def get_other_deck(self):
        return self.get_other_player().deck

    def get_active_idx(self):
        return self.active_player

    def get_other_idx(self):
        return 1 if self.active_player == 0 else 0

    def get_active_side(self):
        return self.sides[self.get_active_idx()]

    def get_other_side(self):
        return self.sides[self.get_other_idx()]

    def get_active_player(self):
        return self.players[self.get_active_idx()]

    def get_other_player(self):
        return self.players[self.get_other_idx()]

    def game_loop(self):
        pass

    def game_over(self, active):
        self.winner = active+1        
        if self.exit_on_game_over:
            print(str(self))
            print('Player #{} won!'.format(active+1))
            sys.exit(self.winner)

    def is_game_over(self):
        return self.winner is not None

    def __str__(self):
        board_str = ''
        for player in self.players:
            board_str += str(player) + '\n'
        i = 1
        board_str += '\n\n'
        for side in self.sides:
            board_str += 'SIDE OF PLAYER #{}:\n'.format(i)
            i += 1
            for card in side:
                board_str += '{}\n'.format(card)
        return board_str
Ejemplo n.º 2
0
class Analyzer:
    def __init__(self, board):
        self.board = board
        self.actions = ActionFactory(board)
        self.reviewer = BoardReviewer(board)

    def generate_actions(self):
        if self.board.is_game_over():
            return []
        all_actions = []
        all_actions.extend(self.generate_playing_minions())
        all_actions.extend(self.generate_attacks())
        all_actions.extend(self.generate_casting_spells())
        all_actions.extend(self.generate_ending_turn())
        # all_actions.extend(self.generate_card_draw())
        return all_actions

    def grade_board(self):
        return self.reviewer.grade_board()

    def generate_playing_minions(self):
        player = self.board.get_active_player()
        active_side = self.board.get_active_side()
        actions = []
        for idx, card in enumerate(player.hand.cards):
            if card.cost <= player.mana:
                if card.type == 'minion':
                    if len(active_side) < 7:
                        actions.append(self.actions.play_minion(idx))
        return actions

    def generate_ending_turn(self):
        return [self.actions.end_turn()]

    def generate_attacks(self):
        active_side = self.board.get_active_side()
        other_side = self.board.get_other_side()
        actions = []
        for idx, minion in enumerate(active_side):
            # Skip the hero
            if idx == 0: continue
            if minion.can_attack:
                taunts = [c for c in other_side if c.taunt]
                for enemyidx, enemy in enumerate(other_side):
                    if taunts:
                        if enemy.taunt:
                            actions.append(self.actions.attack(idx, enemyidx))
                    else:
                        actions.append(self.actions.attack(idx, enemyidx))
        return actions

    def generate_casting_spells(self):
        active_player = self.board.get_active_player()
        other_side = self.board.get_other_side()
        actions = []
        for cardidx, card in enumerate(active_player.hand.cards):
            if card.type != 'spell': continue
            if card.cost > active_player.mana: continue
            for enemyidx, _ in enumerate(other_side):
                actions.append(self.actions.cast_spell(cardidx, enemyidx))
        return actions

    def generate_card_draw(self):
        deck = self.board.get_active_deck()
        card_scores = [self.reviewer.grade_card(c) for c in deck.cards]
        max_score_idx = card_scores.index(max(card_scores))
        return [self.actions.draw(max_score_idx)]