From 06c33962035b085b4721448aee5e09b15619b844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Schr=C3=B6der?= <fschroeder@techfak.uni-bielefeld.de> Date: Thu, 7 Dec 2023 15:28:30 +0100 Subject: [PATCH] changed pick_up method to return the item in the players hand. Plates are now stackable on the PlateReturn. occupied by is now a list in the plate return --- overcooked_simulator/counters.py | 52 +++++++++++-------- overcooked_simulator/game_items.py | 4 +- .../overcooked_environment.py | 36 +++++++++---- overcooked_simulator/player.py | 10 ++-- overcooked_simulator/pygame_gui/pygame_gui.py | 8 ++- 5 files changed, 68 insertions(+), 42 deletions(-) diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py index 49cbd6f0..8e0722de 100644 --- a/overcooked_simulator/counters.py +++ b/overcooked_simulator/counters.py @@ -30,7 +30,7 @@ class Counter: self.occupied_by = None return give_player - def can_drop_off(self, item: HoldableItem): + def can_drop_off(self, item: HoldableItem) -> bool: """Checks whether an item by the player can be dropped of. More relevant for example with ingredient dispensers, which should always be occupied and cannot take an item. @@ -42,7 +42,7 @@ class Counter: """ return self.occupied_by is None or self.occupied_by.can_combine(item) - def drop_off(self, item: HoldableItem): + def drop_off(self, item: HoldableItem) -> HoldableItem | None: """Takes the thing dropped of by the player. Args: @@ -55,6 +55,7 @@ class Counter: self.occupied_by = item elif self.occupied_by.can_combine(item): self.occupied_by.combine(item) + return None def interact_start(self): """Starts an interaction by the player. Nothing happens for the standard counter.""" @@ -100,14 +101,14 @@ class CuttingBoard(Counter): class ServingWindow(Counter): - def drop_off(self, item): - return 5 + def drop_off(self, item) -> HoldableItem | None: + return None def can_score(self, item): if isinstance(item, Plate) and isinstance(item.holds, ProgressibleItem): return item.holds.finished - def can_drop_off(self, item: HoldableItem): + def can_drop_off(self, item: HoldableItem) -> bool: return self.can_score(item) def pick_up(self): @@ -120,7 +121,7 @@ class ServingWindow(Counter): class PlateReturn(Counter): def __init__(self, pos): super().__init__(pos) - self.occupied_by = Plate() + self.occupied_by = [Plate()] def pick_up(self): """Gets called upon a player performing the pickup action. Gives back a plate (possibly with ingredient. @@ -128,20 +129,28 @@ class PlateReturn(Counter): Returns: A plate possibly with an ingredient on it. """ - give_player = self.occupied_by - self.occupied_by = Plate() + give_player = self.occupied_by.pop() + if not self.occupied_by: + self.occupied_by.append(Plate()) return give_player - def drop_off(self, item: HoldableItem): + def drop_off(self, item: HoldableItem) -> HoldableItem | None: """Takes the ingredient dropped of by the player. Args: item: The ingredient to be placed on the counter. """ - if item is Plate() and self.occupied_by is Plate(): - self.occupied_by = None - - def can_drop_off(self, item: HoldableItem): + if isinstance(item, Plate): + if self.occupied_by[-1].holds: + return item + self.occupied_by.append(item) + return None + if self.occupied_by[-1].can_combine(item): + self.occupied_by[-1].combine(item) + return None + return item + + def can_drop_off(self, item: HoldableItem) -> bool: """Checks whether an ingredient by the player can be dropped of. Args: @@ -152,8 +161,8 @@ class PlateReturn(Counter): """ # possibility to drop off empty plate on empty plate return return ( - isinstance(self.occupied_by, Plate) and isinstance(item, Plate) - ) or self.occupied_by.can_combine(item) + isinstance(self.occupied_by[-1], Plate) and isinstance(item, Plate) + ) or self.occupied_by[-1].can_combine(item) def __repr__(self): return "PlateReturn" @@ -166,10 +175,10 @@ class TomatoDispenser(Counter): def pick_up(self): return Tomato() - def drop_off(self, item: HoldableItem): - return 0 + def drop_off(self, item: HoldableItem) -> HoldableItem | None: + return None - def can_drop_off(self, item: HoldableItem): + def can_drop_off(self, item: HoldableItem) -> bool: return False def __repr__(self): @@ -180,12 +189,13 @@ class Trash(Counter): def pick_up(self): pass - def drop_off(self, item: HoldableItem): + def drop_off(self, item: HoldableItem) -> HoldableItem | None: if isinstance(item, Plate): item.holds = None - return -1 + return item + return None - def can_drop_off(self, item: HoldableItem): + def can_drop_off(self, item: HoldableItem) -> bool: return True def __repr__(self): diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py index 91286708..986692a6 100644 --- a/overcooked_simulator/game_items.py +++ b/overcooked_simulator/game_items.py @@ -9,9 +9,9 @@ class HoldableItem: class Plate(HoldableItem): - def __init__(self): + def __init__(self, holds: HoldableItem = None): self.clean = True - self.holds = None + self.holds = holds super().__init__() diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index 1150547e..8074de7f 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -13,20 +13,22 @@ from overcooked_simulator.counters import ( Counter, CuttingBoard, Trash, - ServingWindow, TomatoDispenser, + ServingWindow, PlateReturn, ) -SYMBOL_TO_CHARACTER_MAP = { - "C": Counter, - "B": CuttingBoard, - "X": Trash, - "W": ServingWindow, - "T": TomatoDispenser, - "P": PlateReturn, - "E": None, -} + +class GameScore: + def __init__(self): + self.score = 0 + + def increment_score(self, score: int): + self.score += score + print(self.score) + + def read_score(self): + return self.score class Action: @@ -57,6 +59,18 @@ class Environment: self.players: dict[str, Player] = {} self.counter_side_length: int = 40 self.layout_path: Path = layout_path + + self.game_score = GameScore() + self.SYMBOL_TO_CHARACTER_MAP = { + "C": Counter, + "B": CuttingBoard, + "X": Trash, + "W": lambda pos: ServingWindow(pos, self.game_score), + "T": TomatoDispenser, + "P": PlateReturn, + "E": None, + } + self.counters: list[Counter] = self.create_counters(self.layout_path) self.score: int = 0 self.world_width: int = 800 @@ -82,7 +96,7 @@ class Environment: for character in line: character = character.capitalize() pos = np.array([current_x, current_y]) - counter_class = SYMBOL_TO_CHARACTER_MAP[character] + counter_class = self.SYMBOL_TO_CHARACTER_MAP[character] if counter_class is not None: counter = counter_class(pos) counters.append(counter) diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py index 69c65e5c..ab028d71 100644 --- a/overcooked_simulator/player.py +++ b/overcooked_simulator/player.py @@ -3,8 +3,8 @@ from typing import Optional import numpy as np import numpy.typing as npt -from overcooked_simulator.counters import Counter, Trash -from overcooked_simulator.game_items import HoldableItem, Plate +from overcooked_simulator.counters import Counter +from overcooked_simulator.game_items import HoldableItem class Player: @@ -78,11 +78,7 @@ class Player: self.holding = counter.pick_up() elif counter.can_drop_off(self.holding): - if isinstance(counter, Trash) and isinstance(self.holding, Plate): - self.holding.holds = None - else: - counter.drop_off(self.holding) - self.holding = None + self.holding = counter.drop_off(self.holding) elif self.holding.can_combine(counter.occupied_by): returned_by_counter = counter.pick_up() diff --git a/overcooked_simulator/pygame_gui/pygame_gui.py b/overcooked_simulator/pygame_gui/pygame_gui.py index be8b4238..0d61d2e5 100644 --- a/overcooked_simulator/pygame_gui/pygame_gui.py +++ b/overcooked_simulator/pygame_gui/pygame_gui.py @@ -284,7 +284,13 @@ class PyGameGUI: pygame.draw.rect(self.screen, YELLOW, board_rect) if counter.occupied_by is not None: - self.draw_item(counter.pos, counter.occupied_by) + if isinstance(counter.occupied_by, list): + for i, o in enumerate(counter.occupied_by): + self.draw_item( + np.abs([counter.pos[0], counter.pos[1] - (i * 3)]), o + ) + else: + self.draw_item(counter.pos, counter.occupied_by) def draw_counters(self, state): """Visualizes the counters in the environment. -- GitLab