From 35756c6b9b254cd698928c371ba3d4b73d2e88b3 Mon Sep 17 00:00:00 2001
From: fheinrich <fheinrich@techfak.uni-bielefeld.de>
Date: Fri, 15 Dec 2023 14:32:55 +0100
Subject: [PATCH] If "A" is in layout config then players are placed there. If
 no "A"-space left: random free tile

---
 .../overcooked_environment.py                 | 41 +++++++++++++++----
 overcooked_simulator/simulation_runner.py     | 13 +-----
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index 35b78092..372a309a 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 dbb3d4c4..d28f0b68 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"
-- 
GitLab