From 31e71d9df638656569bb7c03705055822d796b47 Mon Sep 17 00:00:00 2001
From: fheinrich <fheinrich@techfak.uni-bielefeld.de>
Date: Thu, 7 Dec 2023 09:39:02 +0100
Subject: [PATCH] Added plate which can hold a tomato.

---
 overcooked_simulator/counters.py              |  2 ++
 overcooked_simulator/game_items.py            | 28 +++++++++++++++++++
 overcooked_simulator/main.py                  |  4 ++-
 .../overcooked_environment.py                 |  6 ++--
 overcooked_simulator/player.py                |  4 +++
 overcooked_simulator/pygame_gui/pygame_gui.py | 13 ++++++++-
 6 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py
index 8955bc66..742b9bb1 100644
--- a/overcooked_simulator/counters.py
+++ b/overcooked_simulator/counters.py
@@ -46,6 +46,8 @@ class Counter:
         """
         if self.occupied_by is None:
             self.occupied_by = item
+        elif self.occupied_by.can_combine(item):
+            self.occupied_by.combine(item)
 
     def interact_start(self):
         """Starts an interaction by the player. Nothing happens for the standard counter."""
diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py
index 4255e14e..a40ad99d 100644
--- a/overcooked_simulator/game_items.py
+++ b/overcooked_simulator/game_items.py
@@ -3,6 +3,31 @@ class HoldableItem:
 
     pass
 
+    def can_combine(self, other):
+        return False
+
+    def combine(self, other):
+        pass
+
+
+class Plate(HoldableItem):
+    def __init__(self):
+        self.clean = True
+        self.holds = None
+
+        super().__init__()
+
+    def can_combine(self, other):
+        if self.holds is None:
+            if isinstance(other, HoldableItem):
+                return True
+
+    def combine(self, other):
+        self.holds = other
+
+    def __repr__(self):
+        return f"Plate({self.holds})"
+
 
 class ProgressibleItem(HoldableItem):
     """Class for items which need to be processed (cut, cooked, ...)"""
@@ -37,5 +62,8 @@ class CuttableItem(ProgressibleItem):
 class Tomato(CuttableItem):
     """Item class representing a tomato. Can be cut on the cutting board"""
 
+    def can_combine(self, other):
+        return False
+
     def __init__(self):
         super().__init__(steps_needed=1500)
diff --git a/overcooked_simulator/main.py b/overcooked_simulator/main.py
index ea66b93a..5138cab1 100644
--- a/overcooked_simulator/main.py
+++ b/overcooked_simulator/main.py
@@ -4,7 +4,7 @@ from pathlib import Path
 import numpy as np
 import pygame
 
-from overcooked_simulator.game_items import Tomato
+from overcooked_simulator.game_items import Tomato, Plate
 from overcooked_simulator.player import Player
 from overcooked_simulator.pygame_gui.pygame_gui import PyGameGUI
 from overcooked_simulator.simulation_runner import Simulator
@@ -19,6 +19,8 @@ def main():
 
     simulator.env.counters[3].occupied_by = Tomato()
     simulator.env.counters[4].occupied_by = Tomato()
+    simulator.env.counters[6].occupied_by = Plate()
+    simulator.env.counters[7].occupied_by = Plate()
 
     # TODO maybe read the player names and keyboard keys from config file?
     keys1 = [
diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py
index 3c8c036d..8aa9f198 100644
--- a/overcooked_simulator/overcooked_environment.py
+++ b/overcooked_simulator/overcooked_environment.py
@@ -183,9 +183,9 @@ class Environment:
         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)
-                or self.detect_collision_world_bounds(player)
+            self.detect_player_collision(player)
+            or self.detect_collision_counters(player)
+            or self.detect_collision_world_bounds(player)
         )
 
     def detect_player_collision(self, player: Player):
diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py
index 9ae0c9f2..48dd8c44 100644
--- a/overcooked_simulator/player.py
+++ b/overcooked_simulator/player.py
@@ -79,6 +79,10 @@ class Player:
             counter.drop_off(self.holding)
             self.holding = None
 
+        elif self.holding.can_combine(counter.occupied_by):
+            returned_by_counter = counter.pick_up()
+            self.holding.combine(returned_by_counter)
+
     def perform_interact_hold_start(self, counter: Counter):
         """Starts an interaction with the counter. Should be called for a
         keydown event, for holding down a key on the keyboard.
diff --git a/overcooked_simulator/pygame_gui/pygame_gui.py b/overcooked_simulator/pygame_gui/pygame_gui.py
index eff1e364..2db2b590 100644
--- a/overcooked_simulator/pygame_gui/pygame_gui.py
+++ b/overcooked_simulator/pygame_gui/pygame_gui.py
@@ -2,7 +2,7 @@ import numpy as np
 import pygame
 
 from overcooked_simulator.counters import CuttingBoard
-from overcooked_simulator.game_items import ProgressibleItem
+from overcooked_simulator.game_items import ProgressibleItem, Plate
 from overcooked_simulator.game_items import Tomato
 from overcooked_simulator.overcooked_environment import Action
 from overcooked_simulator.simulation_runner import Simulator
@@ -177,6 +177,17 @@ class PyGameGUI:
             rect.center = pos
             self.screen.blit(image, rect)
 
+        if isinstance(item, Plate):
+            image = pygame.image.load(
+                "overcooked_simulator/pygame_gui/images/plate.png"
+            ).convert_alpha()  # or .convert_alpha()
+            rect = image.get_rect()
+            rect.center = pos
+            self.screen.blit(image, rect)
+
+            if item.holds is not None:
+                self.draw_item(pos, item.holds)
+
         if isinstance(item, ProgressibleItem) and not item.finished:
             self.draw_progress_bar(pos, item.progressed_steps, item.steps_needed)
 
-- 
GitLab