From 3f3344c3d52598fdd57d5ee6018b066383427aa9 Mon Sep 17 00:00:00 2001
From: fheinrich <fheinrich@techfak.uni-bielefeld.de>
Date: Mon, 4 Dec 2023 15:18:00 +0100
Subject: [PATCH] Added collision detectio for player with players and player
 with counters

---
 .../overcooked_environment.py                 | 51 ++++++++++++++++++-
 overcooked_simulator/player.py                |  1 +
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index c6e4970e..16986f61 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -143,9 +143,58 @@ class Environment:
             player: The player for which to check collisions.
 
         Returns: True if the player is intersecting with any object in the environment.
+        """
+        return self.detect_player_collision(player) or self.detect_collision_counters(player)
+
+    def detect_player_collision(self, player: Player):
+        """Detects collisions between the queried player and other players.
+        A player is modelled as a circle. Collision is detected if the distance between the players is smaller
+        than the sum of the radius's.
+
+        Args:
+            player: The player to check collisions with other players for.
+
+        Returns: True if the player collides with other players, False if not.
 
         """
-        pass
+        other_players = filter(lambda p: p.name != player.name, self.players.values())
+
+        def collide(p):
+            return np.linalg.norm(player.pos - p.pos) <= (player.radius + p.radius)
+
+        return any(map(collide, other_players))
+
+    def detect_collision_counters(self, player: Player):
+        """Checks for collisions of the queried player with each counter.
+
+        Args:
+            player:  The player to check collisions with counters for.
+
+        Returns: True if the player collides with any counter, False if not.
+
+        """
+        return any(map(lambda counter: self.detect_collision_player_counter(player, counter), self.counters))
+
+    def detect_collision_player_counter(self, player: Player, counter: Counter):
+        """Checks if the player and counter collide (overlap).
+        A counter is modelled as a rectangle (square actually), a player is modelled as a circle.
+        The distance of the player position (circle center) and the counter rectangle is calculated, if it is
+        smaller than the player radius, a collision is detected.
+        TODO: Efficiency improvement by checking only nearest counters? Quadtree...?
+
+        Args:
+            player: The player to check the collision for.
+            counter: The counter to check the collision for.
+
+        Returns: True if player and counter overlap, False if not.
+
+        """
+        size = self.counter_side_length
+        cx, cy = player.pos
+        dx = max(np.abs(cx - counter.pos[0]) - size / 2, 0)
+        dy = max(np.abs(cy - counter.pos[1]) - size / 2, 0)
+        distance = np.linalg.norm([dx, dy])
+        return distance < player.radius
 
     def step(self):
         """Performs a step of the environment. Affects time based events such as cooking or cutting things, orders
diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py
index b98df2d6..bea1771a 100644
--- a/overcooked_simulator/player.py
+++ b/overcooked_simulator/player.py
@@ -13,6 +13,7 @@ class Player:
         self.pos = np.array(pos, dtype=float)
         self.holding = None
 
+        self.radius = 18
         self.move_dist = 5
         self.interaction_range = 50
         self.facing_direction = np.array([0, 1])
-- 
GitLab