def replay_game(moves, silently: bool): log.disabled = True game = load_game() if silently is False: log.disabled = False show_board(game) log.disabled = True # First replay everything we had already played for move_info in moves: try: temp = play_move(game, move_info.move, silently) assert len(temp) == 2 play_result = temp[0] if play_result is False: # Something went wrong. Try to re-play the game once again # temp = play_move(game, move_info.move, False) return replay_game(moves, silently) # Moves have previously been played successfully, they MUST be re-played successfully once again except GameOver: assert game.current_player.playstate == PlayState.WON if not silently and len(moves) > 0: log.disabled = False log.info("Board state after playback:") show_board(game) log.disabled = False return game
def init_game(hero1=None, hero2=None, exclude=(), game_class=BaseTestGame): log.info("Initializing a new game") heroes = _select_heroes(hero1, hero2) player1 = Player("Player1", *_draft(hero=heroes[0], exclude=exclude)) player2 = Player("Player2", *_draft(hero=heroes[1], exclude=exclude)) game = game_class(players=(player1, player2)) return game
def prepare_game(hero1=None, hero2=None, exclude=(), game_class=BaseTestGame): log.info("Initializing a new game") heroes = _select_heroes(hero1, hero2) player1 = _prepare_player("Player1", heroes[0], _draft(hero=heroes[0], exclude=exclude)) player2 = _prepare_player("Player2", heroes[1], _draft(hero=heroes[1], exclude=exclude)) game = game_class(players=(player1, player2)) game.start() _empty_mulligan(game) return game
def init_game(class1=None, class2=None, exclude=(), game_class=BaseTestGame): log.info("Initializing a new game") if class1 is None: class1 = _random_class() if class2 is None: class2 = _random_class() player1 = Player("Player1", *_draft(class1, exclude)) player2 = Player("Player2", *_draft(class2, exclude)) game = game_class(players=(player1, player2)) return game
def my_summon(game, cur_controller, card): card.controller = cur_controller card._zone = Zone.PLAY card.play_counter = game.play_counter game.play_counter += 1 game.manager.new_entity(card) # game.cheat_action(cur_controller, [Summon(cur_controller, card)]) log.info("%s summons %r", cur_controller, card) assert isinstance(card, Enchantment) or card.is_summonable() card.controller = cur_controller cur_controller.field.append(card) return card
def prepare_empty_game(hero1=None, hero2=None, game_class=BaseTestGame): log.info("Initializing a new game with empty decks") heroes = _select_heroes(hero1, hero2) player1 = Player("Player1", [], heroes[0]) player1.cant_fatigue = True player2 = Player("Player2", [], heroes[1]) player2.cant_fatigue = True game = game_class(players=(player1, player2)) game.start() _empty_mulligan(game) return game
def prepare_empty_game(class1=None, class2=None, game_class=BaseTestGame): log.info("Initializing a new game with empty decks") if class1 is None: class1 = _random_class() if class2 is None: class2 = _random_class() player1 = Player("Player1", [], class1.default_hero) player1.cant_fatigue = True player2 = Player("Player2", [], class2.default_hero) player2.cant_fatigue = True game = game_class(players=(player1, player2)) game.start() _empty_mulligan(game) return game
def print_player_cards(player: Player): cards = player.name + " hero: " + str(player.hero) \ + "(" + str(player.hero.health) + "); " cards = cards + " cards in field: " for character in player.field: try: cards = cards + str(character) + "({},{},{}); ".format( character.atk, character.health, character.cost) except: # for Spell cards which don't have atk attribute cards = cards + str(character) cards = cards + " cards in hand: " for character in player.hand: try: cards = cards + str(character) + "({},{},{}); ".format( character.atk, character.health, character.cost) except: # for Spell cards which don't have atk attribute cards = cards + str(character) log.info("#" + cards)
def print_main_phase_start(): log.info("\n") log.info("#### Main phase of game starts.")
def print_empty_line(): log.info("\n")
def print_playing_card_on_target(card, target): log.info("# %r playing %r on %r" % (card.controller.name, card, target))
def print_attack(character, target): log.info("### {}({},{},{},{}) attacks {}({},{},{},{})".format( str(character), character.atk, character.health, character.cost, character.controller.name, str(target), target.atk, target.health, target.cost, target.controller.name))
def show_board(game): log.info("") log.info("----- Board -----") assert not (game is None) for player in game.players: log.info("Player has hero %r with %d health out of %d", CardList([player.hero]), player.hero.health, player.hero.max_health) if len(player.field) == 0: log.info("Board of player %s is empty", player.name) else: log.info("%s has %d entities on board:", player.name, len(player.field)) for minion in player.field: assert isinstance(minion, Minion) log.info("%s %d / %d (max %d)", minion.name, minion.atk, minion.health, minion.max_health) log.info("----- END of the board -----") log.info("")
def print_choosing_card(choice): log.info("# %r choosing card %r" % (choice.controller.name, choice))
def play_move(game: Game, move: Move, silently: bool) -> [bool, Move]: """ Tries to play the move :param game: Game object :param move: Move object :return: bool (True if move was possible to play) and the next move or None if no move available """ play_message = "" next_move = Move() player = game.current_player assert player.playstate != PlayState.WON and player.playstate != PlayState.LOST and player.playstate != PlayState.TIED try: if not move.m_should_skip_using_hero_power: heropower = player.hero.power if not heropower.is_usable(): next_move.m_should_skip_using_hero_power = True assert next_move.m_hero_power_target == 0 assert next_move.m_cards_in_hand_to_skip == 0 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] if heropower.has_target(): if move.m_hero_power_target == len(heropower.targets): next_move.m_should_skip_using_hero_power = True assert next_move.m_hero_power_target == 0 assert next_move.m_cards_in_hand_to_skip == 0 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] next_move.m_hero_power_target = move.m_hero_power_target + 1 power_target = heropower.targets[move.m_hero_power_target] if silently is False: print("Player {0} uses hero power {1} on {2}".format(player, heropower, power_target)) heropower.use(target=power_target) return [True, next_move] else: next_move.m_should_skip_using_hero_power = True assert next_move.m_hero_power_target == 0 assert next_move.m_cards_in_hand_to_skip == 0 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 if silently is False: print("Player {0} uses hero power {1}".format(player, heropower)) heropower.use() return [True, next_move] # We didn't play Hero power - set fields in next_move accordingly next_move.m_should_skip_using_hero_power = True next_move.m_hero_power_target = 0 if move.m_cards_in_hand_to_skip < len(player.hand): card = player.hand[move.m_cards_in_hand_to_skip] if not card.is_playable(): assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip + 1 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] play_message = "Player plays card {0}".format(card) orig_card = card if card.must_choose_one: if move.m_pre_play_card_choice is None: move.m_pre_play_card_choice = 0 if move.m_pre_play_card_choice == len(card.choose_cards): assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip + 1 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] else: card = card.choose_cards[move.m_pre_play_card_choice] play_message += ", chooses card {0}".format(card) else: next_move.m_pre_play_card_choice = None card_target = None if card.has_target(): if move.m_play_card_target == len(card.targets): if orig_card.must_choose_one: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice + 1 assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 else: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip + 1 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] card_target = card.targets[move.m_play_card_target] play_message += ", picks target card {0}".format(card_target) zone_index = None if isinstance(card, Minion): if move.m_minion_position > len(player.field): if card.has_target(): assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice next_move.m_play_card_target = move.m_play_card_target + 1 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 elif orig_card.must_choose_one: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice + 1 assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 else: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip + 1 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] else: zone_index = next_move.m_minion_position play_message += ", puts minion at position %d" % zone_index if (move.m_after_play_card_choice is None) or move.m_after_play_card_choice == move.m_max_after_play_card_choice: if isinstance(card, Minion): assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice next_move.m_play_card_target = move.m_play_card_target + 1 next_move.m_minion_position = move.m_minion_position + 1 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 elif card.has_target(): assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice next_move.m_play_card_target = move.m_play_card_target + 1 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 elif orig_card.must_choose_one: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice + 1 assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 else: assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip + 1 assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 if not (move.m_after_play_card_choice is None) and move.m_after_play_card_choice == move.m_max_after_play_card_choice: return [False, next_move] try: card.play(target=card_target, index=zone_index) except GameOver: if silently is False: play_message += " and game is over" print(play_message) raise if player.choice: if move.m_after_play_card_choice is None: move.m_after_play_card_choice = 0 move.m_max_after_play_card_choice = len(player.choice.cards) next_move.m_after_play_card_choice = 0 next_move.m_max_after_play_card_choice = len(player.choice.cards) assert move.m_after_play_card_choice < len(player.choice.cards) assert next_move.m_max_after_play_card_choice == len(player.choice.cards) assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip next_move.m_pre_play_card_choice = move.m_pre_play_card_choice next_move.m_play_card_target = move.m_play_card_target + 1 next_move.m_minion_position = move.m_minion_position + 1 next_move.m_after_play_card_choice = move.m_after_play_card_choice + 1 next_move.m_max_after_play_card_choice = move.m_max_after_play_card_choice assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 choice = player.choice.cards[move.m_after_play_card_choice] log.info("After play we're choosing card {0}".format(choice)) try: player.choice.choose(choice) except GameOver: if silently is False: play_message += " and game is over" print(play_message) raise play_message += ", selects card {0} as an afterplay choice".format(choice) if silently is False: print(play_message) return [True, next_move] assert next_move.m_should_skip_using_hero_power is True assert next_move.m_hero_power_target == 0 next_move.m_cards_in_hand_to_skip = move.m_cards_in_hand_to_skip assert next_move.m_pre_play_card_choice is None assert next_move.m_play_card_target == 0 assert next_move.m_minion_position == 0 assert next_move.m_after_play_card_choice is None assert next_move.m_max_after_play_card_choice is None assert next_move.m_characters_who_can_attack_to_skip == 0 assert next_move.m_attack_targets_to_skip == 0 # No more characters left to attack with if move.m_characters_who_can_attack_to_skip == len(player.characters): return [False, None] character = player.characters[move.m_characters_who_can_attack_to_skip] assert not (character is None) if not character.can_attack(): next_move.m_characters_who_can_attack_to_skip = move.m_characters_who_can_attack_to_skip + 1 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] if move.m_attack_targets_to_skip == len(character.targets): next_move.m_characters_who_can_attack_to_skip = move.m_characters_who_can_attack_to_skip + 1 assert next_move.m_attack_targets_to_skip == 0 return [False, next_move] target_to_attack = character.targets[move.m_attack_targets_to_skip] next_move.m_characters_who_can_attack_to_skip = move.m_characters_who_can_attack_to_skip next_move.m_attack_targets_to_skip = move.m_attack_targets_to_skip + 1 try: character.attack(target_to_attack) finally: if silently is False: print("{0} attacks {1}".format(character, target_to_attack)) return [True, next_move] except GameOver: if player.playstate == PlayState.WON: raise return [False, next_move]
def StandardStep1(self, game, option=None, gameLog=[], debugLog=True): debugChoice = False ### Display parameters and scores if option == None: print("StandardStep1 needs an option") return ExceptionPlay.INVALID myWeight = option loopCount = 0 while loopCount < 20: loopCount += 1 if debugChoice: print(">>>>>>>>>>>>>>>>>>>") myCandidate = getCandidates(game) #「何もしない」選択肢は入れていない myChoices = [ Candidate(None, type=ExceptionPlay.TURNEND, turn=game.turn) ] #何もしない選択 maxScore = self.getStageScore(game, myWeight, debugChoice) #何もしないときのスコア if debugChoice: print(" %s %d" % (myChoices[0], maxScore)) maxChoice = None for myChoice in myCandidate: tmpGame = fireplace_deepcopy(game) #tmpGame = copy.deepcopy(game) log.info("Estimate the score for [%s]" % (myChoice)) result = executeAction(tmpGame, myChoice, debugLog=False) postAction(tmpGame.current_player) if result == ExceptionPlay.INVALID: stop = True if result == ExceptionPlay.GAMEOVER: score = 100000 else: if self.__standard_agent__.StandardRandom( tmpGame, debugLog=False ) == ExceptionPlay.GAMEOVER: #ここをもっと賢くしてもよい score = 100000 else: score = self.getStageScore(tmpGame, myWeight, debugChoice) if debugChoice: print(" %s %d" % (myChoice, score)) if score > maxScore: maxScore = score myChoices = [myChoice] if score == 100000: break elif score == maxScore: myChoices.append(myChoice) if debugChoice: print("<<<<<<<<<<<<<<<<<<<") if len(myChoices) > 0: myChoice = random.choice(myChoices) if myChoice.type == ExceptionPlay.TURNEND: if debugLog: print(">%s -> turnend." % (self.name)) return ExceptionPlay.VALID ret = executeAction(game, myChoice, debugLog=debugLog) if ret == ExceptionPlay.GAMEOVER: return ExceptionPlay.GAMEOVER if ret == ExceptionPlay.INVALID: return ExceptionPlay.INVALID player = game.current_player postAction(player) continue else: return ExceptionPlay.VALID
def test_full_game(): moves = list() reload_and_replay = True new_move = Move() best_move_sequence = list() best_game_score = None while True: if reload_and_replay: game = replay_game(moves, True) try: play_result = False next_move = None if not (new_move is None): play_move_silently = True log.disabled = play_move_silently temp = play_move(game, new_move, play_move_silently) log.disabled = False assert len(temp) == 2 play_result = temp[0] next_move = temp[1] if play_result is False: # Failed to play the move if next_move is None: # There is no next move available if len(moves) == 0: # We've checked every possible move, job is done log.info("") log.info("") log.info("") log.info("") log.info("Best game score: {0}, move sequence: {1}".format(best_game_score, best_move_sequence)) replay_game(best_move_sequence, False) return new_move = moves[len(moves) - 1].next_move moves.pop() reload_and_replay = True else: # There is another possible move to try new_move = next_move reload_and_replay = False else: # We've successfully played the move, add it to the list of the successfully played moves temp = GameMove() temp.move = new_move temp.next_move = next_move moves.append(temp) reload_and_replay = False move_score = get_game_score(game) if (best_game_score is None) or move_score.is_better(best_game_score): best_game_score = move_score best_move_sequence = copy.deepcopy(moves) new_move = Move() except GameOver: assert not (new_move is None) moves_played = list() moves_played.extend(moves) temp = GameMove() temp.move = new_move moves_played.append(temp) log.disabled = False for player in game.players: if player == game.current_player: if player.playstate == PlayState.WON: log.info("Player wins with this sequence of moves: %r", moves_played) elif player.playstate == PlayState.LOST: log.info("Player loses with this sequence of moves: %r", moves_played) else: log.info("Game ends with a tie") break log.disabled = True replay_game(moves_played, False) if game.current_player.playstate == PlayState.WON: return else: assert len(moves) != 0 new_move = moves[len(moves) - 1].next_move moves.pop() reload_and_replay = True
def print_deck_content(player_name: str, deck: Deck): deck_info = player_name + "'s deck contains:\n {0}".format(deck) log.info("#" + deck_info)