From 0a07c058337d03001a142872349a2c243be291cc Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Fri, 24 Mar 2023 11:47:48 +0000 Subject: [PATCH 1/2] add flag to randomise spawn - by default randomisation is turned on, to ensure consistency with prior versions - without randomisation, agents are spawned in corners of maps and food are spawned in the center - if spawn points are already occupied then increasing degrees of randomisation are added to ensure that items can still be spawned --- lbforaging/foraging/environment.py | 37 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/lbforaging/foraging/environment.py b/lbforaging/foraging/environment.py index 35497f7..4bb73b6 100644 --- a/lbforaging/foraging/environment.py +++ b/lbforaging/foraging/environment.py @@ -82,6 +82,7 @@ def __init__( sight, max_episode_steps, force_coop, + randomise_spawn=True, normalize_reward=True, grid_observation=False, penalty=0.0, @@ -99,6 +100,7 @@ def __init__( self.max_player_level = max_player_level self.sight = sight self.force_coop = force_coop + self.randomise_spawn = randomise_spawn self._game_over = None self._rendering_initialized = False @@ -253,8 +255,16 @@ def spawn_food(self, max_food, max_level): while food_count < max_food and attempts < 1000: attempts += 1 - row = self.np_random.randint(1, self.rows - 1) - col = self.np_random.randint(1, self.cols - 1) + if self.randomise_spawn: + # spawn food randomly + row = self.np_random.randint(1, self.rows - 1) + col = self.np_random.randint(1, self.cols - 1) + else: + # spawn food in the center of the map + # randomise around center to be able to spawn multiple food + rand = attempts // 10 + row = self.rows // 2 + self.np_random.randint(-rand, rand+1) + col = self.cols // 2 + self.np_random.randint(-rand, rand+1) # check if it has neighbors: if ( @@ -290,8 +300,27 @@ def spawn_players(self, max_player_level): player.reward = 0 while attempts < 1000: - row = self.np_random.randint(0, self.rows) - col = self.np_random.randint(0, self.cols) + if self.randomise_spawn: + # spawn player randomly + row = self.np_random.randint(0, self.rows) + col = self.np_random.randint(0, self.cols) + else: + # spawn players in corners + rand = attempts // 10 + corners = [ + (0, 0), + (0, self.cols - 1), + (self.rows - 1, 0), + (self.rows - 1, self.cols - 1), + ] + for row, col in corners: + # add increasing small randomisation after 10+ attempts + row = row + self.np_random.randint(-rand, rand+1) + col = col + self.np_random.randint(-rand, rand+1) + if self._is_empty_location(row, col): + # found empty corner + break + if self._is_empty_location(row, col): player.setup( (row, col), From 22df79e004802f97db644a5e0f4c6549d4bd0f58 Mon Sep 17 00:00:00 2001 From: Lukas Schaefer Date: Fri, 24 Mar 2023 12:52:44 +0000 Subject: [PATCH 2/2] ensure player and food spawns are valid - player spawns within the map - food spawns within the map, excluding first and low row or column --- lbforaging/foraging/environment.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lbforaging/foraging/environment.py b/lbforaging/foraging/environment.py index 4bb73b6..a14c1a5 100644 --- a/lbforaging/foraging/environment.py +++ b/lbforaging/foraging/environment.py @@ -263,8 +263,8 @@ def spawn_food(self, max_food, max_level): # spawn food in the center of the map # randomise around center to be able to spawn multiple food rand = attempts // 10 - row = self.rows // 2 + self.np_random.randint(-rand, rand+1) - col = self.cols // 2 + self.np_random.randint(-rand, rand+1) + row = max(1, min(self.rows - 2, self.rows // 2 + self.np_random.randint(-rand, rand+1))) + col = max(1, min(self.cols - 2, self.cols // 2 + self.np_random.randint(-rand, rand+1))) # check if it has neighbors: if ( @@ -274,6 +274,7 @@ def spawn_food(self, max_food, max_level): ): continue + self.field[row, col] = ( min_level if min_level == max_level @@ -315,8 +316,8 @@ def spawn_players(self, max_player_level): ] for row, col in corners: # add increasing small randomisation after 10+ attempts - row = row + self.np_random.randint(-rand, rand+1) - col = col + self.np_random.randint(-rand, rand+1) + row = max(0, min(self.rows - 1, row + self.np_random.randint(-rand, rand+1))) + col = max(0, min(self.cols - 1, col + self.np_random.randint(-rand, rand+1))) if self._is_empty_location(row, col): # found empty corner break @@ -504,6 +505,7 @@ def reset(self): self.spawn_food( self.max_food, max_level=sum(player_levels[:3]) ) + self.current_step = 0 self._game_over = False self._gen_valid_moves()