diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index 35b780927a624d9cc0a4fb7adf9f75e90f456a55..372a309a2bfb23681a8d34703135952f96ca2cb4 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -1,5 +1,6 @@ from __future__ import annotations +import random from typing import TYPE_CHECKING import numpy.typing as npt @@ -75,14 +76,19 @@ class Environment: "T": lambda pos: Dispenser(pos, self.item_info["Tomato"]), "L": lambda pos: Dispenser(pos, self.item_info["Lettuce"]), "P": lambda pos: Dispenser(pos, self.item_info["Plate"]), - "_": None, + "_": "Free", + "A": "Agent", "U": lambda pos: Stove( pos, self.item_info["Pot"].create_item(), ), # Stove with pot: U because it looks like a pot } - self.counters, self.free_positions = self.create_counters(self.layout_path) + ( + self.counters, + self.designated_player_positions, + self.free_positions, + ) = self.parse_layout_file(self.layout_path) self.score: int = 0 self.world_width: int = 800 self.world_height: int = 600 @@ -99,7 +105,7 @@ class Environment: item_info.equipment.add_start_item_to_equipment(item_info) return item_lookup - def create_counters(self, layout_file: Path): + def parse_layout_file(self, layout_file: Path): """Creates layout of kitchen counters in the environment based on layout file. Counters are arranged in a fixed size grid starting at [0,0]. The center of the first counter is at [counter_size/2, counter_size/2], counters are directly next to each other (of no empty space is specified @@ -110,6 +116,7 @@ class Environment: """ current_y: float = self.counter_side_length / 2 counters: list[Counter] = [] + designated_player_positions: list[npt.NDArray] = [] free_positions: list[npt.NDArray] = [] with open(layout_file, "r") as layout_file: @@ -121,16 +128,20 @@ class Environment: character = character.capitalize() pos = np.array([current_x, current_y]) counter_class = self.SYMBOL_TO_CHARACTER_MAP[character] - if counter_class is not None: + if not isinstance(counter_class, str): counter = counter_class(pos) counters.append(counter) else: - free_positions.append(np.array([current_x, current_y])) + if counter_class == "Agent": + designated_player_positions.append( + np.array([current_x, current_y]) + ) + elif counter_class == "Free": + free_positions.append(np.array([current_x, current_y])) current_x += self.counter_side_length current_y += self.counter_side_length - - return counters, free_positions + return counters, designated_player_positions, free_positions def perform_action(self, action: Action): """Performs an action of a player in the environment. Maps different types of action inputs to the @@ -332,6 +343,22 @@ class Environment: distance = np.linalg.norm([dx, dy]) return distance < player.radius + def add_player(self, player: Player): + # print(f"Added player {player.name} to the game.") + + self.players[player.name] = player + if player.pos is None: + if len(self.designated_player_positions) > 0: + free_idx = random.randint(0, len(self.designated_player_positions) - 1) + player.move_abs(self.designated_player_positions[free_idx]) + del self.designated_player_positions[free_idx] + elif len(self.free_positions) > 0: + free_idx = random.randint(0, len(self.free_positions) - 1) + player.move_abs(self.free_positions[free_idx]) + del self.free_positions[free_idx] + else: + print("No free positions left in kitchens.") + def detect_collision_world_bounds(self, player: Player): """Checks for detections of the player and the world bounds. diff --git a/overcooked_simulator/simulation_runner.py b/overcooked_simulator/simulation_runner.py index dbb3d4c491b82995f19126ca414ab6ad4b5dc4ab..d28f0b689b276f8c0eb066d20341d4c95edca97d 100644 --- a/overcooked_simulator/simulation_runner.py +++ b/overcooked_simulator/simulation_runner.py @@ -71,16 +71,7 @@ class Simulator(Thread): Args: player: The player to be added. """ - # print(f"Added player {player.name} to the game.") - - self.env.players[player.name] = player - if player.pos is None: - if len(self.env.free_positions) > 0: - free_idx = random.randint(0, len(self.env.free_positions) - 1) - player.move_abs(self.env.free_positions[free_idx]) - del self.env.free_positions[free_idx] - else: - print("No free positions left in kitchens.") + self.env.add_player(player) def register_players(self, players: list[Player]): """Registers multiple players from a list @@ -95,8 +86,6 @@ class Simulator(Thread): def run(self): """Starts the simulator thread. Runs in a loop until stopped.""" - for p in self.env.players.values(): - print(p.pos) assert all( p.pos is not None for p in self.env.players.values() ), "At least one player position not initialized"