From c9ecf4347367a5b4cbbd099055af2119c0f44515 Mon Sep 17 00:00:00 2001
From: fheinrich <fheinrich@techfak.uni-bielefeld.de>
Date: Wed, 13 Mar 2024 10:38:05 +0100
Subject: [PATCH] Display cook and meal images when showing completed meals

- added number of players to level info
- added draw cook method to vis
- Draw cook and meal on sufaces and show them on postgame screen instead of text
---
 cooperative_cuisine/pygame_2d_vis/drawing.py | 34 ++++---
 cooperative_cuisine/pygame_2d_vis/gui.py     | 96 +++++++++++++++-----
 cooperative_cuisine/study_server.py          |  4 +
 3 files changed, 101 insertions(+), 33 deletions(-)

diff --git a/cooperative_cuisine/pygame_2d_vis/drawing.py b/cooperative_cuisine/pygame_2d_vis/drawing.py
index 0c67eaf1..3f273ff3 100644
--- a/cooperative_cuisine/pygame_2d_vis/drawing.py
+++ b/cooperative_cuisine/pygame_2d_vis/drawing.py
@@ -14,7 +14,7 @@ from scipy.spatial import KDTree
 
 from cooperative_cuisine import ROOT_DIR
 from cooperative_cuisine.environment import Environment
-from cooperative_cuisine.pygame_2d_vis.game_colors import colors
+from cooperative_cuisine.pygame_2d_vis.game_colors import colors, RGB
 from cooperative_cuisine.state_representation import (
     PlayerState,
     CookingEquipmentState,
@@ -308,6 +308,26 @@ class Visualizer:
 
         screen.blit(image, rect)
 
+    def draw_cook(
+        self,
+        screen: pygame.Surface,
+        grid_size: float,
+        pos: npt.NDArray[float] | list[float],
+        color: RGB,
+        facing: npt.NDArray[float] | list[float],
+    ):
+        pygame.draw.circle(
+            screen,
+            color,
+            pos - facing * grid_size * 0.25,
+            grid_size * 0.2,
+        )
+
+        img_path = self.config["Cook"]["parts"][0]["path"]
+        angle = calc_angle(facing.tolist(), [0, 1])
+        size = self.config["Cook"]["parts"][0]["size"] * grid_size
+        self.draw_image(screen, img_path, size, pos, angle)
+
     def draw_players(
         self,
         screen: pygame.Surface,
@@ -330,18 +350,10 @@ class Visualizer:
             facing = np.array(player_dict["facing_direction"], dtype=float)
 
             if USE_PLAYER_COOK_SPRITES:
-                pygame.draw.circle(
-                    screen,
-                    colors[self.player_colors[p_idx]],
-                    pos - facing * grid_size * 0.25,
-                    grid_size * 0.2,
+                self.draw_cook(
+                    screen, grid_size, pos, colors[self.player_colors[p_idx]], facing
                 )
 
-                img_path = self.config["Cook"]["parts"][0]["path"]
-                angle = calc_angle(facing.tolist(), [0, 1])
-                size = self.config["Cook"]["parts"][0]["size"] * grid_size
-                self.draw_image(screen, img_path, size, pos, angle)
-
             else:
                 player_radius = 0.4
                 size = player_radius * grid_size
diff --git a/cooperative_cuisine/pygame_2d_vis/gui.py b/cooperative_cuisine/pygame_2d_vis/gui.py
index ccc4dd10..5cb16eef 100644
--- a/cooperative_cuisine/pygame_2d_vis/gui.py
+++ b/cooperative_cuisine/pygame_2d_vis/gui.py
@@ -1116,8 +1116,8 @@ class PyGameGUI:
 
         served_meals = state["served_meals"]
 
-        row_height = self.window_height * 0.04
-        container_width = self.scroll_width_completed_meals * 0.9
+        row_height = self.window_height * 0.07
+        container_width = self.scroll_width_completed_meals
         container_height = len(served_meals) * row_height
 
         main_container = pygame_gui.elements.UIPanel(
@@ -1143,34 +1143,89 @@ class PyGameGUI:
                     "top_target": last_completed_meals[idx - 1],
                 }
 
-            container = pygame_gui.elements.UIPanel(
-                relative_rect=pygame.Rect(
-                    (0, 0),
-                    (
-                        container_width,
-                        row_height,
-                    ),
+            rect = pygame.Rect(
+                (0, 0),
+                (
+                    container_width / 2,
+                    row_height,
                 ),
+            )
+            container = pygame_gui.elements.UIPanel(
+                relative_rect=rect,
                 object_id="#graph_container",
                 manager=self.manager,
                 container=main_container,
                 anchors=anchors,
             )
 
-            meal = re.sub(r"(?<!^)(?=[A-Z])", " ", meal)
-            meal = meal.replace("(", "").replace(")", "")
-            text = f"Player {player} served a {meal}."
+            text = ":"
+            rect = pygame.Rect(
+                (0, 0),
+                (container_width / 10, row_height),
+            )
+            rect.left = 0
             meal_label = pygame_gui.elements.UILabel(
                 text=text,
-                relative_rect=pygame.Rect(
-                    (0, 0),
-                    (container_width, row_height),
-                ),
+                relative_rect=rect,
                 manager=self.manager,
                 container=container,
-                object_id="#recipe",
+                object_id="#served_meal",
                 anchors={"center": "center"},
             )
+
+            cook_surface = pygame.Surface(
+                (row_height, row_height), flags=pygame.SRCALPHA
+            )
+            player_idx = int(player)
+            player_color = colors[self.vis.player_colors[player_idx]]
+            self.vis.draw_cook(
+                screen=cook_surface,
+                grid_size=row_height,
+                pos=np.array([row_height / 2, row_height / 2]),
+                color=player_color,
+                facing=np.array([0, 1]),
+            )
+            rect = cook_surface.get_rect()
+            rect.right = 0
+            cook_image = pygame_gui.elements.UIImage(
+                relative_rect=rect,
+                image_surface=cook_surface,
+                manager=self.manager,
+                container=container,
+                anchors={
+                    "centery": "centery",
+                    "right": "right",
+                    "right_target": meal_label,
+                },
+            )
+
+            meal_surface = pygame.Surface(
+                (row_height, row_height), flags=pygame.SRCALPHA
+            )
+            self.vis.draw_item(
+                pos=np.array([row_height / 2, row_height / 2]),
+                item={"type": "Plate"},
+                plate=True,
+                screen=meal_surface,
+                grid_size=row_height,
+            )
+            self.vis.draw_item(
+                pos=np.array([row_height / 2, row_height / 2]),
+                item={"type": meal},
+                plate=True,
+                screen=meal_surface,
+                grid_size=row_height,
+            )
+            rect = meal_surface.get_rect()
+            # rect.left = 0
+            meal_image = pygame_gui.elements.UIImage(
+                relative_rect=rect,
+                image_surface=meal_surface,
+                manager=self.manager,
+                container=container,
+                anchors={"centery": "centery", "left_target": meal_label},
+            )
+
             last_completed_meals.append(container)
 
         self.scroll_space_completed_meals.set_scrollable_area_dimensions(
@@ -1482,10 +1537,7 @@ class PyGameGUI:
             else:
                 log.warning("COULD NOT GET GAME CONNECTION")
                 self.menu_state = MenuStates.Start
-
-            self.number_players = (
-                self.number_humans_to_be_added + self.number_bots_to_be_added
-            )
+                self.number_players = -1
 
             if self.split_players:
                 assert (
@@ -1564,7 +1616,7 @@ class PyGameGUI:
 
         state = self.request_state()
 
-        self.vis.create_player_colors(len(state["players"]))
+        self.vis.create_player_colors(self.level_info["number_players"])
 
         self.kitchen_width = state["kitchen"]["width"]
         self.kitchen_height = state["kitchen"]["height"]
diff --git a/cooperative_cuisine/study_server.py b/cooperative_cuisine/study_server.py
index 501cfa4e..f26963fa 100644
--- a/cooperative_cuisine/study_server.py
+++ b/cooperative_cuisine/study_server.py
@@ -79,6 +79,8 @@ class LevelInfo(BaseModel):
     """If the level is the last in the study."""
     recipe_graphs: list[dict]
     """Graph representations for the recipes in this level."""
+    number_players: int
+    """Number of players in this level."""
 
 
 class StudyConfig(BaseModel):
@@ -305,6 +307,7 @@ class Study:
                 name=current_level["name"],
                 last_level=self.last_level,
                 recipe_graphs=self.current_running_env["recipe_graphs"],
+                number_players=len(self.current_running_env["player_info"]),
             )
             return player_info, level_info
         else:
@@ -474,6 +477,7 @@ class StudyManager:
                 name="Tutorial",
                 last_level=False,
                 recipe_graphs=tutorial_env["recipe_graphs"],
+                number_players=1,
             )
             player_info = tutorial_env["player_info"]
             return player_info, level_info
-- 
GitLab