def write_json(self, file): """ Write a replay in the complete json format. This format is compatible with the netplay format, and is also designed to be more future proof. For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file should be written. If an IO object, then the IO object should be opened for writing. :type file: :class:`str` or :class:`io.TextIOBase` """ was_filename = False if 'write' not in dir(file): was_filename = True writer = open(file, 'w') else: writer = file header_cards = [{"cards": [card.name for card in self.__shorten_deck(deck.cards)], "class": CHARACTER_CLASS.to_str(deck.character_class)} for deck in self.decks] header = { 'decks': header_cards, 'keep': self.keeps, 'random': self.random, } json.dump({'header': header, 'moves': self._moves}, writer, default=lambda o: o.__to_json__(), indent=2, sort_keys=True) if was_filename: writer.close()
def read_json(self, file): """ Read a replay in the complete json format. This format is compatible with the netplay format, and is also designed to be more future proof. For more info, see the `replay format <https://github.com/danielyule/hearthbreaker/blob/master/replay_format.md>`_ :param file: Either a string or an IO object. If a string, then it is assumed to be a filename describing where a replay file is found. If an IO object, then the IO object should be opened for reading. :type file: :class:`str` or :class:`io.TextIOBase` """ was_filename = False if 'read' not in dir(file): was_filename = True file = open(file, 'r') jd = json.load(file) self.decks = [] for deck in jd['header']['decks']: deck_size = len(deck['cards']) cards = [hearthbreaker.game_objects.card_lookup(deck['cards'][index % deck_size]) for index in range(0, 30)] self.decks.append( hearthbreaker.game_objects.Deck(cards, CHARACTER_CLASS.from_str(deck['class']))) self.random = jd['header']['random'] self.keeps = jd['header']['keep'] if len(self.keeps) == 0: self.keeps = [[0, 1, 2], [0, 1, 2, 3]] self._moves = [Move.from_json(**js) for js in jd['moves']] if was_filename: file.close()
def draw_hero(self, hero, window, x, y): color = curses.color_pair(0) if self.targets: if hero is self.selected_target: color = curses.color_pair(4) elif hero in self.targets: color = curses.color_pair(3) if hero.weapon is not None: weapon_power = "({0}) ({1})".format(hero.weapon.base_attack, hero.weapon.durability) window.addstr(y, x, "{0:^20}".format(hero.weapon.card)) window.addstr(y + 1, x, "{0:^20}".format(weapon_power)) hero_power = "({0}) ({1}+{4}) -- {2}/{3}".format( hero.calculate_attack(), hero.health, hero.player.mana, hero.player.max_mana, hero.armor) window.addstr( y, x + 20, "{0:^20}".format(CHARACTER_CLASS.to_str(hero.character_class)), color) window.addstr(y + 1, x + 20, "{0:^20}".format(hero_power), color) window.addstr(y, x + 40, "{0:^20}".format("Hero Power")) if hero.power.can_use(): window.addstr(y + 1, x + 40, "{0:^20}".format("*"))
def test_all_cards(self): fake_game = generate_game_for(StonetuskBoar, StonetuskBoar, DoNothingBot, DoNothingBot) overload_re = re.compile("Overload: \((\\d)\)") spell_damage_re = re.compile("Spell Damage \\+(\\d)") battlecry_re = re.compile("Battlecry: .*") deathrattle_re = re.compile("Deathrattle: .*") split_re = re.compile("\\s*\\.\\s*") file = open("cards.csv", "r") reader = csv.DictReader(file) for row in reader: if row['Implemented?'] == "yes": card = card_lookup(row["Name"]) self.assertEqual(int(row["Cost"]), card.mana, row["Name"]) self.assertEqual(CHARACTER_CLASS.from_str(row["Class"]), card.character_class, row["Name"]) self.assertEqual(CARD_RARITY.from_str(row["Rarity"]), card.rarity, "Expected card '{0}' to have rarity {1}".format(row["Name"], row["Rarity"])) if row["Type"] == "Minion": minion = card.create_minion(fake_game.current_player) minion.player = fake_game.current_player minion.game = fake_game for effect in split_re.split(row["Text"]): if effect == "Taunt": self.assertTrue(minion.taunt, "Expected {:s} to have taunt".format(row["Name"])) elif effect == "Divine Shield": self.assertTrue(minion.divine_shield, "Expected {:s} to have divine shield".format(row["Name"])) elif effect == "Stealth": self.assertTrue(minion.stealth, "Expected {:s} to have stealth".format(row["Name"])) elif effect == "Windfury": self.assertTrue(minion.windfury, "Expected {:s} to have windfury".format(row["Name"])) elif effect == "Charge": self.assertTrue(minion.charge, "Expected {:s} to have charge".format(row["Name"])) elif battlecry_re.match(effect): self.assertTrue(minion.battlecry is not None, "Expected {:s} to have a battlecry".format (row["Name"])) elif deathrattle_re.match(effect): self.assertTrue(minion.deathrattle is not None, "Expected {:s} to have a deathrattle".format (row["Name"])) elif overload_re.match(effect) is not None: self.assertEqual(int(overload_re.match(effect).group(1)), card.overload, ("Expected {:s} to have overload of" + " {:s}, but had {:d}").format(row["Name"], overload_re.match(effect).group(1), card.overload)) elif spell_damage_re.match(effect) is not None: self.assertEqual(int(spell_damage_re.match(effect).group(1)), minion.spell_damage, ("Expected {:s} to have spell damage of" + " {:s}, but had {:d}").format(row["Name"], spell_damage_re.match(effect).group(1), minion.spell_damage)) minion.silence() self.assertEqual(int(row["Attack"]), minion.calculate_attack(), row["Name"]) self.assertEqual(int(row["Health"]), minion.health, row["Name"]) self.assertEqual(MINION_TYPE.from_str(row["Race"]), card.minion_type, row["Name"]) elif row["Type"] == "Weapon": weapon = card.create_weapon(fake_game.current_player) self.assertEqual(int(row["Attack"]), weapon.base_attack, row["Name"]) self.assertEqual(int(row["Health"]), weapon.durability, row["Name"]) file.close()
def __init_weapon__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str( card_def['character_class']) if 'battlecry' in card_def: init_dict['battlecry'] = Battlecry.from_json( **card_def['battlecry']) if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] if 'buffs' in card_def: init_dict['buffs'] = [ Buff.from_json(**buff) for buff in card_def['buffs'] ] if 'auras' in card_def: init_dict['auras'] = [ Aura.from_json(**aura) for aura in card_def['auras'] ] if 'effects' in card_def: init_dict['effects'] = [ Effect.from_json(**effect) for effect in card_def['effects'] ] WeaponCard.__init__(self, **init_dict)
def __init__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str( card_def['character_class']) if 'minion_type' in card_def: init_dict['minion_type'] = MINION_TYPE.from_str( card_def['minion_type']) if 'battlecry' in card_def: init_dict['battlecry'] = Battlecry.from_json( **card_def['battlecry']) if 'choices' in card_def: init_dict['choices'] = [ Choice.from_json(**choice) for choice in card_def['choices'] ] if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] MinionCard.__init__(self, **init_dict)
def __init__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str(card_def['character_class']) if 'minion_type' in card_def: init_dict['minion_type'] = MINION_TYPE.from_str(card_def['minion_type']) if 'battlecry' in card_def: init_dict['battlecry'] = Battlecry.from_json(**card_def['battlecry']) if 'choices' in card_def: init_dict['choices'] = [Choice.from_json(**choice) for choice in card_def['choices']] if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] MinionCard.__init__(self, **init_dict)
def __init_weapon__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str(card_def['character_class']) if 'battlecry' in card_def: init_dict['battlecry'] = Battlecry.from_json(**card_def['battlecry']) if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] if 'buffs' in card_def: init_dict['buffs'] = [Buff.from_json(**buff) for buff in card_def['buffs']] if 'auras' in card_def: init_dict['auras'] = [Aura.from_json(**aura) for aura in card_def['auras']] if 'effects' in card_def: init_dict['effects'] = [Effect.from_json(**effect) for effect in card_def['effects']] WeaponCard.__init__(self, **init_dict)
def __init__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str(card_def['character_class']) if 'minion_type' in card_def: init_dict['minion_type'] = MINION_TYPE.from_str(card_def['minion_type']) if 'battlecry' in card_def: init_dict['battlecry'] = tuple(Battlecry.from_json(**battlecry) for battlecry in card_def['battlecry']) if 'choices' in card_def: init_dict['choices'] = [Choice.from_json(**choice) for choice in card_def['choices']] if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] if 'buffs' in card_def: init_dict['buffs'] = [Buff.from_json(**buff) for buff in card_def['buffs']] if 'auras' in card_def: init_dict['auras'] = [Aura.from_json(**aura) for aura in card_def['auras']] if 'effects' in card_def: init_dict['effects'] = [Effect.from_json(**effect) for effect in card_def['effects']] MinionCard.__init__(self, **init_dict)
def __init__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str( card_def['character_class']) if 'minion_type' in card_def: init_dict['minion_type'] = MINION_TYPE.from_str( card_def['minion_type']) if 'battlecry' in card_def: init_dict['battlecry'] = tuple( Battlecry.from_json(**battlecry) for battlecry in card_def['battlecry']) if 'choices' in card_def: init_dict['choices'] = [ Choice.from_json(**choice) for choice in card_def['choices'] ] if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] if 'buffs' in card_def: init_dict['buffs'] = [ Buff.from_json(**buff) for buff in card_def['buffs'] ] if 'auras' in card_def: init_dict['auras'] = [ Aura.from_json(**aura) for aura in card_def['auras'] ] if 'effects' in card_def: init_dict['effects'] = [ Effect.from_json(**effect) for effect in card_def['effects'] ] MinionCard.__init__(self, **init_dict)
def __init_weapon__(self): init_dict = { 'name': card_def['name'], 'mana': card_def['mana'], 'rarity': CARD_RARITY.from_str(card_def['rarity']) } if 'character_class' in card_def: init_dict['character_class'] = CHARACTER_CLASS.from_str(card_def['character_class']) if 'battlecry' in card_def: init_dict['battlecry'] = Battlecry.from_json(**card_def['battlecry']) if 'combo' in card_def: init_dict['combo'] = Battlecry.from_json(**card_def['combo']) if 'overload' in card_def: init_dict['overload'] = card_def['overload'] WeaponCard.__init__(self, **init_dict)
def draw_hero(self, player, window, x, y): color = curses.color_pair(0) if self.targets: if player.hero is self.selected_target: color = curses.color_pair(4) elif player.hero in self.targets: color = curses.color_pair(3) if player.weapon is not None: weapon_power = "({0}) ({1})".format(player.weapon.base_attack, player.weapon.durability) window.addstr(y, x, "{0:^20}".format(player.weapon.card.name)) window.addstr(y + 1, x, "{0:^20}".format(weapon_power)) hero_power = "({0}) ({1}+{4}) -- {2}/{3}".format(player.hero.calculate_attack(), player.hero.health, player.mana, player.max_mana, player.hero.armor) window.addstr(y, x + 20, "{0:^20}".format(CHARACTER_CLASS.to_str(player.hero.character_class)), color) window.addstr(y + 1, x + 20, "{0:^20}".format(hero_power), color) window.addstr(y, x + 40, "{0:^20}".format("Hero Power")) if player.hero.power.can_use(): window.addstr(y + 1, x + 40, "{0:^20}".format("*"))
def test_all_cards(self): fake_game = generate_game_for(StonetuskBoar, StonetuskBoar, DoNothingAgent, DoNothingAgent) overload_re = re.compile("Overload: \\((\\d)\\)") spell_damage_re = re.compile("Spell Damage \\+(\\d)") battlecry_re = re.compile("Battlecry: .*") deathrattle_re = re.compile("Deathrattle: .*") split_re = re.compile("\\s*\\.|\n\\s*") bold_tag_re = re.compile("</?b>") file = open("AllSets.enUS.json", "r", encoding="UTF-8") card_dict = json.load(file) not_implemented = [] total_cards = 0 for card_set in ['Classic', "Basic", "Curse of Naxxramas", "Goblins vs Gnomes", "Blackrock Mountain", "The Grand Tournament", "Reward", "Promotion"]: for card_info in card_dict[card_set]: if card_info["type"] in ['Minion', 'Spell', 'Weapon', 'Secret']: total_cards += 1 try: card = card_lookup(id_mappings[card_info["id"]]) except KeyError: if 'collectible' in card_info and card_info['collectible']: not_implemented.append("{}: ({})".format(card_info["name"], card_info['id'])) continue if "cost" in card_info: self.assertEqual(int(card_info["cost"]), card.mana, "Expected {} to have cost {}. Got {}".format( card_info["name"], card_info["cost"], card.mana)) if "playerClass" in card_info: self.assertEqual(CHARACTER_CLASS.from_str(card_info["playerClass"]), card.character_class, "Expected {} to have class {}. Got {}".format( card_info["name"], card_info["playerClass"], CHARACTER_CLASS.to_str(card.character_class))) else: self.assertEqual(CHARACTER_CLASS.ALL, card.character_class, "Expected {} to have no class. Got {}".format( card_info["name"], CHARACTER_CLASS.to_str(card.character_class))) if "rarity" in card_info: self.assertEqual(CARD_RARITY.from_str(card_info["rarity"]), card.rarity, "Expected card {} to have rarity {}. Got {}".format( card_info["name"], card_info["rarity"], CARD_RARITY.to_str(card.rarity))) if "collectible" in card_info: if card_info['collectible']: self.assertTrue(card.collectible, "Expected card {} to be collectible".format( card_info['name'])) else: self.assertFalse(card.collectible, "Expected card {} not to be collectible".format( card_info['name'])) if card_info["type"] == "Minion": minion = card.create_minion(fake_game.current_player) minion.player = fake_game.current_player minion.game = fake_game minion.card = card minion.add_to_board(0) if "text" in card_info: if card_info['name'] == "Argent Horserider": print(split_re.split(re.sub(bold_tag_re, "", card_info["text"]))) for effect in split_re.split(re.sub(bold_tag_re, "", card_info["text"])): if effect == "Taunt": self.assertTrue(minion.taunt, "Expected {:s} to have taunt".format(card_info["name"])) elif effect == "Divine Shield": self.assertTrue(minion.divine_shield, "Expected {:s} to have divine shield".format(card_info["name"])) elif effect == "Stealth": self.assertTrue(minion.stealth, "Expected {:s} to have stealth".format(card_info["name"])) elif effect == "Windfury": self.assertTrue(minion.windfury(), "Expected {:s} to have windfury".format(card_info["name"])) elif effect == "Charge": self.assertTrue(minion.charge(), "Expected {:s} to have charge".format(card_info["name"])) elif battlecry_re.match(effect): self.assertTrue(card.battlecry is not None, "Expected {:s} to have a battlecry".format (card_info["name"])) elif deathrattle_re.match(effect): self.assertTrue(minion.deathrattle is not None, "Expected {:s} to have a deathrattle".format (card_info["name"])) elif overload_re.match(effect) is not None: self.assertEqual(int(overload_re.match(effect).group(1)), card.overload, ("Expected {:s} to have overload of" + " {:s}, but had {:d}").format(card_info["name"], overload_re.match(effect).group(1), card.overload)) elif spell_damage_re.match(effect) is not None: self.assertEqual(int(spell_damage_re.match(effect).group(1)), minion.player.spell_damage, ("Expected {:s} to have spell damage of" + " {}, but had {}").format(card_info["name"], spell_damage_re.match(effect).group(1), minion.player.spell_damage)) minion.silence() self.assertEqual(int(card_info["attack"]), minion.calculate_attack(), "Expected {} to have attack of {}. Got {}".format( card_info["name"], card_info["attack"], minion.calculate_attack())) self.assertEqual(int(card_info["health"]), minion.health, "Expected {} to have health of {}. Got {}".format( card_info["name"], card_info["health"], minion.health)) if "race" in card_info: self.assertEqual(MINION_TYPE.from_str(card_info["race"]), card.minion_type, "Expected {} to have race {}. Got {}".format( card_info["name"], card_info["race"], MINION_TYPE.to_str(card.minion_type))) else: self.assertEqual(MINION_TYPE.NONE, card.minion_type, "Expected {} to have no race. Got {}".format( card_info["name"], MINION_TYPE.to_str(card.minion_type))) elif card_info["type"] == "Weapon": weapon = card.create_weapon(fake_game.current_player) self.assertEqual(int(card_info["attack"]), weapon.base_attack, "Expected {} to have attack of {}. Got {}".format( card_info["name"], card_info["attack"], weapon.base_attack)) self.assertEqual(int(card_info["durability"]), weapon.durability, "Expected {} to have durability of {}. Got {}".format( card_info["name"], card_info["durability"], weapon.durability)) file.close() if len(not_implemented) > 0: print("{} of {} cards implemented".format(total_cards - len(not_implemented), total_cards)) print("Cards not implemented:") for card in not_implemented: print(" - {}".format(card))
def test_all_cards(self): fake_game = generate_game_for(StonetuskBoar, StonetuskBoar, DoNothingAgent, DoNothingAgent) overload_re = re.compile("Overload: \\((\\d)\\)") spell_damage_re = re.compile("Spell Damage \\+(\\d)") battlecry_re = re.compile("Battlecry: .*") deathrattle_re = re.compile("Deathrattle: .*") split_re = re.compile("\\s*\\.\\s*") bold_tag_re = re.compile("</?b>") file = open("AllSets.enUS.json", "r", encoding="UTF-8") card_dict = json.load(file) not_implemented = [] total_cards = 0 for card_set in [ 'Expert', "Basic", "Curse of Naxxramas", "Goblins vs Gnomes", "Reward", "Promotion" ]: for card_info in card_dict[card_set]: if card_info["type"] in [ 'Minion', 'Spell', 'Weapon', 'Secret' ]: total_cards += 1 try: card = card_lookup(id_mappings[card_info["id"]]) except KeyError: not_implemented.append("{}: ({})".format( card_info["name"], card_info['id'])) continue if "cost" in card_info: self.assertEqual( int(card_info["cost"]), card.mana, "Expected {} to have cost {}. Got {}".format( card_info["name"], card_info["cost"], card.mana)) if "playerClass" in card_info: self.assertEqual( CHARACTER_CLASS.from_str(card_info["playerClass"]), card.character_class, "Expected {} to have class {}. Got {}".format( card_info["name"], card_info["playerClass"], CHARACTER_CLASS.to_str(card.character_class))) else: self.assertEqual( CHARACTER_CLASS.ALL, card.character_class, "Expected {} to have no class. Got {}".format( card_info["name"], CHARACTER_CLASS.to_str(card.character_class))) if "rarity" in card_info: self.assertEqual( CARD_RARITY.from_str(card_info["rarity"]), card.rarity, "Expected card {} to have rarity {}. Got {}". format(card_info["name"], card_info["rarity"], CARD_RARITY.to_str(card.rarity))) if "collectible" in card_info: if card_info['collectible']: self.assertTrue( card.collectible, "Expected card {} to be collectible".format( card_info['name'])) else: self.assertFalse( card.collectible, "Expected card {} not to be collectible". format(card_info['name'])) if card_info["type"] == "Minion": minion = card.create_minion(fake_game.current_player) minion.player = fake_game.current_player minion.game = fake_game minion.card = card minion.add_to_board(0) if "text" in card_info: for effect in split_re.split( re.sub(bold_tag_re, "", card_info["text"])): if effect == "Taunt": self.assertTrue( minion.taunt, "Expected {:s} to have taunt".format( card_info["name"])) elif effect == "Divine Shield": self.assertTrue( minion.divine_shield, "Expected {:s} to have divine shield". format(card_info["name"])) elif effect == "Stealth": self.assertTrue( minion.stealth, "Expected {:s} to have stealth".format( card_info["name"])) elif effect == "Windfury": self.assertTrue( minion.windfury(), "Expected {:s} to have windfury". format(card_info["name"])) elif effect == "Charge": self.assertTrue( minion.charge(), "Expected {:s} to have charge".format( card_info["name"])) elif battlecry_re.match(effect): self.assertTrue( card.battlecry is not None, "Expected {:s} to have a battlecry". format(card_info["name"])) elif deathrattle_re.match(effect): self.assertTrue( minion.deathrattle is not None, "Expected {:s} to have a deathrattle". format(card_info["name"])) elif overload_re.match(effect) is not None: self.assertEqual( int( overload_re.match(effect).group( 1)), card.overload, ("Expected {:s} to have overload of" + " {:s}, but had {:d}").format( card_info["name"], overload_re.match(effect).group( 1), card.overload)) elif spell_damage_re.match(effect) is not None: self.assertEqual( int( spell_damage_re.match( effect).group(1)), minion.player.spell_damage, ("Expected {:s} to have spell damage of" + " {}, but had {}").format( card_info["name"], spell_damage_re.match( effect).group(1), minion.player.spell_damage)) minion.silence() self.assertEqual( int(card_info["attack"]), minion.calculate_attack(), "Expected {} to have attack of {}. Got {}".format( card_info["name"], card_info["attack"], minion.calculate_attack())) self.assertEqual( int(card_info["health"]), minion.health, "Expected {} to have health of {}. Got {}".format( card_info["name"], card_info["health"], minion.health)) if "race" in card_info: self.assertEqual( MINION_TYPE.from_str(card_info["race"]), card.minion_type, "Expected {} to have race {}. Got {}".format( card_info["name"], card_info["race"], MINION_TYPE.to_str(card.minion_type))) else: self.assertEqual( MINION_TYPE.NONE, card.minion_type, "Expected {} to have no race. Got {}".format( card_info["name"], MINION_TYPE.to_str(card.minion_type))) elif card_info["type"] == "Weapon": weapon = card.create_weapon(fake_game.current_player) self.assertEqual( int(card_info["attack"]), weapon.base_attack, "Expected {} to have attack of {}. Got {}".format( card_info["name"], card_info["attack"], weapon.base_attack)) self.assertEqual( int(card_info["durability"]), weapon.durability, "Expected {} to have durability of {}. Got {}". format(card_info["name"], card_info["durability"], weapon.durability)) file.close() if len(not_implemented) > 0: print("{} of {} cards implemented".format( total_cards - len(not_implemented), total_cards)) print("Cards not implemented:") for card in not_implemented: print(" - {}".format(card))
def test_all_cards(self): fake_game = generate_game_for(StonetuskBoar, StonetuskBoar, DoNothingBot, DoNothingBot) overload_re = re.compile("Overload: \((\\d)\)") spell_damage_re = re.compile("Spell Damage \\+(\\d)") battlecry_re = re.compile("Battlecry: .*") deathrattle_re = re.compile("Deathrattle: .*") split_re = re.compile("\\s*\\.\\s*") file = open("cards.csv", "r") reader = csv.DictReader(file) implemented_count = 0 total_count = 0 for row in reader: total_count += 1 if row['Implemented?'] == "yes": implemented_count += 1 card = card_lookup(row["Name"]) self.assertEqual(int(row["Cost"]), card.mana, row["Name"]) self.assertEqual(CHARACTER_CLASS.from_str(row["Class"]), card.character_class, row["Name"]) self.assertEqual( CARD_RARITY.from_str(row["Rarity"]), card.rarity, "Expected card '{0}' to have rarity {1}".format( row["Name"], row["Rarity"])) if row["Type"] == "Minion": minion = card.create_minion(fake_game.current_player) minion.player = fake_game.current_player for effect in split_re.split(row["Text"]): if effect == "Taunt": self.assertTrue( minion.taunt, "Expected {:s} to have taunt".format( row["Name"])) elif effect == "Divine Shield": self.assertTrue( minion.divine_shield, "Expected {:s} to have divine shield".format( row["Name"])) elif effect == "Stealth": self.assertTrue( minion.stealth, "Expected {:s} to have stealth".format( row["Name"])) elif effect == "Windfury": self.assertTrue( minion.windfury, "Expected {:s} to have windfury".format( row["Name"])) elif effect == "Charge": self.assertTrue( minion.charge, "Expected {:s} to have charge".format( row["Name"])) elif battlecry_re.match(effect): self.assertTrue( minion.battlecry is not None, "Expected {:s} to have a battlecry".format( row["Name"])) elif deathrattle_re.match(effect): self.assertTrue( minion.deathrattle is not None, "Expected {:s} to have a deathrattle".format( row["Name"])) elif overload_re.match(effect) is not None: self.assertEqual( int(overload_re.match(effect).group(1)), card.overload, ("Expected {:s} to have overload of" + " {:s}, but had {:d}").format( row["Name"], overload_re.match(effect).group(1), card.overload)) elif spell_damage_re.match(effect) is not None: self.assertEqual( int(spell_damage_re.match(effect).group(1)), minion.spell_damage, ("Expected {:s} to have spell damage of" + " {:s}, but had {:d}").format( row["Name"], spell_damage_re.match(effect).group(1), minion.spell_damage)) minion.silence() self.assertEqual(int(row["Attack"]), minion.calculate_attack(), row["Name"]) self.assertEqual(int(row["Health"]), minion.health, row["Name"]) self.assertEqual(MINION_TYPE.from_str(row["Race"]), card.minion_type, row["Name"]) elif row["Type"] == "Weapon": weapon = card.create_weapon(fake_game.current_player) self.assertEqual(int(row["Attack"]), weapon.base_attack, row["Name"]) self.assertEqual(int(row["Health"]), weapon.durability, row["Name"]) file.close() print("Implemented {0} cards, with {1} cards left".format( implemented_count, total_count - implemented_count))