def test_three_collision(self): state = GameState() loc1 = (10, 11) loc2 = (9, 10) loc3 = (11, 10) dest = (10, 10) state.add_robot(loc1, 0) state.add_robot(loc2, 1) state.add_robot(loc3, 1) actions = { loc1: ['move', dest], loc2: ['move', dest], loc3: ['move', dest] } deltas = state.get_delta(actions) d_player0 = delta_for(deltas, loc1) d_player1_1 = delta_for(deltas, loc2) d_player1_2 = delta_for(deltas, loc3) self.assertEqual(d_player0.hp - d_player0.hp_end, d_player1_1.damage_caused + d_player1_2.damage_caused) player1_hp_lose = d_player1_1.hp - d_player1_1.hp_end + \ d_player1_2.hp - d_player1_2.hp_end self.assertEqual(player1_hp_lose, d_player0.damage_caused)
def test_suicide(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = {loc1: ['move', dest1], loc2: ['suicide']} deltas = state.get_delta(actions) d_guard = delta_for(deltas, loc1) d_suicide = delta_for(deltas, loc2) self.assertEqual(d_guard.hp - d_guard.hp_end, d_suicide.damage_caused)
def test_attack(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) dest2 = dest1 state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = {loc1: ['move', dest1], loc2: ['attack', dest2]} deltas = state.get_delta(actions) d_move = delta_for(deltas, loc1) d_attack = delta_for(deltas, loc2) self.assertEqual(d_move.hp - d_move.hp_end, d_attack.damage_caused)
def test_simple_collision(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) dest2 = dest1 state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = {loc1: ['move', dest1], loc2: ['move', dest2]} deltas = state.get_delta(actions) d_move1 = delta_for(deltas, loc1) d_move2 = delta_for(deltas, loc2) self.assertEqual(d_move1.hp - d_move1.hp_end, d_move2.damage_caused) self.assertEqual(d_move2.hp - d_move2.hp_end, d_move1.damage_caused)
def test_suicide(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = { loc1: ['move', dest1], loc2: ['suicide'] } deltas = state.get_delta(actions) d_guard = delta_for(deltas, loc1) d_suicide = delta_for(deltas, loc2) self.assertEqual(d_guard.hp - d_guard.hp_end, d_suicide.damage_caused)
def test_attack(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) dest2 = dest1 state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = { loc1: ['move', dest1], loc2: ['attack', dest2] } deltas = state.get_delta(actions) d_move = delta_for(deltas, loc1) d_attack = delta_for(deltas, loc2) self.assertEqual(d_move.hp - d_move.hp_end, d_attack.damage_caused)
def test_collision_and_attack(self): state = GameState() loc1 = (10, 11) loc2 = (9, 10) loc3 = (11, 11) dest = (10, 10) attack_dest = loc1 state.add_robot(loc1, 0) state.add_robot(loc2, 1) state.add_robot(loc3, 1) actions = { loc1: ['move', dest], loc2: ['move', dest], loc3: ['attack', attack_dest] } deltas = state.get_delta(actions) d_player0 = delta_for(deltas, loc1) d_player1_move = delta_for(deltas, loc2) d_player1_attack = delta_for(deltas, loc3) self.assertEqual(d_player1_move.damage_caused, settings.collision_damage) self.assertTrue(settings.attack_range[0] <= d_player1_attack.damage_caused <= settings.attack_range[1]) self.assertEqual(d_player0.hp - d_player0.hp_end, d_player1_move.damage_caused + d_player1_attack.damage_caused) player1_hp_lose = d_player1_move.hp - d_player1_move.hp_end + \ d_player1_attack.hp - d_player1_attack.hp_end self.assertEqual(player1_hp_lose, d_player0.damage_caused)
def test_simple_collision(self): state = GameState() loc1 = (10, 11) dest1 = (10, 10) loc2 = (9, 10) dest2 = dest1 state.add_robot(loc1, 0) state.add_robot(loc2, 1) actions = { loc1: ['move', dest1], loc2: ['move', dest2] } deltas = state.get_delta(actions) d_move1 = delta_for(deltas, loc1) d_move2 = delta_for(deltas, loc2) self.assertEqual(d_move1.hp - d_move1.hp_end, d_move2.damage_caused) self.assertEqual(d_move2.hp - d_move2.hp_end, d_move1.damage_caused)
class Game(object): def __init__(self, players, record_actions=False, record_history=False, print_info=False, seed=None, quiet=0, delta_callback=None, symmetric=True): self._players = players for i, player in enumerate(self._players): player.set_player_id(i) self._record_actions = record_actions self._record_history = record_history self._print_info = print_info if seed is None: seed = random.randint(0, settings.max_seed) self.seed = str(seed) self._random = random.Random(self.seed) self._quiet = quiet self._delta_callback = delta_callback self._state = GameState(use_start=True, seed=self.seed, symmetric=symmetric) self._actions_on_turn = {} self._states = {} self.history = [] # TODO: make private # actions_on_turn = {loc: log_item} # log_item = { # 'name': action_name, # 'target': action_target or None, # 'loc': loc, # 'hp': hp, # 'player': player_id, # 'loc_end': loc_end, # 'hp_end': hp_end # } # # or dummy if turn == settings.max_turn def get_actions_on_turn(self, turn): assert self._record_actions return self._actions_on_turn[turn] def get_state(self, turn): return self._states[turn] def _save_actions_on_turn(self, actions_on_turn, turn): self._actions_on_turn[turn] = actions_on_turn def _save_state(self, state, turn): self._states[turn] = state def _get_robots_actions(self): if self._quiet >= 1: sys.stdout = NullDevice() if self._quiet >= 2: sys.stderr = NullDevice() actions = {} for player in self._players: seed = self._random.randint(0, settings.max_seed) actions.update(player.get_actions(self._state, seed)) if self._quiet >= 1: sys.stdout = sys.__stdout__ if self._quiet >= 2: sys.stderr = sys.__stderr__ return actions def _make_history(self, actions): ''' An aggregate of all bots and their actions this turn. Stores a list of each player's bots at the start of this turn and the actions they each performed this turn. Newly spawned bots have no actions. ''' robots = [] for loc, robot in self._state.robots.iteritems(): robot_info = { 'location': loc, 'hp': robot.hp, 'player_id': robot.player_id, 'robot_id': robot.robot_id, } if loc in actions: robot_info['action'] = actions[loc] robots.append(robot_info) return robots def _calculate_actions_on_turn(self, delta, actions): actions_on_turn = {} for delta_info in delta: loc = delta_info.loc if loc in actions: name = actions[loc][0] if name in ['move', 'attack']: target = actions[loc][1] else: target = None else: name = 'spawn' target = None # note that a spawned bot may overwrite an existing bot actions_on_turn[loc] = { 'name': name, 'target': target, 'loc': loc, 'hp': delta_info.hp, 'player': delta_info.player_id, 'loc_end': delta_info.loc_end, 'hp_end': delta_info.hp_end } return actions_on_turn def run_turn(self): if self._print_info: print (' running turn %d ' % (self._state.turn)).center(70, '-') actions = self._get_robots_actions() delta = self._state.get_delta(actions) if self._record_actions: actions_on_turn = self._calculate_actions_on_turn(delta, actions) self._save_actions_on_turn(actions_on_turn, self._state.turn) new_state = self._state.apply_delta(delta) if self._delta_callback is not None and self._state.turn > 1: self._delta_callback(delta, new_state) self._save_state(new_state, new_state.turn) if self._record_history: self.history.append(self._make_history(actions)) self._state = new_state def run_all_turns(self): assert self._state.turn == 0 if self._print_info: print ('Match seed: {0}'.format(self.seed)) self._save_state(self._state, 0) while self._state.turn < settings.max_turns: self.run_turn() # create last turn's state for server history if self._record_history: self.history.append(self._make_history({})) # create dummy data for last turn # TODO: render should be cleverer actions_on_turn = {} for loc, robot in self._state.robots.iteritems(): log_item = { 'name': '', 'target': None, 'loc': loc, 'hp': robot.hp, 'player': robot.player_id, 'loc_end': loc, 'hp_end': robot.hp } actions_on_turn[loc] = log_item self._save_actions_on_turn(actions_on_turn, settings.max_turns) def get_scores(self): return self.get_state(settings.max_turns).get_scores()
def test_spawn(self): state = GameState() deltas = state.get_delta(actions={}, spawn=True) for d in deltas: self.assertTrue(hasattr(d, 'damage_caused'))
class Game(object): def __init__(self, players, record_actions=False, record_history=False, print_info=False, seed=None, quiet=0, delta_callback=None, symmetric=True): self._players = players for i, player in enumerate(self._players): player.set_player_id(i) self._record_actions = record_actions self._record_history = record_history self._print_info = print_info if seed is None: seed = random.randint(0, settings.max_seed) self.seed = str(seed) self._random = random.Random(self.seed) self._quiet = quiet self._delta_callback = delta_callback self._state = GameState(use_start=True, seed=self.seed, symmetric=symmetric) self._actions_on_turn = {} self._states = {} self.history = [] # TODO: make private # actions_on_turn = {loc: log_item} # log_item = { # 'name': action_name, # 'target': action_target or None, # 'loc': loc, # 'hp': hp, # 'player': player_id, # 'loc_end': loc_end, # 'hp_end': hp_end # } # # or dummy if turn == settings.max_turn def get_actions_on_turn(self, turn): assert self._record_actions return self._actions_on_turn[turn] def get_state(self, turn): return self._states[turn] def _save_actions_on_turn(self, actions_on_turn, turn): self._actions_on_turn[turn] = actions_on_turn def _save_state(self, state, turn): self._states[turn] = state def _get_robots_responses(self): # TODO: honour quietness actions, outputs = {}, {} for player in self._players: seed = self._random.randint(0, settings.max_seed) responses = player.get_responses(self._state, seed) actions.update(responses[0]) outputs.update(responses[1]) return actions, outputs def _make_history(self, responses, record_output=False): # todo: rework this. We are getting data about the player # from two sources: 1) from arguments, and 2) from # class members. Either move *all* to 1) and make # static or move all to 2). ''' An aggregate of all bots and their actions this turn. Optionally records per-bot output. Stores a list of each player's bots at the start of this turn and the actions they each performed this turn. Newly spawned bots have no actions. ''' actions, outputs = responses robots = [] for loc, robot in self._state.robots.items(): robot_info = { 'location': loc, 'hp': robot.hp, 'player_id': robot.player_id, 'robot_id': robot.robot_id, } if loc in actions: # since the state after the final turn does not contain any # actions, 'loc' is not always contained in 'actions' robot_info['action'] = actions[loc] if outputs and loc in outputs: robot_info['output'] = outputs[loc] robots.append(robot_info) return robots def _calculate_actions_on_turn(self, delta, actions): actions_on_turn = {} for delta_info in delta: loc = delta_info.loc if loc in actions: name = actions[loc][0] if name in ['move', 'attack']: target = actions[loc][1] else: target = None else: name = 'spawn' target = None # note that a spawned bot may overwrite an existing bot actions_on_turn[loc] = { 'name': name, 'target': target, 'loc': loc, 'hp': delta_info.hp, 'player': delta_info.player_id, 'loc_end': delta_info.loc_end, 'hp_end': delta_info.hp_end } return actions_on_turn def run_turn(self, record_output=False): if self._print_info: print((' running turn %d ' % (self._state.turn)).center(70, '-')) # pr = cProfile.Profile() # pr.enable() responses = self._get_robots_responses() actions = responses[0] # pr.disable() # s = StringIO.StringIO() # sortby = 'cumulative' # ps = pstats.Stats(pr, stream=s).sort_stats(sortby) # ps.print_stats() # print(s.getvalue()) delta = self._state.get_delta(actions) if self._record_actions: actions_on_turn = self._calculate_actions_on_turn(delta, actions) self._save_actions_on_turn(actions_on_turn, self._state.turn) new_state = self._state.apply_delta(delta) if self._delta_callback is not None and self._state.turn > 1: self._delta_callback(delta, new_state) self._save_state(new_state, new_state.turn) if self._record_history: self.history.append( self._make_history(responses, record_output=record_output)) self._state = new_state def run_all_turns(self): assert self._state.turn == 0 if self._print_info: print(('Match seed: {0}'.format(self.seed))) self._save_state(self._state, 0) while self._state.turn < settings.max_turns: self.run_turn() # create last turn's state for server history if self._record_history: self.history.append(self._make_history(({}, {}))) # create dummy data for last turn # TODO: render should be cleverer actions_on_turn = {} for loc, robot in self._state.robots.items(): log_item = { 'name': '', 'target': None, 'loc': loc, 'hp': robot.hp, 'player': robot.player_id, 'loc_end': loc, 'hp_end': robot.hp } actions_on_turn[loc] = log_item self._save_actions_on_turn(actions_on_turn, settings.max_turns) def get_scores(self): return self.get_state(settings.max_turns).get_scores()
class Game(object): def __init__(self, players, record_actions=False, record_history=False, print_info=False, seed=None, quiet=0, delta_callback=None, symmetric=True): self._players = players for i, player in enumerate(self._players): player.set_player_id(i) self._record_actions = record_actions self._record_history = record_history self._print_info = print_info if seed is None: seed = random.randint(0, settings.max_seed) self.seed = str(seed) self._random = random.Random(self.seed) self._quiet = quiet self._delta_callback = delta_callback self._state = GameState(use_start=True, seed=self.seed, symmetric=symmetric) self._actions_on_turn = {} self._states = {} self.history = [] # TODO: make private # actions_on_turn = {loc: log_item} # log_item = { # 'name': action_name, # 'target': action_target or None, # 'loc': loc, # 'hp': hp, # 'player': player_id, # 'loc_end': loc_end, # 'hp_end': hp_end # } # # or dummy if turn == settings.max_turn def get_actions_on_turn(self, turn): assert self._record_actions return self._actions_on_turn[turn] def get_state(self, turn): return self._states[turn] def _save_actions_on_turn(self, actions_on_turn, turn): self._actions_on_turn[turn] = actions_on_turn def _save_state(self, state, turn): self._states[turn] = state def _get_robots_actions(self): if self._quiet >= 1: sys.stdout = NullDevice() if self._quiet >= 2: sys.stderr = NullDevice() actions = {} for player in self._players: seed = self._random.randint(0, settings.max_seed) actions.update(player.get_actions(self._state, seed)) if self._quiet >= 1: sys.stdout = sys.__stdout__ if self._quiet >= 2: sys.stderr = sys.__stderr__ return actions def _make_history(self, actions): ''' An aggregate of all bots and their actions this turn. Stores a list of each player's bots at the start of this turn and the actions they each performed this turn. Newly spawned bots have no actions. ''' robots = [] for loc, robot in self._state.robots.iteritems(): robot_info = { 'location': loc, 'hp': robot.hp, 'player_id': robot.player_id, 'robot_id': robot.robot_id, } if loc in actions: robot_info['action'] = actions[loc] robots.append(robot_info) return robots def _calculate_actions_on_turn(self, delta, actions): actions_on_turn = {} for delta_info in delta: loc = delta_info.loc if loc in actions: name = actions[loc][0] if name in ['move', 'attack']: target = actions[loc][1] else: target = None else: name = 'spawn' target = None # note that a spawned bot may overwrite an existing bot actions_on_turn[loc] = { 'name': name, 'target': target, 'loc': loc, 'hp': delta_info.hp, 'player': delta_info.player_id, 'loc_end': delta_info.loc_end, 'hp_end': delta_info.hp_end } return actions_on_turn def run_turn(self): if self._print_info: print(' running turn %d ' % (self._state.turn)).center(70, '-') actions = self._get_robots_actions() delta = self._state.get_delta(actions) if self._record_actions: actions_on_turn = self._calculate_actions_on_turn(delta, actions) self._save_actions_on_turn(actions_on_turn, self._state.turn) new_state = self._state.apply_delta(delta) if self._delta_callback is not None and self._state.turn > 1: self._delta_callback(delta, new_state) self._save_state(new_state, new_state.turn) if self._record_history: self.history.append(self._make_history(actions)) self._state = new_state def run_all_turns(self): assert self._state.turn == 0 if self._print_info: print('Match seed: {0}'.format(self.seed)) self._save_state(self._state, 0) while self._state.turn < settings.max_turns: self.run_turn() # create last turn's state for server history if self._record_history: self.history.append(self._make_history({})) # create dummy data for last turn # TODO: render should be cleverer actions_on_turn = {} for loc, robot in self._state.robots.iteritems(): log_item = { 'name': '', 'target': None, 'loc': loc, 'hp': robot.hp, 'player': robot.player_id, 'loc_end': loc, 'hp_end': robot.hp } actions_on_turn[loc] = log_item self._save_actions_on_turn(actions_on_turn, settings.max_turns) def get_scores(self): return self.get_state(settings.max_turns).get_scores()
class Game(object): def __init__(self, players, record_actions=False, record_history=False, print_info=False, seed=None, quiet=0, delta_callback=None, symmetric=True): self._players = players for i, player in enumerate(self._players): player.set_player_id(i) self._record_actions = record_actions self._record_history = record_history self._print_info = print_info if seed is None: seed = random.randint(0, settings.max_seed) self.seed = str(seed) self._random = random.Random(self.seed) self._quiet = quiet self._delta_callback = delta_callback self._state = GameState(use_start=True, seed=self.seed, symmetric=symmetric) self._actions_on_turn = {} self._states = {} self.history = [] # TODO: make private # actions_on_turn = {loc: log_item} # log_item = { # 'name': action_name, # 'target': action_target or None, # 'loc': loc, # 'hp': hp, # 'player': player_id, # 'loc_end': loc_end, # 'hp_end': hp_end # } # # or dummy if turn == settings.max_turn def get_actions_on_turn(self, turn): assert self._record_actions return self._actions_on_turn[turn] def get_state(self, turn): return self._states[turn] def _save_actions_on_turn(self, actions_on_turn, turn): self._actions_on_turn[turn] = actions_on_turn def _save_state(self, state, turn): self._states[turn] = state def _get_robots_responses(self): # TODO: honour quietness actions, outputs = {}, {} for player in self._players: seed = self._random.randint(0, settings.max_seed) responses = player.get_responses(self._state, seed) actions.update(responses[0]) outputs.update(responses[1]) return actions, outputs def _make_history(self, responses, record_output=False): # todo: rework this. We are getting data about the player # from two sources: 1) from arguments, and 2) from # class members. Either move *all* to 1) and make # static or move all to 2). ''' An aggregate of all bots and their actions this turn. Optionally records per-bot output. Stores a list of each player's bots at the start of this turn and the actions they each performed this turn. Newly spawned bots have no actions. ''' actions, outputs = responses robots = [] for loc, robot in self._state.robots.items(): robot_info = { 'location': loc, 'hp': robot.hp, 'player_id': robot.player_id, 'robot_id': robot.robot_id, } if loc in actions: # since the state after the final turn does not contain any # actions, 'loc' is not always contained in 'actions' robot_info['action'] = actions[loc] if outputs and loc in outputs: robot_info['output'] = outputs[loc] robots.append(robot_info) return robots def _calculate_actions_on_turn(self, delta, actions): actions_on_turn = {} for delta_info in delta: loc = delta_info.loc if loc in actions: name = actions[loc][0] if name in ['move', 'attack']: target = actions[loc][1] else: target = None else: name = 'spawn' target = None # note that a spawned bot may overwrite an existing bot actions_on_turn[loc] = { 'name': name, 'target': target, 'loc': loc, 'hp': delta_info.hp, 'player': delta_info.player_id, 'loc_end': delta_info.loc_end, 'hp_end': delta_info.hp_end } return actions_on_turn def run_turn(self, record_output=False): if self._print_info: print((' running turn %d ' % (self._state.turn)).center(70, '-')) responses = self._get_robots_responses() actions = responses[0] delta = self._state.get_delta(actions) if self._record_actions: actions_on_turn = self._calculate_actions_on_turn(delta, actions) self._save_actions_on_turn(actions_on_turn, self._state.turn) new_state = self._state.apply_delta(delta) if self._delta_callback is not None and self._state.turn > 1: self._delta_callback(delta, new_state) self._save_state(new_state, new_state.turn) if self._record_history: self.history.append(self._make_history( responses, record_output=record_output)) self._state = new_state def run_all_turns(self): assert self._state.turn == 0 if self._print_info: print(('Match seed: {0}'.format(self.seed))) self._save_state(self._state, 0) while self._state.turn < settings.max_turns: self.run_turn() # create last turn's state for server history if self._record_history: self.history.append(self._make_history(({}, {}))) # create dummy data for last turn # TODO: render should be cleverer actions_on_turn = {} for loc, robot in self._state.robots.items(): log_item = { 'name': '', 'target': None, 'loc': loc, 'hp': robot.hp, 'player': robot.player_id, 'loc_end': loc, 'hp_end': robot.hp } actions_on_turn[loc] = log_item self._save_actions_on_turn(actions_on_turn, settings.max_turns) def get_scores(self): return self.get_state(settings.max_turns).get_scores()