def a_vs_b(ship_a, ship_b, agent_a, agent_b, ship_a_hull, trials, attack_range): """This function runs multiple trials of ship_a firing upon ship_b. Args: ship_a ((Ship, str)): Attacker and hull zone tuple. ship_b ((Ship, str)): Defender and hull zone tuple. agent_a (BaseAgent): Agent to control the actions of ship a. agent_b (BaseAgent): Agent to control the actions of ship b. ship_a_hull (str) : Attacking hull zone. trials (int): Number of trials in average calculation. range (str): Attack range. Returns: List[(str, world_state or attack effect tuple)] """ state_log = [] failures = 0 for _ in range(trials): # Reset ship b for each trial ship_b.reset() world_state = WorldState() world_state.addShip(ship_a, 0) world_state.addShip(ship_b, 1) # Begin at round 1 world_state.round = 1 # Don't attempt forever in the case of some catastrophic reoccurring error. attempts = 0 while ship_b.damage_cards() < ship_b.hull( ) and world_state.round <= ArmadaPhases.max_rounds: attempts += 1 # Handle the attack and receive the updated world state #try: world_state = handleAttack(world_state=world_state, attacker=(ship_a, ship_a_hull), defender=(ship_b, "front"), attack_range=attack_range, offensive_agent=agent_a, defensive_agent=agent_b, state_log=state_log) # Record the final state with the incremented round number. world_state.setPhase("status phase", "increment round number") world_state.round += 1 state_log.append(('state', world_state.clone())) #except RuntimeError as err: # # This is fine, the random agent will do illegal things plenty of times # pass if 250 == attempts: raise RuntimeError("Too many failures for ship firing simulation.") return state_log