diff --git a/pelita/game.py b/pelita/game.py index 11c8ab74e..d3b62c9ef 100644 --- a/pelita/game.py +++ b/pelita/game.py @@ -433,6 +433,9 @@ def setup_game(team_specs, *, layout_dict, max_rounds=300, rng=None, # List of boolean flags weather bot has been eaten since its last move bot_was_killed = [False]*4, + # List of pellets eaten by a bot + food_eaten = [0]*4, + # The noisy positions that the bot in `turn` has currently been shown. # None, if not noisy noisy_positions = [None] * 4, @@ -704,6 +707,7 @@ def prepare_bot_state(game_state, team_idx=None): 'kills': game_state['kills'][own_team::2], 'deaths': game_state['deaths'][own_team::2], 'bot_was_killed': game_state['bot_was_killed'][own_team::2], + 'food_eaten': game_state['food_eaten'][own_team::2], 'food': list(game_state['food'][own_team]), 'shaded_food': shaded_food, 'name': game_state['team_names'][own_team], @@ -718,6 +722,7 @@ def prepare_bot_state(game_state, team_idx=None): 'kills': game_state['kills'][enemy_team::2], 'deaths': game_state['deaths'][enemy_team::2], 'bot_was_killed': game_state['bot_was_killed'][enemy_team::2], + 'food_eaten': game_state['food_eaten'][enemy_team::2], 'food': list(game_state['food'][enemy_team]), 'shaded_food': [], 'name': game_state['team_names'][enemy_team], @@ -956,6 +961,7 @@ def apply_move(gamestate, bot_position): kills = gamestate["kills"] deaths = gamestate["deaths"] bot_was_killed = gamestate["bot_was_killed"] + food_eaten = gamestate["food_eaten"] # reset our own bot_was_killed flag bot_was_killed[turn] = False @@ -987,6 +993,7 @@ def apply_move(gamestate, bot_position): if not in_homezone(bot_position, team, shape): if bot_position in food[1 - team]: _logger.info(f"Bot {turn} eats food at {bot_position}.") + food_eaten[turn] += 1 food[1 - team].remove(bot_position) # This is modifying the old game state score[team] = score[team] + 1 @@ -1000,6 +1007,7 @@ def apply_move(gamestate, bot_position): "score": score, "deaths": deaths, "kills": kills, + "food_eaten": food_eaten, "bot_was_killed": bot_was_killed, "game_phase": "RUNNING", } diff --git a/pelita/team.py b/pelita/team.py index 8ea3e61ee..00dc0a20d 100644 --- a/pelita/team.py +++ b/pelita/team.py @@ -668,6 +668,7 @@ def __init__(self, *, bot_index, kills, deaths, was_killed, + food_eaten, random, graph, round, @@ -700,6 +701,7 @@ def __init__(self, *, bot_index, self.kills = kills self.deaths = deaths self.was_killed = was_killed + self.food_eaten = food_eaten self._bot_index = bot_index self.round = round self.char = bot_char @@ -943,6 +945,7 @@ def make_bots(*, walls, shape, initial_positions, homezone, team, enemy, round, deaths=team['deaths'][idx], kills=team['kills'][idx], was_killed=team['bot_was_killed'][idx], + food_eaten=team['food_eaten'][idx], is_noisy=False, food=_ensure_list_tuples(team['food']), shaded_food=_ensure_list_tuples(team['shaded_food']), @@ -970,6 +973,7 @@ def make_bots(*, walls, shape, initial_positions, homezone, team, enemy, round, kills=enemy['kills'][idx], deaths=enemy['deaths'][idx], was_killed=enemy['bot_was_killed'][idx], + food_eaten=team['food_eaten'][idx], is_noisy=enemy['is_noisy'][idx], food=_ensure_list_tuples(enemy['food']), shaded_food=[], diff --git a/pelita/ui/tk_canvas.py b/pelita/ui/tk_canvas.py index f9a66ea2a..8d13ed226 100644 --- a/pelita/ui/tk_canvas.py +++ b/pelita/ui/tk_canvas.py @@ -867,10 +867,11 @@ def status(team_idx): err_desc = game_state['fatal_errors'][team_idx][0]['description'] ret = f"FATAL: {err_type} {err_desc}" else: - # sum the deaths of both bots in this team - deaths = game_state['deaths'][team_idx] + game_state['deaths'][team_idx+2] + # sum the counters of both bots in this team kills = game_state['kills'][team_idx] + game_state['kills'][team_idx+2] - ret = "Kills: %d, Deaths: %d, Time: %.2f" % (kills, deaths, game_state["team_time"][team_idx]) + food_eaten = game_state['food_eaten'][team_idx] + game_state['food_eaten'][team_idx+2] + team_time = game_state["team_time"][team_idx] + ret = f"Food: {food_eaten}, Kills: {kills}, Time: {team_time:.2f}" return ret except TypeError: return "" diff --git a/pelita/utils.py b/pelita/utils.py index 5d6a9f01f..23bc9afb3 100644 --- a/pelita/utils.py +++ b/pelita/utils.py @@ -228,6 +228,7 @@ def setup_test_game(*, layout, is_blue=True, round=None, score=None, seed=None, 'kills': [0]*2, 'deaths': [0]*2, 'bot_was_killed' : [False]*2, + 'food_eaten': [0]*2, 'food': food[team_index], 'shaded_food': list(shaded_food(bot_positions, food[team_index], radius=SHADOW_DISTANCE)), 'name': "blue" if is_blue else "red", @@ -240,6 +241,7 @@ def setup_test_game(*, layout, is_blue=True, round=None, score=None, seed=None, 'kills': [0]*2, 'deaths': [0]*2, 'bot_was_killed': [False]*2, + 'food_eaten': [0]*2, 'food': food[enemy_index], 'shaded_food': [], 'is_noisy': is_noisy_enemy, diff --git a/test/test_game.py b/test/test_game.py index c0c8fd4ae..7ee1b995a 100644 --- a/test/test_game.py +++ b/test/test_game.py @@ -633,6 +633,7 @@ def test_moving_through_maze(): assert test_first_round['bots'] == state['bots'] assert test_first_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 0, 0, 0] assert state['score'] == [0, 0] for i in range(4): @@ -646,6 +647,7 @@ def test_moving_through_maze(): assert test_second_round['bots'] == state['bots'] assert test_second_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 0, 0] assert state['score'] == [0, 1] for i in range(4): @@ -659,6 +661,7 @@ def test_moving_through_maze(): assert test_third_round['bots'] == state['bots'] assert test_third_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 0, 0] assert state['score'] == [game.KILL_POINTS, 1] for i in range(4): @@ -672,6 +675,7 @@ def test_moving_through_maze(): assert test_fourth_round['bots'] == state['bots'] assert test_fourth_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 0, 0] assert state['score'] == [game.KILL_POINTS, game.KILL_POINTS + 1] for i in range(4): @@ -684,6 +688,7 @@ def test_moving_through_maze(): ###### """) assert test_fifth_round['bots'] == state['bots'] assert test_fifth_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 0, 0] assert state['score'] == [game.KILL_POINTS * 2, game.KILL_POINTS + 1] for i in range(4): @@ -698,6 +703,7 @@ def test_moving_through_maze(): assert test_sixth_round['bots'] == state['bots'] assert test_sixth_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 0, 0] assert state['score'] == [game.KILL_POINTS * 2, game.KILL_POINTS * 2+ 1] for i in range(3): # !! Only move three bots @@ -713,6 +719,7 @@ def test_moving_through_maze(): assert test_seventh_round['bots'] == state['bots'] assert test_seventh_round['food'] == list(state['food'][0]) + list(state['food'][1]) + assert state['food_eaten'] == [0, 1, 1, 0] assert state['score'] == [game.KILL_POINTS * 2 + 1, game.KILL_POINTS * 2 + 1] assert state['gameover'] is True assert state['whowins'] == 2 @@ -753,6 +760,7 @@ def test_play_turn_move(): "kills":[0]*4, "deaths": [0]*4, "bot_was_killed": [False]*4, + "food_eaten": [0]*4, "fatal_errors": [{}, {}], "rng": Random(), "game_phase": "RUNNING", diff --git a/test/test_network.py b/test/test_network.py index 967c420b4..ae3d08fa9 100644 --- a/test/test_network.py +++ b/test/test_network.py @@ -91,6 +91,7 @@ def stopping(bot, state): 'kills': [0]*2, 'deaths': [0]*2, 'bot_was_killed': [False]*2, + 'food_eaten': [0]*2, 'food': [(1, 1)], 'shaded_food': [(1, 1)], 'name': 'dummy', @@ -103,6 +104,7 @@ def stopping(bot, state): 'kills': [0]*2, 'deaths': [0]*2, 'bot_was_killed': [False]*2, + 'food_eaten': [0]*2, 'food': [(2, 2)], 'shaded_food': [], 'name': 'other dummy', diff --git a/test/test_team.py b/test/test_team.py index 9afbaa356..026779142 100644 --- a/test/test_team.py +++ b/test/test_team.py @@ -72,7 +72,7 @@ def test_round_counting(): assert round_counting_team._storage['rounds'] == 3 def test_track_and_kill_count(): - # for each team, we track whether they have been eaten at least once + # for each team, we track whether they have been killed/eaten at least once # and count the number of times they have been killed bot_states = { 0: [{'track': [], 'eaten': False, 'times_killed': 0, 'deaths': 0}, @@ -183,13 +183,13 @@ def trackingBot(bot, state): assert state['round'] >= 1 # check that someone has been killed, or the whole test is not doing anything assert sum(state['deaths']) > 0 - # check that each single bot has been eaten, or we are not testing the full range of possibilities + # check that each single bot has been killed, or we are not testing the full range of possibilities assert all(state['deaths']) @pytest.mark.parametrize('bot_to_move', range(4)) -def test_eaten_flag_kill(bot_to_move): - """ Test that the eaten flag is set correctly in kill situations. """ +def test_was_killed_flag(bot_to_move): + """ Test that the was_killed flag is set correctly in kill situations. """ layout = """ ######## # xa # @@ -208,7 +208,7 @@ def move(bot, state): if bot.round == 1 and not bot.is_blue and bot.turn == 0: assert bot.was_killed assert bot.other.was_killed is False - # as bot 1 has been moved, the eaten flag will be reset in all other cases + # as bot 1 has been moved, the was_killed flag will be reset in all other cases else: assert bot.was_killed is False assert bot.other.was_killed is False @@ -216,7 +216,7 @@ def move(bot, state): # we move in the first round as red team if bot.round == 1 and not bot.is_blue and bot.turn == 0: new_pos = (x + 1, y) - # The other team should notice immediately that its other bot (#0) has been eaten + # The other team should notice immediately that its other bot (#0) has been killed if bot.round == 1 and bot.is_blue and bot.turn == 1: assert bot.was_killed is False assert bot.other.was_killed @@ -235,7 +235,7 @@ def move(bot, state): if bot.round == 1 and not bot.is_blue and bot.turn == 1: assert bot.was_killed assert bot.other.was_killed is False - # as bot 2 has been moved, the eaten flag will be reset in all other cases + # as bot 2 has been moved, the was_killed flag will be reset in all other cases else: assert bot.was_killed is False assert bot.other.was_killed is False @@ -243,7 +243,7 @@ def move(bot, state): # we move in the first round as red team in turn == 1 if bot.round == 1 and not bot.is_blue and bot.turn == 1: new_pos = (x + 1, y) - # The blue team should notice immediately (in round == 2!) that bot 1 has been eaten + # The blue team should notice immediately (in round == 2!) that bot 1 has been was killed if bot.round == 2 and bot.is_blue and bot.turn == 0: assert bot.was_killed is False assert bot.other.was_killed @@ -264,8 +264,8 @@ def move(bot, state): @pytest.mark.parametrize("bot_to_move", range(4)) -def test_eaten_flag_suicide(bot_to_move): - """ Test that the eaten flag is set correctly in suicide situations. """ +def test_was_killed_flag_suicide(bot_to_move): + """ Test that the was_killed flag is set correctly in suicide situations. """ layout = """ ######## # ax # @@ -423,6 +423,7 @@ def asserting_team(bot, state): assert set(bot.other.shaded_food) == shaded_food assert set(bot.enemy[0].shaded_food) == set() assert set(bot.enemy[1].shaded_food) == set() + assert bot.food_eaten == 0 else: assert set(bot.homezone) == set(homezones[1]) assert set(bot.enemy[0].homezone) == set(homezones[0]) @@ -430,6 +431,7 @@ def asserting_team(bot, state): assert set(bot.other.shaded_food) == set() assert set(bot.enemy[0].shaded_food) == set() assert set(bot.enemy[1].shaded_food) == set() + assert bot.food_eaten == 0 return bot.position state = run_game([asserting_team, asserting_team], max_rounds=1, layout_dict=parsed)