def test_deathwing(initialized_game): initialized_game.player_board[0] = PlayerBoard(0, HeroType.DEATHWING, 1, 1, [HarvestGolem()]) initialized_game.player_board[1] = PlayerBoard(0, None, 1, 1, [PunchingBag(attack=10)], enemy_is_deathwing=True) initialized_game.start_of_game() initialized_game.single_round() assert initialized_game.player_board[0].minions[0].attack == 4 initialized_game.player_board[0] = PlayerBoard(0, HeroType.DEATHWING, 1, 1, [HarvestGolem()], enemy_is_deathwing=True) initialized_game.player_board[1] = PlayerBoard(0, HeroType.DEATHWING, 1, 1, [PunchingBag(attack=10)], enemy_is_deathwing=True) initialized_game.start_of_game() initialized_game.single_round() assert initialized_game.player_board[0].minions[0].attack == 6
def test_yshaarj(initialized_game): initialized_game.player_board[0] = PlayerBoard(0, HeroType.YSHAARJ_ACTIVATED, 1, 1, []) initialized_game.player_board[1] = PlayerBoard(0, None, 1, 1, []) attacker_board = initialized_game.player_board[0] defender_board = initialized_game.player_board[1] initialized_game.start_of_game() initialized_game.single_round() assert attacker_board.minions[0].rank == 1
def test_kurtrus_ashfallen(initialized_game): initialized_game.player_board[0] = PlayerBoard( 0, HeroType.KURTRUS_ASHFALLEN_ACTIVATED, 1, 1, [AcolyteOfCThun()]) initialized_game.player_board[1] = PlayerBoard(0, None, 1, 1, [PunchingBag(attack=10)]) initialized_game.start_of_game() initialized_game.single_round() acolyte = initialized_game.player_board[0].minions[0] # Reborn minions get the +2/+2 buff assert acolyte.attack == 4 assert acolyte.health == 3
def test_greybough(initialized_game): initialized_game.player_board[0] = PlayerBoard(0, HeroType.GREYBOUGH, 1, 1, [HarvestGolem()]) initialized_game.player_board[1] = PlayerBoard(0, None, 1, 1, [PunchingBag(attack=10)]) initialized_game.start_of_game() initialized_game.single_round() golem_token = initialized_game.player_board[0].minions[0] assert golem_token.attack == 3 assert golem_token.health == 3 assert golem_token.taunt
def test_illidan_stormrage(initialized_game): initialized_game.player_board[0] = PlayerBoard(0, HeroType.ILLIDAN_STORMRAGE, 1, 1, [AcolyteOfCThun()]) initialized_game.player_board[1] = PlayerBoard( 0, None, 1, 1, [HarvestGolem(), PunchingBag(taunt=True)]) attacker_board = initialized_game.player_board[0] defender_board = initialized_game.player_board[1] # NOTE: Illidan player bonus attacks trigger before combat, even though opponent has more minons initialized_game.start_of_game() acolyte = attacker_board.minions[0] punching_bag = defender_board.minions[1] assert acolyte.attack == 4 assert punching_bag.health == 96 # Deathrattles and pirate attacks should resolve punching_bag = PunchingBag(attack=1) attacker_board.set_minions([Scallywag(), Alleycat()]) defender_board.set_minions([punching_bag]) initialized_game.start_of_game() assert punching_bag.health == 92 # Test windfury and attack order scallywag = Scallywag() punching_bag = PunchingBag() attacker_board.set_minions([scallywag, CracklingCyclone()]) defender_board.set_minions([punching_bag]) initialized_game.start_of_game() assert punching_bag.health == 84 first_attacker = attacker_board.select_attacking_minion() assert first_attacker == scallywag # Single minion only attacks once single_minion = PunchingBag() attacker_board.set_minions([single_minion]) defender_board.set_minions([PunchingBag()]) initialized_game.start_of_game() assert single_minion.attack == 2
def test_tonytwotusk(initialized_game): non_golden_pirate = DreadAdmiralEliza() bag = PunchingBag(attack=10) initialized_game.player_board[0] = PlayerBoard( 0, HeroType.GREYBOUGH, 1, 1, [ ReplicatingMenace(), HarvestGolem(), non_golden_pirate, TonyTwoTusk() ]) attacker_board = initialized_game.player_board[0] defender_board = initialized_game.player_board[1] defender_board.set_minions([bag]) initialized_game.start_of_game() for _ in range(5): initialized_game.single_round() assert non_golden_pirate.golden assert non_golden_pirate.health == non_golden_pirate.base_health * 2 initialized_game.single_round() initialized_game.single_round() assert non_golden_pirate.attack == 16 assert non_golden_pirate.health == 6
def simulate_game_from_log(logPath): logreader = LogReader(logPath) turns = 0 turn_results = {} while True: board_state = logreader.watch_log_file_for_combat_state() if not board_state: break player_board_0 = PlayerBoard( player_id=0, hero=board_state.friendlyHero, life_total=board_state.friendlyPlayerHealth, rank=board_state.friendlyTechLevel, minions=board_state.friendlyBoard, enemy_is_deathwing=board_state.enemyHero is HeroType.DEATHWING) player_board_1 = PlayerBoard( player_id=1, hero=board_state.enemyHero, life_total=board_state.enemyPlayerHealth, rank=board_state.enemyTechLevel, minions=board_state.enemyBoard, enemy_is_deathwing=board_state.friendlyHero is HeroType.DEATHWING) try: single_threaded = False games = 10_000 game_state = (player_board_0, player_board_1) pickled_state = pickle.dumps(game_state) if single_threaded: results = [] for _ in range(games): results.append(Simulator.Simulate(pickled_state)) else: pool = Pool() results = pool.map(Simulator.Simulate, repeat(pickled_state, games)) pool.close() pool.join() counter = Counter(results) results = sorted(counter.items(), key=lambda x: x[0]) wins, losses, ties, enemy_lethal, friendly_lethal = 0.0, 0.0, 0.0, 0.0, 0.0 for result in results: damage = result[0] game_count = result[1] if damage > 0: wins += game_count if damage > player_board_1.life_total: enemy_lethal += game_count elif damage < 0: losses += game_count if (damage * -1) > player_board_0.life_total: friendly_lethal += game_count else: ties += game_count turn_results[turns] = [ 100 * enemy_lethal / games, 100 * wins / games, 100 * ties / games, 100 * losses / games, 100 * friendly_lethal / games ] turns += 1 except Exception as e: print(f"Game:{logPath}, turn:{turns}, error:{e}") turn_results[turns] = [0, 0, 0, 0, 0] turns += 1 return turn_results
import logging from utils.profile import Profile from game.game_instance import GameInstance from game.simulation import Simulation from game.player_board import PlayerBoard from minions.rank_1 import DragonspawnLieutenant, FiendishServant, RedWhelp, RighteousProtector, Mecharoo player_board_0 = PlayerBoard(player_id=0, hero=None, life_total=12, rank=4, minions=[ FiendishServant(), DragonspawnLieutenant(), DragonspawnLieutenant(), RedWhelp(), RedWhelp() ]) player_board_1 = PlayerBoard(player_id=1, hero=None, life_total=12, rank=4, minions=[ DragonspawnLieutenant(), Mecharoo(), FiendishServant(), DragonspawnLieutenant(), FiendishServant(),
def main(): logPath = "C:/Users/scott/Desktop/hearthstone_games/Recorded_games/Power_game_15.log" #logPath = "C:/Program Files (x86)/Hearthstone/Logs/Power_old.log" #logging.basicConfig(level=logging.DEBUG, format="%(message)s") print("Reading Log: ", logPath) logreader = LogReader(logPath) turns = 0 profile = Profile() profile.__enter__() while True: print( "------------------------------------------------------------------------" ) board_state = logreader.watch_log_file_for_combat_state() if not board_state: print("\n*** Game Over ***") profile.__exit__() continue player_board_0 = PlayerBoard( player_id=0, hero=board_state.friendlyHero, life_total=board_state.friendlyPlayerHealth, rank=board_state.friendlyTechLevel, minions=board_state.friendlyBoard, enemy_is_deathwing=board_state.enemyHero is HeroType.DEATHWING) player_board_1 = PlayerBoard( player_id=1, hero=board_state.enemyHero, life_total=board_state.enemyPlayerHealth, rank=board_state.enemyTechLevel, minions=board_state.enemyBoard, enemy_is_deathwing=board_state.friendlyHero is HeroType.DEATHWING) print("Enemy board") print(player_board_1) print("Friendly board") print(player_board_0) # turns += 1 # if turns < 9: # continue try: single_threaded = True games = 10_000 game_state = (player_board_0, player_board_1) pickled_state = pickle.dumps(game_state) if single_threaded: results = [] start = time.time() for _ in range(games): results.append(Simulator.Simulate(pickled_state)) else: start = time.time() pool = Pool() results = pool.map(Simulator.Simulate, repeat(pickled_state, games)) pool.close() pool.join() counter = Counter(results) results = sorted(counter.items(), key=lambda x: x[0]) wins, losses, ties, enemy_lethal, friendly_lethal = 0.0, 0.0, 0.0, 0.0, 0.0 for result in results: damage = result[0] game_count = result[1] if damage > 0: wins += game_count if damage > player_board_1.life_total: enemy_lethal += game_count elif damage < 0: losses += game_count if (damage * -1) > player_board_0.life_total: friendly_lethal += game_count else: ties += game_count end = time.time() print("Win", 100 * wins / games, "Tie", 100 * ties / games, "Loss", 100 * losses / games, "Elapsed:", end - start) print("We kill enemy:", 100 * enemy_lethal / games, "Enemy kills us:", 100 * friendly_lethal / games) print( "------------------------------------------------------------------------\n" ) except Exception as e: print(e)