From c61f906fbd753c243eb0e8bea9956337d119108f Mon Sep 17 00:00:00 2001
From: fheinrich <fheinrich@techfak.uni-bielefeld.de>
Date: Fri, 8 Mar 2024 14:39:39 +0100
Subject: [PATCH] Human readable game event record printing

---
 .../configs/environment_config.yaml           |   4 +-
 cooperative_cuisine/recording.py              | 202 +++++++++++++-----
 2 files changed, 156 insertions(+), 50 deletions(-)

diff --git a/cooperative_cuisine/configs/environment_config.yaml b/cooperative_cuisine/configs/environment_config.yaml
index 46517a09..eec7ad50 100644
--- a/cooperative_cuisine/configs/environment_config.yaml
+++ b/cooperative_cuisine/configs/environment_config.yaml
@@ -188,8 +188,8 @@ extra_setup_functions:
         - serve_not_ordered_meal
         - serve_without_plate
         - completed_order
-        #        - new_orders
-        #        - order_expired
+        - new_orders
+        - order_expired
         - action_on_not_reachable_counter
         - new_fire
         - fire_spreading
diff --git a/cooperative_cuisine/recording.py b/cooperative_cuisine/recording.py
index ba7a669c..24e6f3ca 100644
--- a/cooperative_cuisine/recording.py
+++ b/cooperative_cuisine/recording.py
@@ -45,6 +45,7 @@ import logging
 import os
 import traceback
 from pathlib import Path
+from string import Template
 
 from cooperative_cuisine.counters import Counter
 from cooperative_cuisine.environment import Environment
@@ -83,12 +84,35 @@ class FileRecorder(HookCallbackClass):
             if isinstance(item, (Counter, Item, Effect)):
                 kwargs[key] = item.to_dict()
             elif isinstance(item, Order):
-                kwargs[key] = str(item)
+                order_state = {
+                    "id": item.uuid,
+                    "category": "Order",
+                    "meal": item.meal.name,
+                    "start_time": item.start_time.isoformat(),
+                    "max_duration": item.max_duration.total_seconds(),
+                }
+                kwargs[key] = order_state
+
             elif isinstance(item, list):
-                kwargs[key] = [i.to_dict() for i in item]
-        if hook_ref == "new_orders":
-            new_orders = kwargs["new_orders"]
-            kwargs["new_orders"] = [str(order) for order in new_orders]
+                new_list = []
+                for i in item:
+                    if isinstance(i, Order):
+                        new_list.append(
+                            {
+                                "id": i.uuid,
+                                "category": "Order",
+                                "meal": i.meal.name,
+                                "start_time": i.start_time.isoformat(),
+                                "max_duration": i.max_duration.total_seconds(),
+                            }
+                        )
+                    else:
+                        new_list.append(i.to_dict())
+
+                kwargs[key] = new_list
+        # if hook_ref == "new_orders":
+        #     new_orders = kwargs["new_orders"]
+        #     kwargs["new_orders"] = [str(order) for order in new_orders]
         try:
             record = (
                 json.dumps(
@@ -111,6 +135,33 @@ class FileRecorder(HookCallbackClass):
 
 
 def print_recorded_events_human_readable(jsonl_path: Path):
+    def stringify_item(item):
+        if isinstance(item, float):
+            return str(item)
+        if isinstance(item, str):
+            return item
+        if isinstance(item, list) and len(item) == 1:
+            item = item[0]
+        if item:
+            content = None
+            if item and item["type"] in [
+                "Plate",
+                "Pot",
+                "Basket",
+                "Peel",
+                "Pan",
+            ]:
+                if item != "Plate" and item["content_ready"]:
+                    content_ready = stringify_item(item["content_ready"])
+                    return f"{item['type']}{f'({content_ready})'}"
+
+                content = [stringify_item(i) for i in item["content_list"]]
+                if not content:
+                    content = "None"
+            return f"{item['type']}{f'({content})' if content else ''}"
+        else:
+            return None
+
     seen_keys = []
     print()
     column_size = 20
@@ -118,41 +169,15 @@ def print_recorded_events_human_readable(jsonl_path: Path):
         for line in jsonl_file:
             record = json.loads(line)
 
-            def stringify_item(item):
-                if isinstance(item, str):
-                    return item
-                if isinstance(item, list) and len(item) == 1:
-                    item = item[0]
-                if item:
-                    content = None
-                    if item and item["type"] in [
-                        "Plate",
-                        "Pot",
-                        "Basket",
-                        "Peel",
-                        "Pan",
-                    ]:
-                        if item != "Plate" and item["content_ready"]:
-                            content_ready = stringify_item(item["content_ready"])
-                            return f"{item['type']}{f'({content_ready})'}"
-
-                        content = [stringify_item(i) for i in item["content_list"]]
-                        if not content:
-                            content = "None"
-                    return f"{item['type']}{f'({content})' if content else ''}"
-                else:
-                    return None
-
-            print(f"{record['hook_ref']}")
+            hook = record["hook_ref"]
+
             for dict_key in record.keys():
-                # print(dict_key, record[dict_key])
                 match dict_key:
                     case "hook_ref" | "env_time" | "on_hands":
                         pass
-
                     case "counter":
                         if not record[dict_key]:
-                            print(f"    {'Counter:'.ljust(column_size)}None")
+                            record[dict_key] = "None"
                         else:
                             occupied = record[dict_key]["occupied_by"]
                             if occupied:
@@ -160,26 +185,107 @@ def print_recorded_events_human_readable(jsonl_path: Path):
                                     occupied = [stringify_item(i) for i in occupied]
                                 else:
                                     occupied = stringify_item(occupied)
-                            print(
-                                f"    {'Counter:'.ljust(column_size)}{record[dict_key]['type']}({occupied})",
-                            )
-                    # case "return_this" | "item" | "equipment" | "content_ready" | "before" | "returned_item" | "result" | "meal" | "target" | "meal" | "meal_name" | "Occupied_by":
+                            record[dict_key] = f"{record[dict_key]['type']}({occupied})"
 
+                    case "order":
+                        order = f"Order({record[dict_key]['meal']})"
+                        record[dict_key] = order
+                    case "new_orders":
+                        orders = [f"Order({o['meal']})" for o in record[dict_key]]
+                        record[dict_key] = orders
                     case other:
-                        try:
-                            print(
-                                f"    {(str(dict_key).capitalize()+':').ljust(column_size)}{stringify_item(record[dict_key])}"
-                            )
-                        except Exception as e:
-                            print(
-                                f"    {(str(dict_key).capitalize()+':').ljust(column_size)}{record[dict_key]}"
-                            )
+                        record[dict_key] = stringify_item(record[dict_key])
 
-            print()
+            match hook:
+                case "post_dispenser_pick_up":
+                    n = Template(
+                        "Player $player picked up $return_this from the $counter."
+                    )
+                    print(n.substitute(**dict(record.items())))
+                case "post_counter_pick_up":
+                    n = Template("Player $player picked $return_this up from $counter.")
+                    print(n.substitute(**dict(record.items())))
+                case "post_counter_drop_off":
+                    n = Template("Player $player dropped $item off on $counter.")
+                    print(n.substitute(**dict(record.items())))
+                case "cutting_board_100":
+                    n = Template("Player $player_name finished chopping at $counter.")
+                    print(n.substitute(**dict(record.items())))
+                case "player_start_interaction":
+                    n = Template("Player $player started interacting with $counter.")
+                    print(n.substitute(**dict(record.items())))
+                case "player_end_interact":
+                    n = Template("Player $player stopped interacting with $counter.")
+                    print(n.substitute(**dict(record.items())))
+                case "post_serving":
+                    n = Template("Item $item was served at $counter.")
+                    print(n.substitute(**dict(record.items())))
+                # case "no_serving":
+                #     pass
+                case "dirty_plate_arrives":
+                    n = Template("A plate returned to $counter.")
+                    print(n.substitute(**dict(record.items())))
+                # case "trashcan_usage":
+                #     pass
+                # case "plate_cleaned":
+                #     pass
+                # case "added_plate_to_sink":
+                #     pass
+                # case "drop_on_sink_addon":
+                #     pass
+                # case "pick_up_from_sink_addon":
+                #     pass
+                # case "serve_not_ordered_meal":
+                #     pass
+                # case "serve_without_plate":
+                #     pass
+                case "completed_order":
+                    n = Template("Order $order was completed.")
+                    print(n.substitute(**dict(record.items())))
+                case "new_orders":
+                    n = Template("Orders $new_orders were ordered.")
+                    print(n.substitute(**dict(record.items())))
+                # case "order_expired":
+                #     pass
+                # case "action_on_not_reachable_counter":
+                #     pass
+                # case "new_fire":
+                #     pass
+                # case "fire_spreading":
+                #     pass
+                case "drop_off_on_cooking_equipment":
+                    n = Template(
+                        "Player $player put $item in/on $equipment at $counter."
+                    )
+                    print(n.substitute(**dict(record.items())))
+                # case "players_collide":
+                #     pass
+                case "post_plate_dispenser_pick_up":
+                    n = Template(
+                        "Player $player picked up $returned_item from $counter."
+                    )
+                    print(n.substitute(**dict(record.items())))
+                # case "post_plate_dispenser_drop_off":
+                #     pass
+                # case "on_item_transition":
+                #     pass
+                case "progress_started":
+                    n = Template("Item $item started progressing.")
+                    print(n.substitute(**dict(record.items())))
+                case "progress_finished":
+                    n = Template("Item $item finished its progress.")
+                    print(n.substitute(**dict(record.items())))
+                # case "content_ready":
+                #     pass
+                case other:
+                    print()
+                    print(hook)
+                    for key, item in record.items():
+                        print(f"  - {(key+':').ljust(column_size)}{item}")
 
 
 if __name__ == "__main__":
     jsonl_path: Path = Path(
-        "/Users/fheinrich/Library/Logs/cooperative_cuisine/1c3011b16bcc426ab1019ef73bd2c1c9/game_events.jsonl"
+        "/Users/fheinrich/Library/Logs/cooperative_cuisine/e8b0551442934324bd3204c46379ebe5/game_events.jsonl"
     )
     print_recorded_events_human_readable(jsonl_path)
-- 
GitLab