From c509030bb67233bdf7d4c2b78c4e676c0af25694 Mon Sep 17 00:00:00 2001 From: fheinrich <fheinrich@techfak.uni-bielefeld.de> Date: Wed, 6 Dec 2023 11:51:19 +0100 Subject: [PATCH] Added different types of items. Added a cutting-board-counter which can process cuttable items. A player can hold the interact key for the cut process to progress. Tied to simulator frequency. --- overcooked_simulator/counters.py | 43 +++++++++++++++++++ overcooked_simulator/game_items.py | 38 +++++++++++++++- overcooked_simulator/layouts/basic.layout | 2 +- overcooked_simulator/main.py | 3 +- .../overcooked_environment.py | 16 ++++--- overcooked_simulator/player.py | 9 ---- 6 files changed, 93 insertions(+), 18 deletions(-) diff --git a/overcooked_simulator/counters.py b/overcooked_simulator/counters.py index c51e40e3..46dcda1e 100644 --- a/overcooked_simulator/counters.py +++ b/overcooked_simulator/counters.py @@ -1,5 +1,7 @@ import numpy as np +from overcooked_simulator.game_items import CuttableItem + class Counter: """Simple class for a counter at a specified position (center of counter). Can hold things on top.""" @@ -53,3 +55,44 @@ class Counter: def __repr__(self): return f"Counter(pos:{str(self.pos)},holds:{self.occupied_by})" + + +class CuttingBoard(Counter): + def __init__(self, pos): + self.progressing = False + super().__init__(pos) + + def progress(self): + """Called by environment step function for time progression""" + if self.progressing: + if isinstance(self.occupied_by, CuttableItem): + self.occupied_by.progress() + + def start_progress(self): + self.progressing = True + + def pause_progress(self): + self.progressing = False + + def drop_off(self, item): + if self.occupied_by is None: + self.occupied_by = item + + def can_drop_off(self, item): + return self.occupied_by is None + + def pick_up(self): + return_to_player = self.occupied_by + self.occupied_by = None + return return_to_player + + def interact_start(self): + print("START") + self.start_progress() + + def interact_stop(self): + print("STOP") + self.pause_progress() + + def __repr__(self): + return f"CuttingBoard({self.occupied_by})" diff --git a/overcooked_simulator/game_items.py b/overcooked_simulator/game_items.py index 8dfb402a..cd784132 100644 --- a/overcooked_simulator/game_items.py +++ b/overcooked_simulator/game_items.py @@ -1,6 +1,42 @@ class HoldableItem: + """Base class for game items which can be held by a player.""" + pass -class Tomato(HoldableItem): +class ProgressibleItem(HoldableItem): + """Class for items which need to be processed (cut, cooked, ...)""" + + def __init__(self, steps_needed): + self.progressed_steps = 0 + self.steps_needed = steps_needed + self.finished = False + super().__init__() + + def progress(self): + """Progresses the item process as long as it is not finished.""" + print("PROGRESSING ITEM") + if self.progressed_steps >= self.steps_needed: + self.finished = True + self.progressed_steps = 0 + if not self.finished: + self.progressed_steps += 1 + + def __repr__(self): + if self.finished: + return "CutTomato" + else: + return f"{self.__class__.__name__}({int(self.progressed_steps / self.steps_needed * 100)}%)" + + +class CuttableItem(ProgressibleItem): + """Class of item which can be processed by the cutting board.""" + pass + + +class Tomato(CuttableItem): + """Item class representing a tomato. Can be cut on the cutting board""" + + def __init__(self): + super().__init__(steps_needed=1500) diff --git a/overcooked_simulator/layouts/basic.layout b/overcooked_simulator/layouts/basic.layout index 82524fc6..beb5fc01 100644 --- a/overcooked_simulator/layouts/basic.layout +++ b/overcooked_simulator/layouts/basic.layout @@ -7,5 +7,5 @@ ECEEEEEEEEE ECEEEEEEEEE ECEEEEEEECE ECEEEEEEECE -ECCCCCCCCCE +ECCBBCCCCCE EEEEEEEEEEE diff --git a/overcooked_simulator/main.py b/overcooked_simulator/main.py index 393255aa..48b34e3c 100644 --- a/overcooked_simulator/main.py +++ b/overcooked_simulator/main.py @@ -8,7 +8,7 @@ from overcooked_simulator.simulation_runner import Simulator def main(): - simulator = Simulator(Path("overcooked_simulator/layouts/basic.layout"), 300) + simulator = Simulator(Path("overcooked_simulator/layouts/basic.layout"), 600) simulator.register_player(Player("p1", [100, 200])) simulator.register_player(Player("p2", [200, 100])) @@ -17,7 +17,6 @@ def main(): gui = PyGameGUI(simulator) simulator.start() - gui.start_pygame() simulator.stop() diff --git a/overcooked_simulator/overcooked_environment.py b/overcooked_simulator/overcooked_environment.py index 4b3d48e2..209485bf 100644 --- a/overcooked_simulator/overcooked_environment.py +++ b/overcooked_simulator/overcooked_environment.py @@ -7,7 +7,7 @@ if TYPE_CHECKING: from pathlib import Path import numpy as np from scipy.spatial import distance_matrix -from overcooked_simulator.counters import Counter +from overcooked_simulator.counters import Counter, CuttingBoard class Action: @@ -65,9 +65,12 @@ class Environment: if character == "C": counter = Counter(np.array([current_x, current_y])) counters.append(counter) - current_x += self.counter_side_length + elif character == "B": + counter = CuttingBoard(np.array([current_x, current_y])) + counters.append(counter) elif character == "E": - current_x += self.counter_side_length + pass + current_x += self.counter_side_length current_y += self.counter_side_length return counters @@ -80,7 +83,8 @@ class Environment: action: The action to be performed """ - # print("RECEIVED ACTION:", action) + # if action.act_type != "movement": + # print("RECEIVED ACTION:", action) assert action.player in self.players.keys(), "Unknown player." player = self.players[action.player] @@ -256,7 +260,9 @@ class Environment: """Performs a step of the environment. Affects time based events such as cooking or cutting things, orders and time limits. """ - pass + for counter in self.counters: + if isinstance(counter, CuttingBoard): + counter.progress() def get_state(self): """Get the current state of the game environment. The state here is accessible by the current python objects. diff --git a/overcooked_simulator/player.py b/overcooked_simulator/player.py index 4920f0dc..28f812bd 100644 --- a/overcooked_simulator/player.py +++ b/overcooked_simulator/player.py @@ -75,15 +75,6 @@ class Player: counter.drop_off(self.holding) self.holding = None - def interact(self, counter: Counter): - """Performs the interact-action with the counter. Handles logic of starting processes - like for e.g. cutting onions. TODO holding the button vs pressing once? - - Args: - counter: The counter to interact with. - """ - pass - 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. -- GitLab