def test_agent_once(one, other = None): #print("game_started") generator = RandomDeckGenerator() deck1 = generator.generate() deck2 = deck1.copy() if other is None: other = TradeAgent() #other = RandomAgent() game = Game([deck1, deck2], [one, other]) new_game = game.copy() try: new_game.start() # new_data = GameHistoryGenerator.process_history(history, new_game) # Data = open("data.txt", "a") # for i in new_data: # tmp = i[0] # tmp.append(i[1]) # for j in range(len(tmp)): # tmp[j] = str(tmp[j]) # Data.write(" ".join(tmp)) # Data.write("\n") # Data.close() print("Game lasted: " + str(new_game._turns_passed)) print("winning agent: " + new_game.winner.agent.name) except Exception as e: print("Game error: " + str(e)) # raise e return False # spark_weights(ql.weights) return new_game.winner.agent.name
def generate_game_for(card1, card2, first_agent_type, second_agent_type, run_pre_game=True): if not isinstance(card1, collections.Sequence): card_set1 = [card1()] else: card_set1 = [card() for card in card1] class1 = CHARACTER_CLASS.MAGE for card in card_set1: if card.character_class != CHARACTER_CLASS.ALL: class1 = card.character_class break if not isinstance(card2, collections.Sequence): card_set2 = [card2()] else: card_set2 = [card() for card in card2] class2 = CHARACTER_CLASS.MAGE for card in card_set2: if card.character_class != CHARACTER_CLASS.ALL: class2 = card.character_class break deck1 = StackedDeck(card_set1, class1) deck2 = StackedDeck(card_set2, class2) game = Game([deck1, deck2], [first_agent_type(), second_agent_type()]) game.current_player = game.players[1] game.other_player = game.players[0] if run_pre_game: game.pre_game() return game
def enshelf_one(index): loader = DeckLoader() generator = RandomDeckGenerator() # deck1 = loader.load_deck("zoo.hsdeck") # deck2 = loader.load_deck("zoo.hsdeck") deck1 = generator.generate() deck2 = generator.generate() game = Game([deck1, deck2], [TradeAgent(), TradeAgent()]) new_game = game.copy() game_log = Hearthlogger() game_log.attach(new_game) try: new_game.start() except Exception as e: #print(json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) #print(new_game._all_cards_played) del new_game del game_log print(e) return False # print("winning agent: " + new_game.winner.agent.__class__.__name__) game_log.shelf(index) del new_game del game_log return True
def start_state(self): generator = RandomDeckGenerator() deck1 = generator.generate() deck2 = deck1.copy() game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) game.pre_game() return game
def test_create_game(self): card_set1 = [] card_set2 = [] test_env = self for cardIndex in range(0, 30): card_set1.append(card_lookup("Stonetusk Boar")) card_set2.append(card_lookup("Novice Engineer")) deck1 = Deck(card_set1, Malfurion()) deck2 = Deck(card_set2, Jaina()) checked_cards = [] class MockAgent1: def do_card_check(self, cards): test_env.assertEqual(len(cards), 3) checked_cards.append(list(cards)) return [False, True, True] def set_game(self, game): pass class MockAgent2: def do_card_check(self, cards): test_env.assertEqual(len(cards), 4) checked_cards.append(list(cards)) return [False, True, True, False] def set_game(self, game): pass agent1 = mock.Mock(spec=MockAgent1(), wraps=MockAgent1()) agent2 = mock.Mock(spec=MockAgent2(), wraps=MockAgent2()) game = Game([deck1, deck2], [agent1, agent2]) game.pre_game() self.assertEqual(agent1.method_calls[0][0], "do_card_check", "Agent not asked to select cards") self.assertEqual(agent2.method_calls[0][0], "do_card_check", "Agent not asked to select cards") self.assertTrue(game.players[0].deck == deck1, "Deck not assigned to player") self.assertTrue(game.players[1].deck == deck2, "Deck not assigned to player") self.assertTrue(game.players[0].agent == agent1, "Agent not stored in the hearthbreaker") self.assertTrue(game.players[1].agent == agent2, "Agent not stored in the hearthbreaker") self.assertListEqual(checked_cards[0][1:], game.players[0].hand[1:], "Cards not retained after request") self.assertListEqual(checked_cards[1][1:2], game.players[1].hand[1:2], "Cards not retained after request")
def test_SavageRoar(self): deck1 = StackedDeck([StonetuskBoar(), StonetuskBoar(), SavageRoar()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) game = Game([deck1, deck2], [OneCardPlayingAgent(), OneCardPlayingAgent()]) game.current_player = 1 game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() minion_increase_mock = mock.Mock() game.other_player.minions[0].bind("attack_changed", minion_increase_mock) game.other_player.minions[1].bind("attack_changed", minion_increase_mock) player_increase_mock = mock.Mock() game.other_player.hero.bind("attack_changed", player_increase_mock) game.play_single_turn() self.assertEqual(0, game.current_player.mana) # Make sure the attack got increased self.assertListEqual([mock.call(2), mock.call(2)], minion_increase_mock.call_args_list) self.assertListEqual([mock.call(2)], player_increase_mock.call_args_list) # And make sure that it went down again self.assertEqual(1, game.current_player.minions[0].calculate_attack()) self.assertEqual(1, game.current_player.minions[1].calculate_attack()) self.assertEqual(0, game.current_player.hero.calculate_attack())
def test_CircleOfHealing(self): deck1 = StackedDeck([ CircleOfHealing(), MogushanWarden(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing() ], CHARACTER_CLASS.PRIEST) deck2 = StackedDeck([MogushanWarden()], CHARACTER_CLASS.PALADIN) game = Game( [deck1, deck2], [CardTestingAgent(), OneCardPlayingAgent()]) game.pre_game() game.current_player = 1 for turn in range(0, 8): game.play_single_turn() game.players[0].minions[0].health = 4 game.players[1].minions[0].health = 4 game.play_single_turn() # Circle of Healing should be played self.assertEqual(game.players[0].minions[0].calculate_max_health(), game.players[0].minions[0].health) self.assertEqual(game.players[1].minions[0].calculate_max_health(), game.players[1].minions[0].health)
def generate_one(agent1, agent2, extractor): generator = RandomDeckGenerator() deck1 = generator.generate() deck2 = deck1.copy() game = Game([deck1, deck2], [agent1, agent2]) try: history = game.start_with_history() except Exception as e: return None if not game.game_ended: return None return GameHistoryGenerator.process_history(history, game, extractor)
def test_deck_shortening(self): deck1 = Deck([RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), GoldshireFootman(), GoldshireFootman()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.HUNTER) game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) replay = record(game) game.start() replay.write(StringIO())
def test_first_turn(self): card_set1 = [] card_set2 = [] for cardIndex in range(0, 30): card_set1.append(card_lookup("Stonetusk Boar")) card_set2.append(card_lookup("Novice Engineer")) deck1 = Deck(card_set1, Malfurion()) deck2 = Deck(card_set2, Jaina()) agent1 = mock.Mock(spec=DoNothingAgent(), wraps=DoNothingAgent()) agent2 = mock.Mock(spec=DoNothingAgent(), wraps=DoNothingAgent()) game = Game([deck1, deck2], [agent1, agent2]) game.start()
def do_stuff(): _count = 0 def play_game(): nonlocal _count _count += 1 new_game = game.copy() try: new_game.start() except Exception as e: print( json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) print(new_game._all_cards_played) raise e del new_game if _count % 1000 == 0: print("---- game #{} ----".format(_count)) deck1 = load_deck("mage.hsdeck") deck2 = load_deck("mage2.hsdeck") game = Game([deck1, deck2], [AggressiveAgent(), RandomAgent()]) # game = Game([deck1, deck2], [TalkativeAgent(), RandomAgent()]) # game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) print(timeit.timeit(play_game, 'gc.enable()', number=1))
def serialization_copy(old_game): game_json = json.dumps(old_game, default=_save_object, indent=2) d = json.loads(game_json) game = Game.__from_json__( d, [player.agent for player in old_game.players]) game._has_turn_ended = old_game._has_turn_ended return game
def run_game(self, other): mydeck = self.breakerdeck() game = Game([mydeck, other.breakerdeck()], [RandomAgent(), RandomAgent()]) tries = 0 while tries < 10: try: game.start() result = game.players[0].hero.dead and game.players[0].deck == mydeck if result: database.create_game('mutational', self.id, other.id, self.id) else: database.create_game('mutational', self.id, other.id, other.id) return except: tries += 1 return True
def generate_replays(): loader = DeckLoader() deck1 = loader.load_deck("patron.hsdeck") deck2 = loader.load_deck("patron.hsdeck") game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) new_game = game.copy() replay = record(new_game) try: new_game.start() except Exception as e: print(json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) print(new_game._all_cards_played) raise e replay.write_json("replay_text.hsreplay") del new_game print("done!")
def test_recording_game(self): self.maxDiff = None random.seed(9876) deck1 = hearthbreaker.engine.Deck([StonetuskBoar() for i in range(0, 30)], CHARACTER_CLASS.MAGE) deck2 = hearthbreaker.engine.Deck([Naturalize() for i in range(0, 30)], CHARACTER_CLASS.DRUID) agent1 = PredictableAgent() agent2 = PredictableAgent() game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.start() output = StringIO() replay.write_json(output) f = open("tests/replays/stonetusk_innervate.hsreplay", 'r') dif = self.__compare_json(output.getvalue(), f.read()) self.assertTrue(dif) f.close()
def deserialize(json_string, agents): """ Decode the given game instance from a JSON formatted string. :param string json_string: The string representation of the game :rtype: :class:`hearthbreaker.engine.Game` """ d = json.loads(json_string) return Game.__from_json__(d, agents)
def test_recording_game(self): self.maxDiff = None random.seed(9876) deck1 = hearthbreaker.engine.Deck( [StonetuskBoar() for i in range(0, 30)], Jaina()) deck2 = hearthbreaker.engine.Deck([Naturalize() for i in range(0, 30)], Malfurion()) agent1 = PredictableAgent() agent2 = PredictableAgent() game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.start() output = StringIO() replay.write_json(output) f = open("tests/replays/stonetusk_innervate.hsreplay", 'r') dif = self.__compare_json(output.getvalue(), f.read()) self.assertTrue(dif) f.close()
def test_random_character_saving(self): deck1 = hearthbreaker.engine.Deck( [RagnarosTheFirelord() for i in range(0, 30)], Jaina()) deck2 = hearthbreaker.engine.Deck( [StonetuskBoar() for i in range(0, 30)], Malfurion()) agent1 = PlayAndAttackAgent() agent2 = OneCardPlayingAgent() random.seed(4879) game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.pre_game() for turn in range(0, 17): game.play_single_turn() output = StringIO() replay.write_json(output) random.seed(4879) new_game = playback(Replay(StringIO(output.getvalue()))) new_game.pre_game() for turn in range(0, 17): new_game.play_single_turn() self.assertEqual(2, len(new_game.current_player.minions)) self.assertEqual(30, new_game.other_player.hero.health) self.assertEqual(5, len(new_game.other_player.minions))
def test_HolyNova(self): deck1 = StackedDeck([MogushanWarden(), HolyNova()], CHARACTER_CLASS.PRIEST) deck2 = StackedDeck([MogushanWarden()], CHARACTER_CLASS.PALADIN) game = Game([deck1, deck2], [CardTestingAgent(), OneCardPlayingAgent()]) game.pre_game() game.current_player = 1 for turn in range(0, 8): game.play_single_turn() self.assertEqual(1, len(game.players[0].minions)) self.assertEqual(1, len(game.players[1].minions)) game.players[0].minions[0].health = 4 # Fake damage self.assertEqual(4, game.players[0].minions[0].health) self.assertEqual(7, game.players[1].minions[0].health) game.play_single_turn() # Holy Nova should be played self.assertEqual(6, game.players[0].minions[0].health) self.assertEqual(5, game.players[1].minions[0].health)
def test_json_saving(self): self.maxDiff = 6000 deck1 = hearthbreaker.engine.Deck([RagnarosTheFirelord() for i in range(0, 30)], CHARACTER_CLASS.MAGE) deck2 = hearthbreaker.engine.Deck([StonetuskBoar() for i in range(0, 30)], CHARACTER_CLASS.DRUID) agent1 = PlayAndAttackAgent() agent2 = OneCardPlayingAgent() random.seed(4879) game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.pre_game() for turn in range(0, 17): game.play_single_turn() output = StringIO() replay.write_json(output) inp = StringIO(output.getvalue()) new_replay = Replay() new_replay.read_json(inp) old_output = output.getvalue() other_output = StringIO() new_replay.write_json(other_output) self.assertEqual(other_output.getvalue(), old_output)
def test_deck_shortening(self): deck1 = Deck([ RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), RagnarosTheFirelord(), GoldshireFootman(), GoldshireFootman() ], Malfurion()) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.HUNTER) game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) replay = record(game) game.start() replay.write(StringIO())
def test_random_character_saving(self): deck1 = hearthbreaker.engine.Deck([RagnarosTheFirelord() for i in range(0, 30)], CHARACTER_CLASS.MAGE) deck2 = hearthbreaker.engine.Deck([StonetuskBoar() for i in range(0, 30)], CHARACTER_CLASS.DRUID) agent1 = PlayAndAttackAgent() agent2 = OneCardPlayingAgent() random.seed(4879) game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.pre_game() for turn in range(0, 17): game.play_single_turn() output = StringIO() replay.write_json(output) random.seed(4879) new_game = playback(Replay(StringIO(output.getvalue()))) new_game.pre_game() for turn in range(0, 17): new_game.play_single_turn() self.assertEqual(2, len(new_game.current_player.minions)) self.assertEqual(30, new_game.other_player.hero.health) self.assertEqual(5, len(new_game.other_player.minions))
def test_agent_once(one, other): generator = RandomDeckGenerator() deck1 = generator.generate() deck2 = deck1.copy() if other is None: other = TradeAgent() #other = RandomAgent() game = Game([deck1, deck2], [one, other]) new_game = game.copy() try: new_game.start() except Exception as e: print("Game error: " + str(e)) raise e # raise #print(json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) # new_game return False print("Game lasted: " + str(new_game._turns_passed)) print("winning agent: " + new_game.winner.agent.name) # spark_weights(ql.weights) return new_game.winner.agent.name
def test_CircleOfHealing(self): deck1 = StackedDeck( [CircleOfHealing(), MogushanWarden(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing(), CircleOfHealing()], CHARACTER_CLASS.PRIEST) deck2 = StackedDeck([MogushanWarden()], CHARACTER_CLASS.PALADIN) game = Game([deck1, deck2], [CardTestingAgent(), OneCardPlayingAgent()]) game.pre_game() game.current_player = 1 for turn in range(0, 8): game.play_single_turn() game.players[0].minions[0].health = 4 game.players[1].minions[0].health = 4 game.play_single_turn() # Circle of Healing should be played self.assertEqual(game.players[0].minions[0].calculate_max_health(), game.players[0].minions[0].health) self.assertEqual(game.players[1].minions[0].calculate_max_health(), game.players[1].minions[0].health)
def do_stuff(agent1, agent2, d1, d2): _count = 0 lwins = 0 rwins = 0 def play_game(): nonlocal _count nonlocal lwins nonlocal rwins _count += 1 new_game = game.copy() try: new_game.start() lwins += (new_game.players[0].hero.health != 0) rwins += (new_game.players[1].hero.health != 0) except Exception as e: print( json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__())) print(new_game._all_cards_played) raise e del new_game # if _count % 50 == 0: # print("---- game #{} ----".format(_count)) # print("lwins: " + str(lwins) + ", rwins: "+ str(rwins)) deck1 = load_deck(d1) deck2 = load_deck(d2) game = Game([deck1, deck2], [agent1, agent2]) print(timeit.timeit(play_game, 'gc.enable()', number=100)) returnString = str(game.players[0].agent ) + " with deck " + d1 + ": " + str(lwins) + " wins" returnString += '\n\t' + str( game.players[1].agent) + " with deck " + d2 + ": " + str( rwins) + " wins" if rwins != 0: returnString += '\n\t ratio: ' + str(lwins / rwins) return (returnString, lwins, rwins)
def do_stuff(): _count = 0 def play_game(): nonlocal _count _count += 1 new_game = game.copy() try: winner = new_game.start() print("Winner: ", winner) print("turns passed : ", new_game._turns_passed) print("# " * 27, " GAME OVER ", " #" * 27) print(new_game.players[0], "has", new_game.players[0].hero.health, "life points,\t", end='') print(new_game.players[1], "has", new_game.players[1].hero.health, "life points") print(winner, 'won the game (', winner.agent, ')') print("# " * 61, "\n") print("AVG tree depth per nr of turns", global_depth) print("AVG percent of explored children", global_nodesvisited) except Exception as e: # print(json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) # print(new_game._all_cards_played) raise e del new_game if _count % 1000 == 0: print("---- game #{} ----".format(_count)) cards = load_deck("mage3.hsdeck") deck1 = Deck(cards, Jaina()) deck2 = Deck(cards, Malfurion()) game = Game([deck1, deck2], [MCTSAgent(30), RandomAgent()]) # game = Game([deck1, deck2], [AggressiveAgent(), RandomAgent()]) # game = Game([deck1, deck2], [ControllingAgent(), RandomAgent()]) # game = Game([deck1, deck2], [TalkativeAgent(), RandomAgent()]) # game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) print(timeit.timeit(play_game, 'gc.enable()', number=1))
def do_stuff(): _count = 0 player_one_win = 0 player_two_win = 0 def play_game(): nonlocal _count, player_two_win, player_one_win _count += 1 new_game = game.copy() try: new_game.start() except Exception as e: print( json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) print(new_game._all_cards_played) raise e print('Player one hp: ' + str(new_game.players[0].hero.health) + ' vs ' + 'Player two hp: ' + str(new_game.players[1].hero.health)) if new_game.players[1].hero.health == 0: player_one_win += 1 else: player_two_win += 1 del new_game if _count % 1000 == 0: print("---- game #{} ----".format(_count)) deck1 = load_deck("test_deck.hsdeck") deck2 = load_deck("test_deck.hsdeck") game = Game([deck1, deck2], [GreedyAttackHeroAgent(), GreedyControlHeroAgent()]) print('\nTime: ' + str(timeit.timeit(play_game, 'gc.enable()', number=1))) print('Player one won: ' + str(player_one_win) + ' games, ' + game.players[0].agent.__class__.__name__) print('Player two won: ' + str(player_two_win) + ' games, ' + game.players[1].agent.__class__.__name__)
def test_strategy(): generator = RandomDeckGenerator() deck1 = generator.generate() deck2 = deck1.copy() game = Game([deck1, deck2], [TradeAgent(), TradeAgent()]) game.pre_game() game.current_player = game.players[1] while not game.game_ended: manager = StrategyManager(StatePairLinearModel(RelativeResourceExtractor())) manager.think(game) outcomes = manager.get_outcomes() print("Number of outcomes: " + str(len(outcomes)) + '\n') # for situation in outcomes: # print("See: " + str(situation.other_player.hero.__to_json__()) + '\n') # input("Presss enter to continue:") game.play_single_turn()
def do_stuff(): global _totalTry _count = 0 def play_game(): global _totalCount nonlocal _count _count += 1 new_game = game.copy() try: new_game.start() except Exception as e: print( json.dumps(new_game.__to_json__(), default=lambda o: o.__to_json__(), indent=1)) print(new_game._all_cards_played) raise e if new_game.playersInOrder[0].hero.dead and new_game._turns_passed < 50: _totalCount += 1.0 del new_game if _count % 1000 == 0: print("---- game #{} ----".format(_count)) deck1 = load_deck("zoo.hsdeck") deck2 = load_deck("zoo.hsdeck") '''Give agent object and play name''' game = Game([deck1, deck2], [(TradeAgent(), "opponent"), (SimpleUCTAgent(0.002, 200), "uct")]) # game = Game([deck1, deck2], [(UCTAgent.SimpleUCTAgent(0.1,100),"opponent"), (UCTAgent.SimpleUCTAgent(0.2,100), # "uct")]) print(timeit.timeit(play_game, 'gc.enable()', number=_totalPlay)) print("uct win rate:%0.2f" % (_totalCount / _totalPlay))
def test_json_saving(self): self.maxDiff = 6000 deck1 = hearthbreaker.engine.Deck( [RagnarosTheFirelord() for i in range(0, 30)], Jaina()) deck2 = hearthbreaker.engine.Deck( [StonetuskBoar() for i in range(0, 30)], Malfurion()) agent1 = PlayAndAttackAgent() agent2 = OneCardPlayingAgent() random.seed(4879) game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.pre_game() for turn in range(0, 17): game.play_single_turn() output = StringIO() replay.write_json(output) inp = StringIO(output.getvalue()) new_replay = Replay() new_replay.read_json(inp) old_output = output.getvalue() other_output = StringIO() new_replay.write_json(other_output) self.assertEqual(other_output.getvalue(), old_output)
def test_PowerOfTheWild(self): deck1 = StackedDeck( [StonetuskBoar(), StonetuskBoar(), PowerOfTheWild()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) # This is a test of the +1/+1 option of the Power Of the Wild Card game = Game([deck1, deck2], [OneCardPlayingAgent(), OneCardPlayingAgent()]) game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(2, game.current_player.minions[0].calculate_attack()) self.assertEqual(2, game.current_player.minions[0].health) self.assertEqual(2, game.current_player.minions[0].calculate_max_health()) self.assertEqual(2, game.current_player.minions[1].calculate_attack()) self.assertEqual(2, game.current_player.minions[1].calculate_max_health()) # This is a test of the "Summon Panther" option of the Power of the Wild Card agent = OneCardPlayingAgent() agent.choose_option = lambda options, player: options[1] deck1 = StackedDeck( [StonetuskBoar(), StonetuskBoar(), PowerOfTheWild()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) game = Game([deck1, deck2], [agent, OneCardPlayingAgent()]) game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual( "Panther", game.current_player.minions[2].card.__class__.__name__) self.assertEqual(3, game.current_player.minions[2].calculate_attack()) self.assertEqual(2, game.current_player.minions[2].calculate_max_health())
def test_Cenarius(self): deck1 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([WarGolem(), WarGolem(), Cenarius(), Cenarius()], CHARACTER_CLASS.DRUID) game = Game([deck1, deck2], [DoNothingAgent(), OneCardPlayingAgent()]) game.pre_game() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(2, len(game.other_player.minions)) for minion in game.other_player.minions: self.assertEqual(7, minion.calculate_attack()) self.assertEqual(7, minion.health) self.assertEqual(7, minion.calculate_max_health()) game.play_single_turn() self.assertEqual(3, len(game.current_player.minions)) self.assertEqual(5, game.current_player.minions[0].calculate_attack()) self.assertEqual(8, game.current_player.minions[0].health) self.assertEqual(8, game.current_player.minions[0].calculate_max_health()) self.assertEqual("Cenarius", game.current_player.minions[0].card.name) for minion_index in range(1, 3): minion = game.current_player.minions[minion_index] self.assertEqual(9, minion.calculate_attack()) self.assertEqual(9, minion.health) self.assertEqual(9, minion.calculate_max_health()) game.players[1].agent.choose_option = lambda options, player: options[1] game.play_single_turn() game.play_single_turn() self.assertEqual(6, len(game.current_player.minions)) self.assertEqual(5, game.current_player.minions[1].calculate_attack()) self.assertEqual(8, game.current_player.minions[1].health) self.assertEqual(8, game.current_player.minions[1].calculate_max_health()) self.assertEqual("Cenarius", game.current_player.minions[1].card.name) self.assertEqual(2, game.current_player.minions[0].calculate_attack()) self.assertEqual(2, game.current_player.minions[0].health) self.assertEqual(2, game.current_player.minions[0].calculate_max_health()) self.assertTrue(game.current_player.minions[0].taunt) self.assertEqual("Treant", game.current_player.minions[0].card.name) self.assertEqual(2, game.current_player.minions[2].calculate_attack()) self.assertEqual(2, game.current_player.minions[2].health) self.assertEqual(2, game.current_player.minions[2].calculate_max_health()) self.assertTrue(game.current_player.minions[2].taunt) self.assertEqual("Treant", game.current_player.minions[2].card.name)
def test_Swipe(self): deck1 = StackedDeck([BloodfenRaptor(), StonetuskBoar(), StonetuskBoar()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([Swipe()], CHARACTER_CLASS.DRUID, ) game = Game([deck1, deck2], [OneCardPlayingAgent(), EnemyMinionSpellTestingAgent()]) game.pre_game() game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() # The bloodfen raptor should be left, with one hp self.assertEqual(1, len(game.other_player.minions)) self.assertEqual(1, game.other_player.minions[0].health) self.assertEqual(29, game.other_player.hero.health)
def render_game(stdscr): class TextAgent: def __init__(self, game_window, prompt_window, text_window): self.window = prompt_window self.game_window = game_window self.text_window = text_window curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN) def do_turn(self, player): renderer.draw_game() index = 0 action = self.choose_action() while not (action == "quit" or action == "end"): if action == "play": card = self.choose_card(player) if card is not None: player.game.play_card(card) elif action == "attack": attacker = self.choose_attacker(player) if attacker is not None: attacker.attack() elif action == "power": if player.hero.power.can_use(): player.hero.power.use() index += 1 renderer.draw_game() action = self.choose_action() if action == "quit": sys.exit(0) def choose_action(self): self.window.addstr(0, 0, "Choose action") actions = ["play", "attack", "power", "end", "quit"] index = 0 selected = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr( 0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(actions) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(actions): selected = 0 index = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr( 0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return actions[selected] def choose_card(self, player): filtered_cards = [card for card in filter( lambda card: card.can_use(player, player.game), player.hand)] if len(filtered_cards) is 0: return None renderer.targets = filtered_cards renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_attacker(self, player): filtered_attackers = [minion for minion in filter( lambda minion: minion.can_attack(), player.minions)] if player.hero.can_attack(): filtered_attackers.append(player.hero) if len(filtered_attackers) is 0: return None renderer.targets = filtered_attackers renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose attacker") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() self.window.addstr(0, 0, "{0}".format(ch)) self.window.refresh() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def do_card_check(self, cards): self.window.addstr( 0, 0, "Select cards to keep (space selects/deselects a card)") keeping = [True, True, True] if len(cards) > 3: keeping.append(True) index = 0 selected = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr( 0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(cards) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(cards): selected = 0 if ch == 32: keeping[selected] = not keeping[selected] index = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr( 0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return keeping def choose_target(self, targets): if len(targets) is 0: return None renderer.targets = targets renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose target") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_index(self, card, player): renderer.selection_index = 0 renderer.draw_game() self.window.addstr(0, 0, "Choose placement location") self.window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: renderer.selection_index -= 1 if renderer.selection_index < 0: renderer.selection_index = len(player.minions) if ch == curses.KEY_RIGHT: renderer.selection_index += 1 if renderer.selection_index > len(player.minions): renderer.selection_index = 0 renderer.draw_game() self.window.refresh() index = renderer.selection_index renderer.selection_index = -1 if ch == 27: return -1 return index def choose_option(self, options, player): self.window.addstr(0, 0, "Choose option") index = 0 selected = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: starting_selected = selected selected -= 1 if selected < 0: selected = len(options) - 1 while not options[selected].can_choose(player) and selected != starting_selected: selected -= 1 if selected < 0: selected = len(options) - 1 if ch == curses.KEY_RIGHT: starting_selected = selected selected += 1 if selected == len(options): selected = 0 while not options[selected].can_choose(player) and selected != starting_selected: selected += 1 if selected == len(options): selected = 0 index = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return options[selected] class GraphAgent: def __init__(self, game_window, prompt_window, text_window): self.window = prompt_window self.game_window = game_window self.text_window = text_window curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN) def do_turn(self, player): renderer.draw_game() index = 0 action = self.choose_action() while not (action == "quit" or action == "end"): if action == "play": card = self.choose_card(player) if card is not None: player.game.play_card(card) elif action == "attack": attacker = self.choose_attacker(player) if attacker is not None: attacker.attack() elif action == "power": if player.hero.power.can_use(): player.hero.power.use() index += 1 renderer.draw_game() action = self.choose_action() if action == "quit": sys.exit(0) def choose_action(self): self.window.addstr(0, 0, "Choose action") actions = ["play", "attack", "power", "end", "quit"] index = 0 selected = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr( 0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(actions) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(actions): selected = 0 index = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr( 0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return actions[selected] def choose_card(self, player): filtered_cards = [card for card in filter( lambda card: card.can_use(player, player.game), player.hand)] if len(filtered_cards) is 0: return None renderer.targets = filtered_cards renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_attacker(self, player): filtered_attackers = [minion for minion in filter( lambda minion: minion.can_attack(), player.minions)] if player.hero.can_attack(): filtered_attackers.append(player.hero) if len(filtered_attackers) is 0: return None renderer.targets = filtered_attackers renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose attacker") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() self.window.addstr(0, 0, "{0}".format(ch)) self.window.refresh() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def do_card_check(self, cards): self.window.addstr( 0, 0, "Select cards to keep (space selects/deselects a card)") keeping = [True, True, True] if len(cards) > 3: keeping.append(True) index = 0 selected = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr( 0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(cards) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(cards): selected = 0 if ch == 32: keeping[selected] = not keeping[selected] index = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr( 0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return keeping def choose_target(self, targets): if len(targets) is 0: return None renderer.targets = targets renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose target") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_index(self, card, player): renderer.selection_index = 0 renderer.draw_game() self.window.addstr(0, 0, "Choose placement location") self.window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: renderer.selection_index -= 1 if renderer.selection_index < 0: renderer.selection_index = len(player.minions) if ch == curses.KEY_RIGHT: renderer.selection_index += 1 if renderer.selection_index > len(player.minions): renderer.selection_index = 0 renderer.draw_game() self.window.refresh() index = renderer.selection_index renderer.selection_index = -1 if ch == 27: return -1 return index def choose_option(self, options, player): self.window.addstr(0, 0, "Choose option") index = 0 selected = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: starting_selected = selected selected -= 1 if selected < 0: selected = len(options) - 1 while not options[selected].can_choose(player) and selected != starting_selected: selected -= 1 if selected < 0: selected = len(options) - 1 if ch == curses.KEY_RIGHT: starting_selected = selected selected += 1 if selected == len(options): selected = 0 while not options[selected].can_choose(player) and selected != starting_selected: selected += 1 if selected == len(options): selected = 0 index = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return options[selected] def show_text(screen, position, text, color, font_bold=False, font_size=13, font_italic=False): cur_font = pygame.font.SysFont("Monaco", font_size) cur_font.set_bold(font_bold) cur_font.set_italic(font_italic) text_fmt = cur_font.render(text, 1, color) screen.blit(text_fmt, position) def choose_agent(window): agents = registry.get_names() curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) window.addstr(10, 34, "Choose agent") ch = 0 selected = 0 while ch != 10 and ch != 27: index = 0 for agent in agents: if index == selected: color = curses.color_pair(3) else: color = curses.color_pair(0) window.addstr(index + 11, 25, "{:^30}".format(agent), color) index += 1 window.refresh() ch = window.getch() if ch == curses.KEY_UP: selected -= 1 if selected < 0: selected = len(agents) - 1 if ch == curses.KEY_DOWN: selected += 1 if selected == len(agents): selected = 0 window.clear() if ch == 27: sys.exit(0) else: return registry.create_agent(agents[selected]) stdscr.clear() pygame.init() game_window = pygame.display.set_mode((1366, 768), 0, 32) background = pygame.image.load('background.jpg').convert() o_field = pygame.image.load('field.png').convert() end_turn_btn = End_turn_btn(game_window, None, None, (1200, 370)) field_size = width, height = 840, 240 pygame.mouse.set_cursor(*pygame.cursors.tri_left) prompt_window = stdscr.derwin(1, 80, 23, 0) text_window = stdscr.derwin(1, 80, 24, 0) agent = registry.create_agent(registry.get_names()[0]) deck1 = load_deck(sys.argv[1]) deck2 = load_deck(sys.argv[2]) game = Game([deck1, deck2], [TextAgent( stdscr, prompt_window, text_window), agent]) if game.first_player == 0: renderer = GameRender(stdscr, game, game.players[0]) pass else: renderer = GameRender(stdscr, game, game.players[1]) pass current_player = game.players[1] game.pre_game() while(True): pygame.time.Clock().tick(40) for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == pygame.MOUSEMOTION: pass if event.type == pygame.MOUSEBUTTONDOWN: if end_turn_btn.isOver(): end_turn_btn.status = 'hover' pass if event.type == pygame.MOUSEBUTTONUP: if end_turn_btn.isOver(): if end_turn_btn.status == 'hover': game._end_turn() end_turn_btn.status = 'unclicked' else: end_turn_btn.status = 'unclicked' pass #TODO: Render tables game_window.blit(background, (0, 0)) #opponent's field game_window.blit(o_field, ((1366 - 880) / 2, 768 / 2 - height - 1)) #my field game_window.blit(o_field, ((1366 - 880) / 2, 768 / 2 + 1)) end_turn_btn.render() show_text(game_window, (end_turn_btn.position),end_turn_btn.status,(150,150,150)) #TODO: Capture mouse status and generate action pygame.display.update() #刷新一下画面 # self.pre_game() # self.current_player = self.players[1] # while not self.game_ended: # self.play_single_turn() game.start()
def test_MarkOfNature(self): deck1 = StackedDeck([StonetuskBoar(), StonetuskBoar(), MarkOfNature()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) game = Game([deck1, deck2], [OneCardPlayingAgent(), OneCardPlayingAgent()]) game.current_player = 1 game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(5, game.other_player.minions[0].calculate_attack()) deck1 = StackedDeck([StonetuskBoar(), StonetuskBoar(), MarkOfNature()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) agent = OneCardPlayingAgent() agent.choose_option = lambda options, player: options[1] game = Game([deck1, deck2], [agent, OneCardPlayingAgent()]) game.current_player = 1 game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(5, game.other_player.minions[0].calculate_max_health()) self.assertEqual(5, game.other_player.minions[0].health) self.assertTrue(game.other_player.minions[0].taunt)
def test_PowerOfTheWild(self): deck1 = StackedDeck([StonetuskBoar(), StonetuskBoar(), PowerOfTheWild()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) # This is a test of the +1/+1 option of the Power Of the Wild Card game = Game([deck1, deck2], [OneCardPlayingAgent(), OneCardPlayingAgent()]) game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(2, game.current_player.minions[0].calculate_attack()) self.assertEqual(2, game.current_player.minions[0].health) self.assertEqual(2, game.current_player.minions[0].calculate_max_health()) self.assertEqual(2, game.current_player.minions[1].calculate_attack()) self.assertEqual(2, game.current_player.minions[1].calculate_max_health()) # This is a test of the "Summon Panther" option of the Power of the Wild Card agent = OneCardPlayingAgent() agent.choose_option = lambda options, player: options[1] deck1 = StackedDeck([StonetuskBoar(), StonetuskBoar(), PowerOfTheWild()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) game = Game([deck1, deck2], [agent, OneCardPlayingAgent()]) game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual("Panther", game.current_player.minions[2].card.__class__.__name__) self.assertEqual(3, game.current_player.minions[2].calculate_attack()) self.assertEqual(2, game.current_player.minions[2].calculate_max_health())
def _load_object(d): return Game.__from_json__(d)
def render_game(stdscr): class TextAgent: def __init__(self, game_window, prompt_window, text_window): self.window = prompt_window self.game_window = game_window self.text_window = text_window curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN) def do_turn(self, player): renderer.draw_game() index = 0 action = self.choose_action() while not (action == "quit" or action == "end"): if action == "play": card = self.choose_card(player) if card is not None: player.game.play_card(card) elif action == "attack": attacker = self.choose_attacker(player) if attacker is not None: attacker.attack() elif action == "power": if player.hero.power.can_use(): player.hero.power.use() elif action == "state": current_state.export_state() index += 1 renderer.draw_game() action = self.choose_action() if action == "quit": sys.exit(0) def choose_action(self): self.window.addstr(0, 0, "Choose action") actions = ["play", "attack", "power", "end", "state", "quit"] index = 0 selected = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(actions) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(actions): selected = 0 index = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return actions[selected] def choose_card(self, player): filtered_cards = [ card for card in filter( lambda card: card.can_use(player, player.game), player.hand) ] if len(filtered_cards) is 0: return None renderer.targets = filtered_cards renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_attacker(self, player): filtered_attackers = [ minion for minion in filter(lambda minion: minion.can_attack(), player.minions) ] if player.hero.can_attack(): filtered_attackers.append(player.hero) if len(filtered_attackers) is 0: return None renderer.targets = filtered_attackers renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose attacker") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() self.window.addstr(0, 0, "{0}".format(ch)) self.window.refresh() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def do_card_check(self, cards): self.window.addstr( 0, 0, "Select cards to keep (space selects/deselects a card)") keeping = [True, True, True] if len(cards) > 3: keeping.append(True) index = 0 selected = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(cards) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(cards): selected = 0 if ch == 32: keeping[selected] = not keeping[selected] index = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return keeping def choose_target(self, targets): if len(targets) is 0: return None renderer.targets = targets renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose target") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_index(self, card, player): renderer.selection_index = 0 renderer.draw_game() self.window.addstr(0, 0, "Choose placement location") self.window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: renderer.selection_index -= 1 if renderer.selection_index < 0: renderer.selection_index = len(player.minions) if ch == curses.KEY_RIGHT: renderer.selection_index += 1 if renderer.selection_index > len(player.minions): renderer.selection_index = 0 renderer.draw_game() self.window.refresh() index = renderer.selection_index renderer.selection_index = -1 if ch == 27: return -1 return index def choose_option(self, options, player): self.window.addstr(0, 0, "Choose option") index = 0 selected = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr(0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: starting_selected = selected selected -= 1 if selected < 0: selected = len(options) - 1 while not options[selected].can_choose( player) and selected != starting_selected: selected -= 1 if selected < 0: selected = len(options) - 1 if ch == curses.KEY_RIGHT: starting_selected = selected selected += 1 if selected == len(options): selected = 0 while not options[selected].can_choose( player) and selected != starting_selected: selected += 1 if selected == len(options): selected = 0 index = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr( 0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return options[selected] def choose_agent(window): agents = registry.get_names() curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) window.addstr(10, 34, "Choose agent") ch = 0 selected = 0 while ch != 10 and ch != 27: index = 0 for agent in agents: if index == selected: color = curses.color_pair(3) else: color = curses.color_pair(0) window.addstr(index + 11, 25, "{:^30}".format(agent), color) index += 1 window.refresh() ch = window.getch() if ch == curses.KEY_UP: selected -= 1 if selected < 0: selected = len(agents) - 1 if ch == curses.KEY_DOWN: selected += 1 if selected == len(agents): selected = 0 window.clear() if ch == 27: sys.exit(0) else: return registry.create_agent(agents[selected]) stdscr.clear() prompt_window = stdscr.derwin(1, 80, 23, 0) text_window = stdscr.derwin(1, 80, 24, 0) agent = choose_agent(stdscr) deck1 = load_deck(sys.argv[1]) deck2 = load_deck(sys.argv[2]) game = Game([deck1, deck2], [TextAgent(stdscr, prompt_window, text_window), agent]) current_state = State(game) if game.first_player == 0: renderer = GameRender(stdscr, game, game.players[0]) else: renderer = GameRender(stdscr, game, game.players[1]) game.start()
def test_Swipe(self): deck1 = StackedDeck( [BloodfenRaptor(), StonetuskBoar(), StonetuskBoar()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck( [Swipe()], CHARACTER_CLASS.DRUID, ) game = Game([deck1, deck2], [OneCardPlayingAgent(), EnemyMinionSpellTestingAgent()]) game.pre_game() game.current_player = game.players[1] game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() # The bloodfen raptor should be left, with one hp self.assertEqual(1, len(game.other_player.minions)) self.assertEqual(1, game.other_player.minions[0].health) self.assertEqual(29, game.other_player.hero.health)
def test_RandomAgent(self): deck1 = Deck([ GoldshireFootman(), GoldshireFootman(), MurlocRaider(), MurlocRaider(), BloodfenRaptor(), BloodfenRaptor(), FrostwolfGrunt(), FrostwolfGrunt(), RiverCrocolisk(), RiverCrocolisk(), IronfurGrizzly(), IronfurGrizzly(), MagmaRager(), MagmaRager(), SilverbackPatriarch(), SilverbackPatriarch(), ChillwindYeti(), ChillwindYeti(), KeeperOfTheGrove(), KeeperOfTheGrove(), SenjinShieldmasta(), SenjinShieldmasta(), BootyBayBodyguard(), BootyBayBodyguard(), FenCreeper(), FenCreeper(), BoulderfistOgre(), BoulderfistOgre(), WarGolem(), WarGolem(), ], Malfurion()) deck2 = Deck([ Shieldbearer(), Shieldbearer(), FlameImp(), FlameImp(), YoungPriestess(), YoungPriestess(), DarkIronDwarf(), DarkIronDwarf(), DireWolfAlpha(), DireWolfAlpha(), Voidwalker(), Voidwalker(), HarvestGolem(), HarvestGolem(), KnifeJuggler(), KnifeJuggler(), ShatteredSunCleric(), ShatteredSunCleric(), ArgentSquire(), ArgentSquire(), Doomguard(), Doomguard(), Soulfire(), Soulfire(), DefenderOfArgus(), DefenderOfArgus(), AbusiveSergeant(), AbusiveSergeant(), NerubianEgg(), NerubianEgg(), ], Guldan()) game = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) game.pre_game() game.current_player = game.players[1] game.play_single_turn() self.assertEqual(0, len(game.current_player.minions)) game.play_single_turn() self.assertEqual(2, len(game.current_player.minions)) self.assertEqual(3, game.current_player.minions[1].health) self.assertEqual("Young Priestess", game.current_player.minions[0].card.name) game.play_single_turn() self.assertEqual(1, len(game.current_player.minions)) self.assertEqual("Frostwolf Grunt", game.current_player.minions[0].card.name) game.play_single_turn() self.assertEqual(0, len(game.other_player.minions)) self.assertEqual(28, game.other_player.hero.health) self.assertEqual(3, len(game.current_player.minions)) self.assertEqual("Dire Wolf Alpha", game.current_player.minions[2].card.name) for turn in range(0, 13): game.play_single_turn() self.assertFalse(game.game_ended) game.play_single_turn() self.assertEqual(0, game.current_player.hero.health) self.assertEqual(21, game.other_player.hero.health) self.assertTrue(game.game_ended)
def test_recording_game(self): self.maxDiff = None # change random to a certain seed to reproduce the replay #random.seed(9876) random.seed() deck1name = "pat_face_hunter.hsdeck" deck2name = "pat_zoolock.hsdeck" # below decks work, will try hunter v zoolock above #deck1name = "pat_freeze_mage.hsdeck" #deck2name = "pat_midrange_druid.hsdeck" # testing custom decks # need to convert card names to the actual functions deck1 = self.load_deck(deck1name) deck2 = self.load_deck(deck2name) # below are what works #deck1 = hearthbreaker.engine.Deck([StonetuskBoar() for i in range(0, 30)], Jaina()) #deck2 = hearthbreaker.engine.Deck([Naturalize() for i in range(0, 30)], Malfurion()) # PredictableAgent() works, let's try TradeAgent() agent1 = TradeAgent() agent2 = TradeAgent() # agent1 = PredictableAgent() # agent2 = PredictableAgent() game = Game([deck1, deck2], [agent1, agent2]) replay = record(game) game.start() output = StringIO() replay.write_json(output) with open('pat_replay_2.hsreplay', mode='w') as f: print(output.getvalue(), file=f) # testing something 2021_3_15 # ast.literal_eval("{'muffin' : 'lolz', 'foo' : 'kitty'}") replay_json = ast.literal_eval(output.getvalue()) # { #"character": { # "minion": 2, # "player": "p1" # }, # "name": "attack", # "target": { # "player": "p2" # } #}, # { # "name": "end" # } #] #} # last move is always "name": "end" since that's last action taken # so get the move before last_move = replay_json['moves'][-2] # above works fine, need to filter based on results # will take a sample of 10 different replays print("the last move is {}".format(last_move)) # it depends on the last move, we need to check for different situations # first situation is a minion killing a player if last_move['character']: print(last_move['character']) # minion could be 0 if last_move['character']['minion'] is not None: if last_move['target']['player']: dead_player = str(last_move['target']['player']) print("player {} died".format(dead_player)) with open('pat_who_wins.txt', mode='a') as f: print(dead_player, file=f)
def playback(replay): """ Create a game which can be replayed back out of a replay. :param replay: The replay to load the game out of :type replay: :class:`Replay` :return: A game which when played will perform all of the actions in the replay. :rtype: :class:`Game <hearthbreaker.game_objects.Game>` """ move_index = -1 k_index = 0 random_index = 0 game = None class ReplayAgent: def __init__(self): self.next_target = None self.next_index = -1 self.next_option = None def do_card_check(self, cards): nonlocal k_index keep_arr = [False] * len(cards) for index in replay.keeps[k_index]: keep_arr[int(index)] = True k_index += 1 return keep_arr def do_turn(self, player): nonlocal move_index, random_index while move_index < len(replay._moves) and not player.hero.dead and type( replay._moves[move_index]) is not hearthbreaker.serialization.move.TurnEndMove: random_index = 0 replay._moves[move_index].play(game) move_index += 1 if move_index == len(replay._moves): player.game.game_ended = True def set_game(self, game): pass def choose_target(self, targets): return self.next_target def choose_index(self, card, player): return self.next_index def choose_option(self, options, player): return options[self.next_option] game = Game.__new__(Game) _old_random_choice = game.random_choice _old_start_turn = game._start_turn _old_end_turn = game._end_turn _old_pre_game = game.pre_game def _generate_random_between(lowest, highest): nonlocal random_index if len(replay.random) == 0: return 0 else: random_index += 1 if move_index == -1: return replay.random[random_index - 1] return replay._moves[move_index].random_numbers[random_index - 1] def random_choice(choice): nonlocal move_index, random_index if isinstance(replay._moves[move_index].random_numbers[random_index], hearthbreaker.proxies.ProxyCharacter): result = replay._moves[move_index].random_numbers[random_index].resolve(game) random_index += 1 return result return _old_random_choice(choice) def _start_turn(): nonlocal move_index, random_index random_index = 0 _old_start_turn() move_index += 1 def _end_turn(): nonlocal move_index, random_index random_index = 0 _old_end_turn() move_index += 1 def pre_game(): nonlocal move_index _old_pre_game() move_index = 0 game.random_choice = random_choice game._generate_random_between = _generate_random_between game._end_turn = _end_turn game._start_turn = _start_turn game.pre_game = pre_game game.__init__(replay.decks, [ReplayAgent(), ReplayAgent()]) return game
def render_game(stdscr): class TextAgent: def __init__(self, game_window, prompt_window, text_window): self.window = prompt_window self.game_window = game_window self.text_window = text_window curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN) def do_turn(self, player): renderer.draw_game() index = 0 action = self.choose_action() while not (action == "quit" or action == "end"): if action == "play": card = self.choose_card(player) if card is not None: player.game.play_card(card) elif action == "attack": attacker = self.choose_attacker(player) if attacker is not None: attacker.attack() elif action == "power": if player.hero.power.can_use(): player.hero.power.use() index += 1 renderer.draw_game() action = self.choose_action() if action == "quit": sys.exit(0) def choose_action(self): self.window.addstr(0, 0, "Choose action") actions = ["play", "attack", "power", "end", "quit"] index = 0 selected = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(actions) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(actions): selected = 0 index = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return actions[selected] def choose_card(self, player): filtered_cards = [card for card in filter(lambda card: card.can_use(player, player.game), player.hand)] if len(filtered_cards) is 0: return None renderer.targets = filtered_cards renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_attacker(self, player): filtered_attackers = [minion for minion in filter(lambda minion: minion.can_attack(), player.minions)] if player.hero.can_attack(): filtered_attackers.append(player.hero) if len(filtered_attackers) is 0: return None renderer.targets = filtered_attackers renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose attacker") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() self.window.addstr(0, 0, "{0}".format(ch)) self.window.refresh() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def do_card_check(self, cards): self.window.addstr(0, 0, "Select cards to keep (space selects/deselects a card)") keeping = [True, True, True] if len(cards) > 3: keeping.append(True) index = 0 selected = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(cards) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(cards): selected = 0 if ch == 32: keeping[selected] = not keeping[selected] index = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return keeping def choose_target(self, targets): if len(targets) is 0: return None renderer.targets = targets renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose target") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_index(self, card, player): renderer.selection_index = 0 renderer.draw_game() self.window.addstr(0, 0, "Choose placement location") self.window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: renderer.selection_index -= 1 if renderer.selection_index < 0: renderer.selection_index = len(player.minions) if ch == curses.KEY_RIGHT: renderer.selection_index += 1 if renderer.selection_index > len(player.minions): renderer.selection_index = 0 renderer.draw_game() self.window.refresh() index = renderer.selection_index renderer.selection_index = -1 if ch == 27: return -1 return index def choose_option(self, options, player): self.window.addstr(0, 0, "Choose option") index = 0 selected = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr(0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr(0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: starting_selected = selected selected -= 1 if selected < 0: selected = len(options) - 1 while not options[selected].can_choose(player) and selected != starting_selected: selected -= 1 if selected < 0: selected = len(options) - 1 if ch == curses.KEY_RIGHT: starting_selected = selected selected += 1 if selected == len(options): selected = 0 while not options[selected].can_choose(player) and selected != starting_selected: selected += 1 if selected == len(options): selected = 0 index = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr(0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr(0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return options[selected] def exit_word(window, string): window.clear() window.addstr(0, 0, string + " " + "Game is ending in 5 seconds.") window.refresh() time.sleep(5) sys.exit() def log(string): with open("demo_log.txt", "a+") as f: f.write(str(time.ctime()) + " " + string) stdscr.clear() prompt_window = stdscr.derwin(1, 80, 23, 0) text_window = stdscr.derwin(1, 80, 24, 0) generator = RandomDeckGenerator() path = "models/st_fs_deep_neural_40000.t" with open(path, "rb") as f: model = pickle.load(f) agent = StrategyAgent(model, "AI", 5) deck1 = generator.generate() deck2 = deck1.copy() game = Game([deck1, deck2], [TextAgent(stdscr, prompt_window, text_window), agent]) if game.first_player == 0: renderer = GameRender(stdscr, game, game.players[0]) else: renderer = GameRender(stdscr, game, game.players[1]) try: game.start() except Exception as e: exit_word(text_window, "Sorry, an error occurred.") if game.game_ended: if not game.winner is None: if game.winner.agent is agent: log("AI win.") exit_word(prompt_window, "You lost!") else: log("Human win.") exit_word(prompt_window, "You won!") else: log("Draw.") exit_word(prompt_window, "There is no winner!")
# index += 1 # self.window.refresh() # self.text_window.refresh() # if ch == 27: # return None # # return options[selected] if __name__ == '__main__': if len(sys.argv) < 3: port = int(sys.argv[2]) print('Usage: COMMAND host port') sys.exit(1) deck1 = load_deck("zoo.hsdeck") deck2 = load_deck("zoo.hsdeck") logfile = open('hearthbreaker.log', 'a') while True: agent = WebAgent(sys.argv[1], sys.argv[2]) ggame = Game([deck1, deck2], [(agent, "webagent"), (SimpleUCTAgent(0.2, 10), "uct")]) try: ggame.start() agent.reconnect() except ConnectionResetError: logfile.write('Restart game due to connection reset\n') agent.reconnect() except Exception as e: traceback.print_exc(file=logfile) logfile.write('\n') agent.reconnect()
def playback(replay): """ Create a game which can be replayed back out of a replay. :param replay: The replay to load the game out of :type replay: :class:`Replay` :return: A game which when played will perform all of the actions in the replay. :rtype: :class:`Game <hearthbreaker.game_objects.Game>` """ move_index = -1 k_index = 0 random_index = 0 game = None class ReplayAgent: def __init__(self): self.next_target = None self.next_index = -1 self.next_option = None def do_card_check(self, cards): nonlocal k_index keep_arr = [False] * len(cards) for index in replay.keeps[k_index]: keep_arr[int(index)] = True k_index += 1 return keep_arr def do_turn(self, player): nonlocal move_index, random_index while move_index < len( replay._moves) and not player.hero.dead and type( replay._moves[move_index] ) is not hearthbreaker.serialization.move.TurnEndMove: random_index = 0 replay._moves[move_index].play(game) move_index += 1 if move_index == len(replay._moves): player.game.game_ended = True def set_game(self, game): pass def choose_target(self, targets): return self.next_target def choose_index(self, card, player): return self.next_index def choose_option(self, options, player): return options[self.next_option] game = Game.__new__(Game) _old_random_choice = game.random_choice _old_start_turn = game._start_turn _old_end_turn = game._end_turn _old_pre_game = game.pre_game def _generate_random_between(lowest, highest): nonlocal random_index if len(replay.random) == 0: return 0 else: random_index += 1 if move_index == -1: return replay.random[random_index - 1] return replay._moves[move_index].random_numbers[random_index - 1] def random_choice(choice): nonlocal move_index, random_index if isinstance(replay._moves[move_index].random_numbers[random_index], hearthbreaker.proxies.ProxyCharacter): result = replay._moves[move_index].random_numbers[ random_index].resolve(game) random_index += 1 return result return _old_random_choice(choice) def _start_turn(): nonlocal move_index, random_index random_index = 0 _old_start_turn() move_index += 1 def _end_turn(): nonlocal move_index, random_index random_index = 0 _old_end_turn() move_index += 1 def pre_game(): nonlocal move_index _old_pre_game() move_index = 0 game.random_choice = random_choice game._generate_random_between = _generate_random_between game._end_turn = _end_turn game._start_turn = _start_turn game.pre_game = pre_game game.__init__(replay.decks, [ReplayAgent(), ReplayAgent()]) return game
def test_ManaWyrm(self): deck1 = StackedDeck([ManaWyrm(), IceLance(), ManaWyrm(), IceLance(), IceLance(), IceLance()], CHARACTER_CLASS.MAGE) deck2 = StackedDeck([IronbeakOwl()], CHARACTER_CLASS.PALADIN) game = Game([deck1, deck2], [CardTestingAgent(), OneCardPlayingAgent()]) game.pre_game() game.current_player = 1 game.play_single_turn() self.assertEqual(1, len(game.current_player.minions)) self.assertEqual(1, game.current_player.minions[0].calculate_attack()) self.assertEqual(3, game.current_player.minions[0].health) self.assertEqual(3, game.current_player.minions[0].calculate_max_health()) self.assertEqual("Mana Wyrm", game.current_player.minions[0].card.name) game.play_single_turn() game.play_single_turn() self.assertEqual(2, len(game.current_player.minions)) self.assertEqual(1, game.current_player.minions[0].calculate_attack()) self.assertEqual(3, game.current_player.minions[0].health) self.assertEqual(3, game.current_player.minions[0].calculate_max_health()) self.assertEqual(2, game.current_player.minions[1].calculate_attack()) self.assertEqual(3, game.current_player.minions[1].health) self.assertEqual(3, game.current_player.minions[1].calculate_max_health()) game.play_single_turn() game.play_single_turn() self.assertEqual(2, len(game.current_player.minions)) self.assertEqual(1, game.current_player.minions[0].calculate_attack()) self.assertEqual(3, game.current_player.minions[0].health) self.assertEqual(3, game.current_player.minions[0].calculate_max_health()) self.assertEqual(5, game.current_player.minions[1].calculate_attack()) self.assertEqual(3, game.current_player.minions[1].health) self.assertEqual(3, game.current_player.minions[1].calculate_max_health())
def render_game(stdscr): class TextAgent: def __init__(self, game_window, prompt_window, text_window): self.window = prompt_window self.game_window = game_window self.text_window = text_window curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(6, curses.COLOR_BLACK, curses.COLOR_GREEN) def do_turn(self, player): renderer.draw_game() index = 0 action = self.choose_action() while not (action == "quit" or action == "end"): if action == "play": card = self.choose_card(player) if card is not None: player.game.play_card(card) elif action == "attack": attacker = self.choose_attacker(player) if attacker is not None: attacker.attack() elif action == "power": if player.hero.power.can_use(): player.hero.power.use() index += 1 renderer.draw_game() action = self.choose_action() if action == "quit": sys.exit(0) def choose_action(self): self.window.addstr(0, 0, "Choose action") actions = ["play", "attack", "power", "end", "quit"] index = 0 selected = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(actions) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(actions): selected = 0 index = 0 for action in actions: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) self.text_window.addstr(0, index * 10, "{0:^9}".format(action), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: sys.exit(0) #return None return actions[selected] def choose_card(self, player): filtered_cards = [card for card in filter(lambda card: card.can_use(player, player.game), player.hand)] if len(filtered_cards) is 0: return None renderer.targets = filtered_cards renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() self.window.addstr(0, 0, "Choose Card") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_attacker(self, player): filtered_attackers = [minion for minion in filter(lambda minion: minion.can_attack(), player.minions)] if player.hero.can_attack(): filtered_attackers.append(player.hero) if len(filtered_attackers) is 0: return None renderer.targets = filtered_attackers renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose attacker") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() self.window.addstr(0, 0, "{0}".format(ch)) self.window.refresh() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() #fix self.window.addstr(0, 0, "Choose attacker") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def do_card_check(self, cards): self.game_window.clear() #fix #self.window.addstr(0, 0, "Select cards to keep (space selects/deselects a card)") self.game_window.addstr(10, 0, "Select cards to keep (space selects/deselects a card). esc to 离开") keeping = [True, True, True] if len(cards) > 3: keeping.append(True) index = 0 selected = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) #self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) self.game_window.addstr(11, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.window.refresh() #self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: selected -= 1 if selected < 0: selected = len(cards) - 1 if ch == curses.KEY_RIGHT: selected += 1 if selected == len(cards): selected = 0 if ch == 32: keeping[selected] = not keeping[selected] index = 0 for card in cards: if keeping[index]: if index == selected: color = curses.color_pair(6) else: color = curses.color_pair(5) else: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(0) #self.text_window.addstr(0, index * 20, "{0:^19}".format(card.name[:19]), color) self.game_window.addstr(11, index * 20, "{0:^19}".format(card.name[:19]), color) index += 1 self.game_window.refresh() #self.text_window.refresh() if ch == 27: #return None sys.exit(0) return keeping def choose_target(self, targets): if len(targets) is 0: return None renderer.targets = targets renderer.selected_target = renderer.targets[0] renderer.draw_game() self.window.addstr(0, 0, "Choose target") self.window.refresh() ch = 0 index = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: index -= 1 if index < 0: index = len(renderer.targets) - 1 if ch == curses.KEY_RIGHT: index += 1 if index == len(renderer.targets): index = 0 renderer.selected_target = renderer.targets[index] renderer.draw_game() #fix self.window.addstr(0, 0, "Choose target") self.window.refresh() renderer.targets = None if ch == 27: return None return renderer.selected_target def choose_index(self, card, player): renderer.selection_index = 0 renderer.draw_game() self.window.addstr(0, 0, "Choose placement location") self.window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: renderer.selection_index -= 1 if renderer.selection_index < 0: renderer.selection_index = len(player.minions) if ch == curses.KEY_RIGHT: renderer.selection_index += 1 if renderer.selection_index > len(player.minions): renderer.selection_index = 0 renderer.draw_game() self.window.refresh() index = renderer.selection_index renderer.selection_index = -1 if ch == 27: return -1 return index def choose_option(self, options, player): self.window.addstr(0, 0, "Choose option") index = 0 selected = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr(0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr(0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() ch = 0 while ch != 10 and ch != 27: ch = self.game_window.getch() if ch == curses.KEY_LEFT: starting_selected = selected selected -= 1 if selected < 0: selected = len(options) - 1 while not options[selected].can_choose(player) and selected != starting_selected: selected -= 1 if selected < 0: selected = len(options) - 1 if ch == curses.KEY_RIGHT: starting_selected = selected selected += 1 if selected == len(options): selected = 0 while not options[selected].can_choose(player) and selected != starting_selected: selected += 1 if selected == len(options): selected = 0 index = 0 for option in options: if index == selected: color = curses.color_pair(4) else: color = curses.color_pair(3) if isinstance(option, Card): self.text_window.addstr(0, index * 20, "{0:^19}".format(option.name[:19]), color) else: self.text_window.addstr(0, index * 20, "{0:^19}".format(option.card.name[:19]), color) index += 1 self.window.refresh() self.text_window.refresh() if ch == 27: return None return options[selected] def choose_agent(window): agents = registry.get_names() curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_BLUE) window.addstr(10, 34, "Choose agent") ch = 0 selected = 0 while ch != 10 and ch != 27: index = 0 for agent in agents: if index == selected: color = curses.color_pair(3) else: color = curses.color_pair(0) window.addstr(index + 11, 25, "{:^30}".format(agent), color) index += 1 window.refresh() ch = window.getch() if ch == curses.KEY_UP: selected -= 1 if selected < 0: selected = len(agents) - 1 if ch == curses.KEY_DOWN: selected += 1 if selected == len(agents): selected = 0 window.clear() if ch == 27: sys.exit(0) else: return registry.create_agent(agents[selected]) #render_game stdscr.clear() #prompt_window = stdscr.derwin(1, 80, 23, 0) #text_window = stdscr.derwin(1, 80, 24, 0) game_window = stdscr prompt_window = stdscr.derwin(1, 80, 23, 0) text_window = stdscr.derwin(1, 80, 24, 0) #prompt_window = curses.newwin(1, 80, 21, 0) #text_window = curses.newwin(1, 80, 22, 0) agent = choose_agent(stdscr) #deck1 = load_deck(sys.argv[1]) #deck2 = load_deck(sys.argv[2]) deck1 = load_deck('example.hsdeck') deck2 = load_deck('example.hsdeck') #game = Game([deck1, deck2], [TextAgent(stdscr, prompt_window, text_window), agent]) game = Game([deck1, deck2], [TextAgent(game_window, prompt_window, text_window), agent]) if game.first_player == 0: renderer = GameRender(stdscr, game, game.players[0]) else: renderer = GameRender(stdscr, game, game.players[1]) game.start()
def test_MarkOfNature(self): deck1 = StackedDeck( [StonetuskBoar(), StonetuskBoar(), MarkOfNature()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) game = Game([deck1, deck2], [OneCardPlayingAgent(), OneCardPlayingAgent()]) game.current_player = 1 game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(5, game.other_player.minions[0].calculate_attack()) deck1 = StackedDeck( [StonetuskBoar(), StonetuskBoar(), MarkOfNature()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.MAGE) agent = OneCardPlayingAgent() agent.choose_option = lambda options, player: options[1] game = Game([deck1, deck2], [agent, OneCardPlayingAgent()]) game.current_player = 1 game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(5, game.other_player.minions[0].calculate_max_health()) self.assertEqual(5, game.other_player.minions[0].health) self.assertTrue(game.other_player.minions[0].taunt)
def serialization_copy(old_game): game_json = json.dumps(old_game, default=_save_object, indent=2) d = json.loads(game_json) game = Game.__from_json__(d, [player.agent for player in old_game.players]) game._has_turn_ended = old_game._has_turn_ended return game
def test_Cenarius(self): deck1 = StackedDeck([StonetuskBoar()], CHARACTER_CLASS.DRUID) deck2 = StackedDeck( [WarGolem(), WarGolem(), Cenarius(), Cenarius()], CHARACTER_CLASS.DRUID) game = Game([deck1, deck2], [DoNothingAgent(), OneCardPlayingAgent()]) game.pre_game() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() game.play_single_turn() self.assertEqual(2, len(game.other_player.minions)) for minion in game.other_player.minions: self.assertEqual(7, minion.calculate_attack()) self.assertEqual(7, minion.health) self.assertEqual(7, minion.calculate_max_health()) game.play_single_turn() self.assertEqual(3, len(game.current_player.minions)) self.assertEqual(5, game.current_player.minions[0].calculate_attack()) self.assertEqual(8, game.current_player.minions[0].health) self.assertEqual(8, game.current_player.minions[0].calculate_max_health()) self.assertEqual("Cenarius", game.current_player.minions[0].card.name) for minion_index in range(1, 3): minion = game.current_player.minions[minion_index] self.assertEqual(9, minion.calculate_attack()) self.assertEqual(9, minion.health) self.assertEqual(9, minion.calculate_max_health()) game.players[1].agent.choose_option = lambda options, player: options[1 ] game.play_single_turn() game.play_single_turn() self.assertEqual(6, len(game.current_player.minions)) self.assertEqual(5, game.current_player.minions[1].calculate_attack()) self.assertEqual(8, game.current_player.minions[1].health) self.assertEqual(8, game.current_player.minions[1].calculate_max_health()) self.assertEqual("Cenarius", game.current_player.minions[1].card.name) self.assertEqual(2, game.current_player.minions[0].calculate_attack()) self.assertEqual(2, game.current_player.minions[0].health) self.assertEqual(2, game.current_player.minions[0].calculate_max_health()) self.assertTrue(game.current_player.minions[0].taunt) self.assertEqual("Treant", game.current_player.minions[0].card.name) self.assertEqual(2, game.current_player.minions[2].calculate_attack()) self.assertEqual(2, game.current_player.minions[2].health) self.assertEqual(2, game.current_player.minions[2].calculate_max_health()) self.assertTrue(game.current_player.minions[2].taunt) self.assertEqual("Treant", game.current_player.minions[2].card.name)
def bulid_starting_hands(deck_1, deck_2): starting_hands1 = list(itertools.combinations(deck_1.cards, 2)) starting_hands2 = list(itertools.combinations(deck_2.cards, 2)) deck1 = load_deck("patron.hsdeck") deck2 = load_deck("zoo.hsdeck") ''' for i in range(len(deck1.cards)): print(type(deck1.cards[i].name)) print(deck1.cards[i].name) ''' game1 = Game([deck1, deck2], [RandomAgent(), RandomAgent()]) root = build_tree.RootChanceGameState(game1) print('tree built') X1 = [] Y1 = [] X2 = [] Y2 = [] nash1 = [] nash2 = [] chance_sampling_cfr = ChanceSamplingCFR(root) for i in range(100): X1.append(i * 10)