diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py index 50d76412e0d235ef047dcc6b5ce5756ee0dcd209..b05ab74b02f008769f35328993222966f798f92d 100644 --- a/overcooked_simulator/counters.py +++ b/overcooked_simulator/counters.py @@ -92,11 +92,19 @@ class Counter: """ self.pos: npt.NDArray[float] = pos self.occupied_by: Optional[Item] = occupied_by + self.orientation: npt.NDArray[float] = np.zeros(2) + self.orientation[0] = 1 @property def occupied(self): return self.occupied_by is not None + def set_orientation(self, orientation: npt.NDArray[float]) -> None: + if not np.isclose(np.linalg.norm(orientation), 1): + self.orientation = orientation / np.linalg.norm(orientation) + else: + self.orientation = orientation + def pick_up(self, on_hands: bool = True) -> Item | None: """Gets called upon a player performing the pickup action. If the counter can give something to the player, it does so. In the standard counter this is when an item is on the counter. diff --git a/overcooked_simulator/game_content/layouts/basic.layout b/overcooked_simulator/game_content/layouts/basic.layout index 2e7395aa296304bae3d354eea5613affcc0ee6b0..e9639b310fd9589d3df287fd72e0289ec9145194 100644 --- a/overcooked_simulator/game_content/layouts/basic.layout +++ b/overcooked_simulator/game_content/layouts/basic.layout @@ -1,9 +1,9 @@ -#QU#T###NLB# -#__________M -#__________# -W___________ -#__A_____A__ -C___________ -C__________# -#__________X -#P#S+####S+# \ No newline at end of file +#QU#T###NLB## +#__________M# +#__________## +W___________# +#__A_____A__# +C___________# +C__________## +#__________X# +#P#S+####S+## \ No newline at end of file diff --git a/overcooked_simulator/gui_2d_vis/overcooked_gui.py b/overcooked_simulator/gui_2d_vis/overcooked_gui.py index ed86bfadef2c895c956222e211e6c8aab0066e16..e62318bcf9cdb730e54a15d38eceef9895b1d148 100644 --- a/overcooked_simulator/gui_2d_vis/overcooked_gui.py +++ b/overcooked_simulator/gui_2d_vis/overcooked_gui.py @@ -32,7 +32,7 @@ from overcooked_simulator.simulation_runner import Simulator USE_PLAYER_COOK_SPRITES = True SHOW_INTERACTION_RANGE = False -SHOW_COUNTER_CENTERS = False +SHOW_COUNTER_CENTERS = True class MenuStates(Enum): @@ -557,10 +557,35 @@ class PyGameGUI: Args: state: The game state returned by the environment. """ + + pygame.draw.circle( + self.game_screen, + colors["red"], + np.array([self.game_width / 2, self.game_height / 2]), + 3, + ) + for counter in state["counters"]: self.draw_counter(counter) if SHOW_COUNTER_CENTERS: - pygame.draw.circle(self.game_screen, colors["green1"], counter.pos, 3) + pos = counter.pos * self.grid_size + pygame.draw.circle(self.game_screen, colors["green1"], pos, 3) + facing = counter.orientation + pygame.draw.polygon( + self.game_screen, + colors["red"], + ( + ( + pos[0] + (facing[1] * 0.1 * self.grid_size), + pos[1] - (facing[0] * 0.1 * self.grid_size), + ), + ( + pos[0] - (facing[1] * 0.1 * self.grid_size), + pos[1] + (facing[0] * 0.1 * self.grid_size), + ), + pos + (facing * 0.5 * self.grid_size), + ), + ) def update_score_label(self, state): score = state["score"] diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index b60ed369dbeab16833d0a2dad499ec0bac84d59a..7f13e0360617c05046be4950a1abeadb057c36cc 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -342,9 +342,12 @@ class Environment: lines = layout_file.readlines() self.kitchen_height = len(lines) + grid = [] + for line in lines: line = line.replace("\n", "").replace(" ", "") # remove newline char current_x = 0.5 + grid_line = [] for character in line: character = character.capitalize() pos = np.array([current_x, current_y]) @@ -352,7 +355,9 @@ class Environment: if not isinstance(counter_class, str): counter = counter_class(pos) counters.append(counter) + grid_line.append(1) else: + grid_line.append(0) if counter_class == "Agent": designated_player_positions.append( np.array([current_x, current_y]) @@ -362,12 +367,63 @@ class Environment: current_x += 1 if current_x > self.kitchen_width: self.kitchen_width = current_x + + grid.append(grid_line) current_y += 1 self.kitchen_width -= 0.5 + self.determine_counter_orientations( + counters, grid, np.array([self.kitchen_width / 2, self.kitchen_height / 2]) + ) + return counters, designated_player_positions, free_positions + def determine_counter_orientations(self, counters, grid, kitchen_center): + grid = np.array(grid).T + + grid_width = grid.shape[0] + grid_height = grid.shape[1] + + for c in counters: + grid_idx = np.floor(c.pos).astype(int) + neighbour_offsets = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]], dtype=int) + + neighbours = [] + for offset in neighbour_offsets: + neighbour_pos = grid_idx + offset + if ( + neighbour_pos[0] > (grid_width - 1) + or neighbour_pos[0] < 0 + or neighbour_pos[1] > (grid_height - 1) + or neighbour_pos[1] < 0 + ): + pass + else: + if grid[neighbour_pos[0]][neighbour_pos[1]] == 0: + neighbours.append(offset) + if len(neighbours) > 0: + vector_to_center = c.pos - kitchen_center + vector_to_center /= np.linalg.norm(vector_to_center) + n_idx = np.argmin( + np.linalg.norm(vector_to_center - n) for n in neighbours + ) + nearest_vec = neighbours[n_idx] + # print(nearest_vec, type(nearest_vec)) + c.set_orientation(nearest_vec) + + else: + print("HERE", c) + c.set_orientation(np.array([0, 1])) + + # for c in counters: + # near_counters = [ + # other + # for other in counters + # if np.isclose(np.linalg.norm(c.pos - other.pos), 1) + # ] + # # print(c.pos, len(near_counters)) + def perform_action(self, action: Action): """Performs an action of a player in the environment. Maps different types of action inputs to the correct execution of the players.