def test_battle_simple(infantry_unit, fighter_unit): """tests a battle with one unit on each side""" setup = units.BattleSetup(battlefield="land", attackers=(infantry_unit, ), defenders=(fighter_unit, )) results = battle.battle_results[setup] assert len(results) == 3 assert is_close( results[units.BattleSetup(battlefield="land", attackers=(infantry_unit, ), defenders=())], 1 * 2 / 26, ) assert is_close( results[units.BattleSetup(battlefield="land", attackers=(), defenders=(fighter_unit, ))], 5 * 4 / 26, ) assert is_close( results[units.BattleSetup(battlefield="land", attackers=(), defenders=())], 1 * 4 / 26, )
def test_battle_steps_simple(infantry_unit, fighter_unit): """Tests the next step of a battle with one unit is correct""" setup = units.BattleSetup(battlefield="land", attackers=(infantry_unit, ), defenders=(fighter_unit, )) next_steps = battle.battle_steps[setup] assert len(next_steps) == 3 assert is_close(sum(next_steps.values()), 1) assert is_close( next_steps[units.BattleSetup(battlefield="land", attackers=(infantry_unit, ), defenders=())], 1 * 2 / 36, ) assert is_close( next_steps[units.BattleSetup(battlefield="land", attackers=(), defenders=(fighter_unit, ))], 5 * 4 / 36, ) assert is_close( next_steps[units.BattleSetup(battlefield="land", attackers=(), defenders=())], 1 * 4 / 36, )
def compute_battle_step( cache, setup: a_units.BattleSetup) -> Counter[a_units.BattleSetup]: """Computes the next available steps after rolling the dice for one stage.""" del cache # unused if not setup.attackers or not setup.defenders: return collections.Counter({setup: 1}) attack_hits = get_hits(BattleMode.ATTACK, setup.battlefield, *setup.attackers) defense_hits = get_hits(BattleMode.DEFEND, setup.battlefield, *setup.defenders) result = collections.Counter() for n_a_hits, n_a_count in attack_hits.items(): new_defenders = take_cheapest_hits(n_a_hits, *setup.defenders) for n_d_hits, n_d_count in defense_hits.items(): new_attackers = take_cheapest_hits(n_d_hits, *setup.attackers) new_setup = a_units.BattleSetup( battlefield=setup.battlefield, attackers=new_attackers, defenders=new_defenders, ) if new_setup != setup: result[new_setup] += n_a_count * n_d_count # Readjust the counts to sum to 1. total = sum(result.values()) if total != 1: result = collections.Counter({k: v / total for k, v in result.items()}) return result
def test_battle_cost(infantry_unit, fighter_unit): """Tests a battle with two units to get the expect costs.""" setup = units.BattleSetup( battlefield="land", attackers=(infantry_unit, infantry_unit), defenders=(fighter_unit, fighter_unit), ) costs = battle.get_expected_costs(setup) assert 0 < costs["attacker"] < setup.attacker_ipc assert 0 < costs["defender"] < setup.defender_ipc
def test_clear_battle_odds(transport_unit, fighter_unit): """Tests a battle with two units to get the expect costs.""" setup = units.BattleSetup( battlefield="land", attackers=(fighter_unit, fighter_unit), defenders=(transport_unit, transport_unit), ) odds = battle.get_winning_odds(setup) assert odds["attacker"] == 1 assert odds["defender"] == 0 assert odds["draw"] == 0 setup = units.BattleSetup( battlefield="land", attackers=(transport_unit, transport_unit), defenders=(transport_unit, ), ) odds = battle.get_winning_odds(setup) assert odds["attacker"] == 0 assert odds["defender"] == 0 assert odds["draw"] == 1
def test_battle_odds(infantry_unit, fighter_unit): """Tests a battle with two units to get the expect costs.""" setup = units.BattleSetup( battlefield="land", attackers=(infantry_unit, infantry_unit), defenders=(fighter_unit, fighter_unit), ) odds = battle.get_winning_odds(setup) assert 0 < odds["attacker"] < 1 assert 0 < odds["defender"] < 1 assert 0 < odds["draw"] < 1 assert is_close(sum(odds.values()), 1)
def test_battle_steps_two_units(infantry_unit, fighter_unit): """Tests the next step of a battle with two units is correct""" setup = units.BattleSetup( battlefield="land", attackers=(infantry_unit, infantry_unit), defenders=(fighter_unit, fighter_unit), ) next_steps = battle.battle_steps[setup] assert len(next_steps) == 8 assert is_close(sum(next_steps.values()), 1) assert is_close( next_steps[units.BattleSetup( battlefield="land", attackers=(infantry_unit, infantry_unit), defenders=(), )], 1 * 1 * 2 * 2 / 36**2, ) assert is_close( next_steps[units.BattleSetup( battlefield="land", attackers=(infantry_unit, ), defenders=(fighter_unit, ), )], 2 * 5 * 2 * 4 * 2 / 36**2, ) assert is_close( next_steps[units.BattleSetup(battlefield="land", attackers=(), defenders=(fighter_unit, fighter_unit))], 5 * 5 * 4 * 4 / 36**2, ) assert is_close( next_steps[units.BattleSetup(battlefield="land", attackers=(), defenders=())], 1 * 1 * 4 * 4 / 36**2, )
def test_battle_two_units(infantry_unit, fighter_unit): """Tests a battle with two units""" setup = units.BattleSetup( battlefield="land", attackers=(infantry_unit, infantry_unit), defenders=(fighter_unit, fighter_unit), ) results = battle.battle_results[setup] assert len(results) == 1 + 2 + 2 assert sorted(results, key=results.__getitem__)[-1].attackers == () assert sorted(results, key=results.__getitem__)[-2].attackers == () assert sorted(results, key=results.__getitem__)[-3].attackers == () assert sorted(results, key=results.__getitem__)[-3].defenders == () assert sorted(results, key=results.__getitem__)[-4].defenders == () assert sorted(results, key=results.__getitem__)[-5].defenders == ()