def setUp(self): self.ability_1 = {'deal_damage_to_opponent': partial(abilities.deal_damage_to_opposite_player, damage=2)} self.ability_2 = {DIVINE_SHIELD: abilities.divine_shield} self.ability_charge = {CHARGE: abilities.charge} self.card_1 = Minion(name='C1', cost=1, abilities=dict(), attack=1, health=1, minion_type=None) self.card_2 = Minion(name='C2', cost=1, abilities=dict(), attack=1, health=1, minion_type=None) self.card_3 = Minion(name='C3', cost=1, abilities=dict(), attack=2, health=2, minion_type=None) self.card_4 = Minion(name='C4', cost=1, abilities=dict(), attack=2, health=2, minion_type=None) self.card_5 = Minion(name='C5', cost=1, abilities=dict(), attack=3, health=3, minion_type=None) self.card_6 = Minion(name='C6', cost=1, abilities=dict(), attack=3, health=3, minion_type=None) self.card_7 = Minion(name='C7', cost=1, abilities=dict(), attack=4, health=4, minion_type=None) self.card_8 = Minion(name='C8', cost=1, abilities=dict(), attack=4, health=4, minion_type=None) self.spell_1 = Spell(name='PaSpell', cost=1, abilities={**self.ability_1, **self.ability_2}) self.hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.first_player = Player(self.hero_1, [], [], [], []) self.second_player = Player(self.hero_2, [], [], [], []) self.state = State(self.first_player, self.second_player)
def setUp(self): with open(CARDS_FILE) as json_file: data = json.load(json_file) self.abusive_sergeant = card_from_json(data[0]) self.agent_squire = card_from_json(data[1]) self.divine_strength = card_from_json(data[2]) self.selfless_hero = card_from_json(data[3]) self.divine_favor = card_from_json(data[4]) self.seal_of_champions = card_from_json(data[5]) self.steward_of_darshire = card_from_json(data[6]) self.wolfrider = card_from_json(data[7]) self.blessing_of_kings = card_from_json(data[8]) self.defender_of_argus = card_from_json(data[9]) self.hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.first_player = Player(self.hero_1, [], [], [], []) self.second_player = Player(self.hero_2, [], [], [], []) self.state = State(self.first_player, self.second_player)
def game(): deck1, deck2 = build_decks() hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) first_player = Player(hero_1, [], deck1, [], []) second_player = Player(hero_2, [], deck2, [], []) state = State(first_player, second_player) for i in range(2): state.draw_card() state.switch_players() for i in range(3): state.draw_card() state.switch_players() for mana in range(1, 10): state.draw_card() print("Player {}".format(1)) print("Hand: {}".format([(minion.name, minion.cost) for minion in state.current_player.hand])) for card in state.current_player.board: card.summoning_sickness = False state = get_new_state(state, mana, evaluation_utils.offensive_strategy) print("Player 1 health = {} \nPlayer 2 health = {}".format( state.current_player.hero.health, state.opposite_player.hero.health)) state.switch_players() state.draw_card() print("\nPlayer {}".format(2)) print("Hand: {}".format([(minion.name, minion.cost) for minion in state.current_player.hand])) for card in state.current_player.board: card.summoning_sickness = False state = get_new_state(state, mana, evaluation_utils.offensive_strategy) print("Player 1 health = {} \nPlayer 2 health = {}".format( state.current_player.hero.health, state.opposite_player.hero.health)) state.switch_players() print("\n----------------\n") if state.is_terminal: break
def start_mcts_vs_passive(): deck1, deck2 = build_decks() hero_1 = Hero(name='MCTS', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) hero_2 = Hero(name='Agent', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) first_player = Player(hero_1, [], deck1, [], []) second_player = Player(hero_2, [], deck2, [], []) state = State(first_player, second_player) state.draw_card() state.draw_card() state.switch_players() state.draw_card() state.draw_card() state.draw_card() turns = 1 root_wins = [] root_loses = [] best_child_wins = [] best_child_losses = [] visited_nodes = [] while not state.is_terminal: # state.new_turn_for_one_player() # state.switch_players() start_node = get_node_from_state(state) best_child = perform_mcts(start_node) state, path = best_child['state'], best_child['path'] root_wins.append(start_node['wins']) root_loses.append(start_node['losses']) best_child_wins.append(best_child['wins']) best_child_losses.append(best_child['losses']) visited_nodes.append(start_node['wins'] + start_node['losses']) #print("\n\nAction taken by {}: {}\n\n".format(state.current_player.name, path)) #print_state(state.get_player_by_name(hero_1.name), state.get_player_by_name(hero_2.name)) if state.is_terminal: break state.new_turn_for_one_player() state, path = get_new_state(state, evaluation_utils.passive_strategy) #print("\n\nAction taken by {}: {}\n\n".format(state.current_player.name, path)) #print_state(state.get_player_by_name(hero_1.name), state.get_player_by_name(hero_2.name)) turns += 1 mcts_win = 1 if state.get_player_by_name('Agent').health == 0 else 0 #print_state(state.get_player_by_name(hero_1.name), state.get_player_by_name(hero_2.name)) return turns, root_wins, root_loses, best_child_wins, best_child_losses, visited_nodes, mcts_win
class TestCards(unittest.TestCase): def setUp(self): self.ability_1 = {'deal_damage_to_opponent': partial(abilities.deal_damage_to_opposite_player, damage=2)} self.ability_2 = {DIVINE_SHIELD: abilities.divine_shield} self.ability_charge = {CHARGE: abilities.charge} self.card_1 = Minion(name='C1', cost=1, abilities=dict(), attack=1, health=1, minion_type=None) self.card_2 = Minion(name='C2', cost=1, abilities=dict(), attack=1, health=1, minion_type=None) self.card_3 = Minion(name='C3', cost=1, abilities=dict(), attack=2, health=2, minion_type=None) self.card_4 = Minion(name='C4', cost=1, abilities=dict(), attack=2, health=2, minion_type=None) self.card_5 = Minion(name='C5', cost=1, abilities=dict(), attack=3, health=3, minion_type=None) self.card_6 = Minion(name='C6', cost=1, abilities=dict(), attack=3, health=3, minion_type=None) self.card_7 = Minion(name='C7', cost=1, abilities=dict(), attack=4, health=4, minion_type=None) self.card_8 = Minion(name='C8', cost=1, abilities=dict(), attack=4, health=4, minion_type=None) self.spell_1 = Spell(name='PaSpell', cost=1, abilities={**self.ability_1, **self.ability_2}) self.hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.first_player = Player(self.hero_1, [], [], [], []) self.second_player = Player(self.hero_2, [], [], [], []) self.state = State(self.first_player, self.second_player) def test_play_spell(self): self.first_player.hand = [self.card_1, self.spell_1] self.first_player.board = [self.card_3] self.state.play_card(1) self.assertEqual(self.first_player.hand, [self.card_1]) self.assertEqual(self.first_player.board, [self.card_3]) self.assertEqual(self.first_player.graveyard, [self.spell_1]) self.assertEqual(self.second_player.hero.health, 18) def test_attack_minion_by_minion_1(self): self.first_player.board = [self.card_1, self.card_3] self.second_player.board = [self.card_2, self.card_4] self.state.attack(0, 1) self.assertEqual(self.first_player.graveyard, [self.card_1]) self.assertEqual(self.first_player.board, [self.card_3]) self.assertEqual(self.second_player.board, [self.card_2, self.card_4]) self.assertEqual(self.second_player.board[1].health, 1) def test_attack_minion_by_minion_2(self): self.first_player.board = [self.card_1, self.card_3] self.second_player.board = [self.card_2, self.card_4] self.state.attack(1, 0) self.assertEqual(self.first_player.board, [self.card_1, self.card_3]) self.assertEqual(self.second_player.board, [self.card_4]) self.assertEqual(self.second_player.graveyard, [self.card_2]) self.assertEqual(self.first_player.board[1].health, 1) def test_summoning_sickness_is_true_when_minion_is_played(self): self.state.current_player.hand = [self.card_1] self.state.play_card(0) self.assertTrue(self.card_1.summoning_sickness) def test_summoning_sickness_when_minion_with_charge_is_played(self): self.card_1.abilities[CHARGE] = partial(abilities.charge, minion=self.card_1) self.state.current_player.hand = [self.card_1] self.state.play_card(0) self.assertFalse(self.card_1.summoning_sickness) def test_divine_shield_reduce_damage_to_zero_and_disappear(self): self.card_1.abilities[DIVINE_SHIELD] = abilities.divine_shield self.state.current_player.board = [self.card_2] self.state.opposite_player.board = [self.card_1] self.state.attack(0, 0) self.assertTrue(DIVINE_SHIELD not in self.card_1.abilities) self.assertEqual(self.card_2.health, 0) self.assertEqual(self.state.current_player.board, []) self.assertEqual(self.state.current_player.graveyard, [self.card_2])
class TestActions(unittest.TestCase): def setUp(self): with open(CARDS_FILE) as json_file: data = json.load(json_file) self.abusive_sergeant = card_from_json(data[0]) self.agent_squire = card_from_json(data[1]) self.divine_strength = card_from_json(data[2]) self.selfless_hero = card_from_json(data[3]) self.divine_favor = card_from_json(data[4]) self.seal_of_champions = card_from_json(data[5]) self.steward_of_darshire = card_from_json(data[6]) self.wolfrider = card_from_json(data[7]) self.blessing_of_kings = card_from_json(data[8]) self.defender_of_argus = card_from_json(data[9]) self.hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.first_player = Player(self.hero_1, [], [], [], []) self.second_player = Player(self.hero_2, [], [], [], []) self.state = State(self.first_player, self.second_player) def test_how_many_combinations_of_playing_cards(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.divine_strength, self.divine_favor] player_hand = self.state.current_player.hand indexes = np.arange(len(player_hand)) self.assertEqual(len(list(get_cards_play_combinations(player_hand, indexes, 0))), 1) self.assertEqual(len(list(get_cards_play_combinations(player_hand, indexes, 1))), 4) self.assertEqual(len(list(get_cards_play_combinations(player_hand, indexes, 2))), 7) self.assertEqual(len(list(get_cards_play_combinations(player_hand, indexes, 3))), 9) def test_cards_to_play_with_combination(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.selfless_hero] self.state.play_cards([self.state.current_player.hand[i] for i in [0, 2]]) self.assertAlmostEqual(self.state.current_player.board, [self.abusive_sergeant, self.selfless_hero]) def test_cards_to_play(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.selfless_hero] combinations = list(get_cards_to_play(self.state.current_player.hand, 1)) self.assertEqual(combinations[0], []) self.assertEqual(combinations[1], [self.abusive_sergeant]) self.assertEqual(combinations[2], [self.agent_squire]) self.assertEqual(combinations[3], [self.selfless_hero]) self.state.play_cards([self.abusive_sergeant]) self.assertEqual(self.state.current_player.hand, [self.agent_squire, self.selfless_hero]) self.assertEqual(self.state.current_player.board, [self.abusive_sergeant]) def test_ewcia(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.selfless_hero] self.state.current_player.board = [deepcopy(self.abusive_sergeant), deepcopy(self.selfless_hero)] for card in self.state.current_player.board: card.summoning_sickness = False self.state.opposite_player.board = [deepcopy(self.selfless_hero), deepcopy(self.abusive_sergeant)] self.state = get_new_state(self.state, 3, evaluation_utils.random_strategy) print(str(self.state.opposite_player.hero.health)) self.state.switch_players() print(str(self.state.current_player.hero.health)) print(str(self.state.opposite_player.hero.health)) def test_random_moves(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.selfless_hero, self.divine_strength] self.state.current_player.board = [deepcopy(self.abusive_sergeant), deepcopy(self.selfless_hero), deepcopy(self.steward_of_darshire)] for card in self.state.current_player.board: card.summoning_sickness = False self.state.opposite_player.hand = [deepcopy(self.abusive_sergeant), deepcopy(self.agent_squire), deepcopy(self.selfless_hero), deepcopy(self.divine_strength)] self.state.opposite_player.board = [deepcopy(self.abusive_sergeant), deepcopy(self.selfless_hero), deepcopy(self.steward_of_darshire)] self.state.current_player.mana = 1 np.random.seed(0) s, p = get_random_state(self.state) print(p) def test_mtcs(self): deck1 = [deepcopy(self.selfless_hero), deepcopy(self.divine_favor), deepcopy(self.abusive_sergeant), deepcopy(self.agent_squire), deepcopy(self.seal_of_champions), deepcopy(self.steward_of_darshire), deepcopy(self.blessing_of_kings), deepcopy(self.divine_strength), deepcopy(self.wolfrider), deepcopy(self.defender_of_argus)] deck2 = [deepcopy(self.abusive_sergeant), deepcopy(self.defender_of_argus), deepcopy(self.divine_favor), deepcopy(self.seal_of_champions), deepcopy(self.agent_squire), deepcopy(self.divine_strength), deepcopy(self.selfless_hero), deepcopy(self.blessing_of_kings), deepcopy(self.wolfrider), deepcopy(self.steward_of_darshire)] deck1 = deck1[::-1] deck2 = deck2[::-1] self.first_player.deck = deck1 self.second_player.deck = deck2 self.state.draw_card() self.state.draw_card() self.state.switch_players() self.state.draw_card() self.state.draw_card() self.state.draw_card() self.state.switch_players() self.assertEqual(len(self.state.current_player.hand), 2) self.assertEqual(len(self.state.current_player.board), 0) self.assertEqual(len(self.state.current_player.graveyard), 0) self.assertEqual(len(self.state.opposite_player.hand), 3) self.assertEqual(len(self.state.opposite_player.board), 0) self.assertEqual(len(self.state.opposite_player.graveyard), 0) root = {'wins': 0, 'losses': 0, 'state': self.state, 'children': [], 'path': '', 'parent': None} import graphviz as gv graph = gv.Graph(format='svg') graph.node(name=str(0), label="{} / {}".format(root['wins'], root['wins'] + root['losses']), color=get_color(color)) graph.render(filename='graph_{}'.format(0)) for k in range(1, 200): selected = select_node(None, root) win = sim(selected) back_propagation(selected, win) print("Win = {}".format(win)) i = 0 graph = gv.Graph(format='svg') graph.node(name=str(i), label="{} / {}".format(root['wins'], root['wins'] + root['losses']), color=get_color(color)) # graph.render(filename='graph_{}'.format(k)) for child in root['children']: if child['wins'] + child['losses'] > 0: preorder(node=child, graph=graph, parent_name=i, parent_color=color) graph.render(filename='graph') def test_gui(self): self.state.current_player.hand = [self.abusive_sergeant, self.agent_squire, self.selfless_hero, self.divine_strength] self.state.current_player.board = [deepcopy(self.abusive_sergeant), deepcopy(self.selfless_hero), deepcopy(self.steward_of_darshire)] from beautifultable import BeautifulTable table = BeautifulTable() for card in self.state.current_player.hand: table.append_column(card.name, ['Cost = {}'.format(card.cost), get_static_abi(card), get_desc(card)]) print(table) print('\n') table = BeautifulTable() for card in self.state.current_player.board: table.append_column(card.name, [get_static_abi(card), get_desc(card)]) print(table)
class TestDeck(unittest.TestCase): def setUp(self): with open('../HearthstoneAI/cards.json') as json_file: data = json.load(json_file) self.abusive_sergeant = card_from_json(data[0]) self.agent_squire = card_from_json(data[1]) self.divine_strength = card_from_json(data[2]) self.selfless_hero = card_from_json(data[3]) self.divine_favor = card_from_json(data[4]) self.seal_of_champions = card_from_json(data[5]) self.steward_of_darshire = card_from_json(data[6]) self.wolfrider = card_from_json(data[7]) self.blessing_of_kings = card_from_json(data[8]) self.defender_of_argus = card_from_json(data[9]) self.hero_1 = Hero(name='Pamisio', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.hero_2 = Hero(name='Pamewcia', cost=0, abilities=dict(), attack=0, health=20, hero_class=None) self.first_player = Player(self.hero_1, [], [], [], []) self.second_player = Player(self.hero_2, [], [], [], []) self.state = State(self.first_player, self.second_player) def test_abusive_sergeant(self): """ Give a minion +2_Attack this turn. :return: """ self.assertEqual(self.abusive_sergeant.attack, 1) self.assertEqual(self.abusive_sergeant.health, 1) self.assertEqual(self.abusive_sergeant.cost, 1) self.first_player.hand = [self.abusive_sergeant] self.first_player.board = [self.agent_squire] self.state.play_card(0) self.assertEqual(self.state.current_player.hand, []) self.assertEqual(self.state.current_player.board, [self.agent_squire, self.abusive_sergeant]) self.assertEqual(self.agent_squire.attack, 3) self.state.compensate_abilities() self.assertEqual(self.agent_squire.attack, 1) self.state.compensate_abilities() self.assertEqual(self.agent_squire.attack, 1) def test_agent_squire(self): """ Divine Shield :return: """ self.abusive_sergeant.health = 5 self.assertEqual(self.agent_squire.attack, 1) self.assertEqual(self.agent_squire.health, 1) self.assertEqual(self.agent_squire.cost, 1) self.first_player.board = [self.abusive_sergeant] self.second_player.board = [self.agent_squire] self.state.attack(0, 0) self.assertEqual(self.abusive_sergeant.health, 4) self.assertEqual(self.agent_squire.health, 1) self.state.disable_sickness() self.state.attack(0, 0) self.assertEqual(self.abusive_sergeant.health, 3) self.assertEqual(self.agent_squire.health, 0) self.assertEqual(self.state.opposite_player.graveyard, [self.agent_squire]) def test_divine_strength(self): """ Give a minion +1/+2. :return: """ self.first_player.hand = [self.divine_strength] self.first_player.board = [self.abusive_sergeant] self.state.play_card(0) self.assertEqual(self.abusive_sergeant.attack, 2) self.assertEqual(self.abusive_sergeant.health, 3) self.assertEqual(self.abusive_sergeant.cost, 1) self.assertEqual(self.state.current_player.graveyard, [self.divine_strength]) self.state.compensate_abilities() self.assertEqual(self.abusive_sergeant.attack, 2) self.assertEqual(self.abusive_sergeant.health, 3) def test_selfless_hero(self): """ Deathrattle: Give a random friendly minion Divine Shield. :return: """ self.first_player.board = [self.abusive_sergeant] self.second_player.board = [self.selfless_hero] self.state.attack(0, 0) #TODO Fails because there is no minion that can receive a divine shield. Except to pass. def test_divine_favor(self): """ Draw cards until you have as many in hand as your opponent. :return: """ self.first_player.hand = [self.divine_favor] self.first_player.deck = [self.divine_strength, self.seal_of_champions] self.second_player.hand = [self.abusive_sergeant, self.agent_squire] self.state.play_card(0) self.assertEqual(len(self.first_player.hand), len(self.second_player.hand)) self.assertEqual(self.first_player.graveyard, [self.divine_favor]) def test_seal_of_champions(self): """ Give a minion +3 Attack and Divine Shield. :return: """ self.selfless_hero.health = 10 self.first_player.hand = [self.seal_of_champions] self.first_player.board = [self.abusive_sergeant] self.second_player.board = [self.selfless_hero] self.state.play_card(0) self.assertEqual(self.abusive_sergeant.attack, 4) self.state.switch_players() self.state.attack(0, 0) self.assertEqual(self.abusive_sergeant.health, 1) self.assertEqual(self.selfless_hero.health, 6) self.state.disable_sickness() self.state.attack(0, 0) self.assertLessEqual(self.abusive_sergeant.health, 0) self.assertEqual(self.selfless_hero.health, 2) self.assertEqual(self.first_player.graveyard, [self.seal_of_champions, self.abusive_sergeant]) def test_steward_of_darshire(self): """ Divine Shield :return: """ self.abusive_sergeant.health = 9 self.abusive_sergeant.attack = 3 self.first_player.board = [self.abusive_sergeant] self.second_player.board = [self.steward_of_darshire] self.state.attack(0, 0) self.assertEqual(self.abusive_sergeant.health, 6) self.assertEqual(self.steward_of_darshire.health, 3) self.state.disable_sickness() self.state.attack(0, 0) self.assertEqual(self.abusive_sergeant.health, 3) self.assertEqual(self.steward_of_darshire.health, 0) self.assertEqual(self.state.opposite_player.graveyard, [self.steward_of_darshire]) def test_wolfrider(self): """ Charge. :return: """ self.first_player.hand = [self.wolfrider] self.state.play_card(0) self.assertEqual(self.wolfrider.summoning_sickness, False) def test_blessing_of_kings(self): """ Give a minion +4/+4. :return: """ self.first_player.hand = [self.blessing_of_kings] self.first_player.board = [self.abusive_sergeant] self.state.play_card(0) self.assertEqual(self.abusive_sergeant.attack, 5) self.assertEqual(self.abusive_sergeant.health, 5) self.assertEqual(self.abusive_sergeant.cost, 1) self.state.compensate_abilities() self.assertEqual(self.abusive_sergeant.attack, 5) self.assertEqual(self.abusive_sergeant.health, 5) def test_defender_of_argus(self): """ Give your two random minions +1/+1 and Taunt. :return: """ self.first_player.hand = [self.defender_of_argus] self.first_player.board = [self.abusive_sergeant] self.state.play_card(0) self.assertEqual(self.abusive_sergeant.attack, 2) self.assertEqual(self.abusive_sergeant.health, 2) self.assertEqual(self.abusive_sergeant.cost, 1) self.assertEqual(self.abusive_sergeant.attack, 2) self.assertEqual(self.abusive_sergeant.health, 2)