Skip to content
Snippets Groups Projects
Commit 41aa2d13 authored by Florian Schröder's avatar Florian Schröder
Browse files

Merge branch '124-additional-state-keys-and-values' into 'dev'

Resolve "additional state keys and values"

Closes #124

See merge request scs/cocosy/overcooked-simulator!92
parents 500d043e 7eeff989
No related branches found
No related tags found
1 merge request!92Resolve "additional state keys and values"
Pipeline #49694 passed
......@@ -16,7 +16,7 @@
- Send full websocket url in player_info.
- ">90"% code coverage in tests
- i18n for the gui
- Controller hotplugging
- Controller hot-plugging
- Hook when returning items to dispensers
- Displaying image of served meals on game conclusion screen
- Pathfinding in random agent
......@@ -39,6 +39,7 @@
- Better drawing of orders, now in a pygame_gui UIImage
- Buttons for setting player controls in the GUI disappear depending on number of players
- Icon for serving window, now a star
- Additional state content is stored in own variable. Is no longer passed via a kwarg to the step function.
### Deprecated
......
......@@ -186,6 +186,8 @@ hook_callbacks:
- progress_finished
- content_ready
- dispenser_item_returned
- additional_state_update
- game_ended_step
callback_class: !!python/name:cooperative_cuisine.recording.FileRecorder ''
callback_class_kwargs:
......
......@@ -184,6 +184,8 @@ hook_callbacks:
- progress_finished
- content_ready
- dispenser_item_returned
- additional_state_update#
- game_ended_step
callback_class: !!python/name:cooperative_cuisine.recording.FileRecorder ''
callback_class_kwargs:
......
......@@ -52,6 +52,7 @@ from cooperative_cuisine.hooks import (
ITEM_INFO_CONFIG,
POST_STEP,
hooks_via_callback_class,
ADDITIONAL_STATE_UPDATE,
)
from cooperative_cuisine.items import (
ItemInfo,
......@@ -313,6 +314,10 @@ class Environment:
self.info_msgs_per_player: dict[str, list[InfoMsg]] = defaultdict(list)
"""Cache of info messages per player which should be showed in the visualization of each player."""
self.additional_state_content = {}
"""The environment will extend the content of each state with this dictionary. Adapt it with the setter
function."""
self.hook(
ENV_INITIALIZED,
environment_config=env_config,
......@@ -483,14 +488,11 @@ class Environment:
effect_manager.progress(passed_time=passed_time, now=self.env_time)
self.hook(POST_STEP, passed_time=passed_time)
def get_state(
self, player_id: str = None, additional_key_values: dict = None
) -> dict:
def get_state(self, player_id: str = None) -> dict:
"""Get the current state of the game environment. The state here is accessible by the current python objects.
Args:
player_id: The player for which to get the state.
additional_key_values: Additional dict that is added to the state
Returns:
The state of the game as a dict.
......@@ -529,26 +531,23 @@ class Environment:
for msg in self.info_msgs_per_player[player_id]
if msg["start_time"] < self.env_time < msg["end_time"]
],
**(additional_key_values if additional_key_values else {}),
**self.additional_state_content,
}
self.hook(STATE_DICT, state=state, player_id=player_id)
return state
raise ValueError(f"No valid {player_id=}")
def get_json_state(
self, player_id: str = None, additional_key_values: dict = None
) -> str:
def get_json_state(self, player_id: str = None) -> str:
"""Return the current state of the game formatted in json dict.
Args:
player_id: The player for which to get the state.
additional_key_values: Additional dict that is added to the state
Returns:
The state of the game formatted as a json-string
"""
state = self.get_state(player_id, additional_key_values)
state = self.get_state(player_id)
json_data = json.dumps(state)
self.hook(JSON_STATE, json_data=json_data, player_id=player_id)
# assert StateRepresentation.model_validate_json(json_data=json_data)
......@@ -586,3 +585,7 @@ class Environment:
"""Add a value to the current score and log it."""
self.score += score
log.debug(f"Score: {self.score} ({score}) - {info}")
def update_additional_state_content(self, **kwargs):
self.hook(ADDITIONAL_STATE_UPDATE, update=kwargs)
self.additional_state_content.update(kwargs)
......@@ -115,8 +115,6 @@ class EnvironmentData:
"""Time of when the environment was started."""
last_step_time: int | None = None
"""Time of the last performed step of the environment."""
all_players_ready: bool = False
"""Did all players send 'ready'."""
# add manager_id?
......@@ -192,6 +190,8 @@ class EnvironmentHandler:
graphs = env.recipe_validation.get_recipe_graphs()
kitchen_size = (env.kitchen_width, env.kitchen_height)
env.update_additional_state_content(all_players_ready=False)
res = CreateEnvResult(
env_id=env_id,
player_info=player_info,
......@@ -280,7 +280,9 @@ class EnvironmentHandler:
self.envs[env_id].start_time = start_time
self.envs[env_id].last_step_time = time.time_ns()
self.envs[env_id].environment.reset_env_time()
self.envs[env_id].all_players_ready = True
self.envs[env_id].environment.update_additional_state_content(
all_players_ready=True
)
def get_state(
self, player_hash: str
......@@ -301,7 +303,6 @@ class EnvironmentHandler:
env_data = self.envs[self.player_data[player_hash].env_id]
state = env_data.environment.get_json_state(
self.player_data[player_hash].player_id,
additional_key_values={"all_players_ready": env_data.all_players_ready},
)
return state
if player_hash not in self.player_data:
......
......@@ -511,6 +511,14 @@ Args:
counter (Counter): the last interacted counter.
"""
# -- extra --
ADDITIONAL_STATE_UPDATE = "additional_state_update"
"""Update of the additional content of the state.
Args:
update (dict[str, Any]): update of the additional state content.
"""
class Hooks:
"""Represents a collection of hooks and provides methods to register callbacks for hooks and invoke the callbacks when hooks are triggered.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment