Skip to content
Snippets Groups Projects
Commit 378a7080 authored by Fabian Heinrich's avatar Fabian Heinrich
Browse files

Merge remote-tracking branch 'origin/main' into 99-sprites-update

parents cd92f008 2aca985b
No related branches found
No related tags found
1 merge request!68Resolve "Sprites update"
Pipeline #47596 passed
[report]
exclude_lines =
if TYPE_CHECKING:
if __name__ == .__main__.:
\ No newline at end of file
......@@ -3,13 +3,14 @@ pytest:
script:
- apt-get update -qy
- apt-get install -y python3-dev python3-pip graphviz graphviz-dev
- pip install pytest
- pip install .
- pytest --junitxml=report.xml
- pip install '.[test]'
- pytest --cov --cov-report term-missing --cov-report xml:./coverage.xml --junitxml=./test.xml --cov-config=.coveragerc
coverage: '/^TOTAL .+?(\d+%)$/'
artifacts:
when: always
reports:
junit: report.xml
coverage_report:
coverage_format: cobertura
path: coverage.xml
pages:
script:
......
<div align="center">
![Main Pipeline Report](https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator/badges/main/pipeline.svg?key_text=Main+Pipeline&key_width=82)
![Main Coverage Report](https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator/badges/main/coverage.svg?job=pytest&key_text=Main+Test+Coverage&key_width=114)
![Dev Pipeline Report](https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator/badges/dev/pipeline.svg?key_text=Dev+Pipeline&key_width=80)
![Dev Coverage Report](https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator/badges/dev/coverage.svg?job=pytest&key_text=Dev+Test+Coverage&key_width=112)
</div>
# Cooperative Cuisine Environment
[Documentation](https://scs.pages.ub.uni-bielefeld.de/cocosy/overcooked-simulator)
The overcooked-like cooperative cuisine environment for real-time human cooperative interactions and artificial agents.
**The name ist still work in progress and we will probably change it.**
<div align="center">
<img src="cooperative_cuisine/pygame_2d_vis/images/cooperative_cuisine.png" width="800">
</div>
## Installation
......
#QU#FO#TNLB#
#__________M
@__________M
|__________K
$__________I
#__A_____A_D
......
cooperative_cuisine/pygame_2d_vis/images/cooperative_cuisine.png

139 KiB

......@@ -30,9 +30,7 @@ requirements = [
"pydot>=2.0.0",
]
test_requirements = [
"pytest>=3",
]
test_requirements = ["pytest>=3", "pytest-cov>=4.1"]
setup(
author="Annika Österdiekhoff, Dominik Battefeld, Fabian Heinrich, Florian Schröder",
......@@ -58,7 +56,6 @@ setup(
name="cooperative_cuisine",
packages=find_packages(include=["cooperative_cuisine", "cooperative_cuisine.*"]),
test_suite="tests",
tests_require=test_requirements,
url="https://gitlab.ub.uni-bielefeld.de/scs/cocosy/overcooked-simulator",
version="0.1.0",
zip_safe=False,
......@@ -68,6 +65,7 @@ setup(
"stable-baselines3[extra]>=2.2.1",
"opencv-python>=4.9",
"wandb>=0.16.3",
]
],
"test": test_requirements,
},
)
import pytest
from cooperative_cuisine.game_items import ItemInfo, CookingEquipment, Item, ItemType
def test_can_combine_single_other_item():
"""Test the 'can_combine' method with single other item"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
other_item = Item("Onion", ItemInfo(type=ItemType.Ingredient, name="Onion"))
assert cooking_equipment.can_combine(other_item) == False
def test_can_combine_list_of_other_items():
"""Test the 'can_combine' method with list of other items"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
other_item = CookingEquipment(
name="Pan",
transitions={},
item_info=ItemInfo(type=ItemType.Equipment, name="Pan"),
)
assert cooking_equipment.can_combine(other_item) == False
def test_can_combine_without_other_item():
"""Test the 'can_combine' method without other item"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
assert cooking_equipment.can_combine(None) == False
def test_combine():
"""Test the 'combine' method"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
other_item = Item("Onion", ItemInfo(type=ItemType.Ingredient, name="Onion"))
assert cooking_equipment.combine(other_item) is None
def test_progress():
"""Test the 'progress' method"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
result = Item(name="TestResult", item_info=None)
cooking_equipment.active_transition = {
"seconds": 5.0,
"result": result,
}
from datetime import datetime, timedelta
cooking_equipment.progress(passed_time=timedelta(seconds=5.0), now=datetime.now())
assert cooking_equipment.content_list == [result]
def test_reset_content():
"""Test the 'reset_content' method"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
cooking_equipment.content_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
cooking_equipment.reset_content()
assert cooking_equipment.content_list == []
def test_release():
"""Test the 'release' method"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
cooking_equipment.content_list = ["Content1", "Content2"]
assert cooking_equipment.release() == ["Content1", "Content2"]
assert cooking_equipment.content_list == []
def test_extra_repr_without_content():
"""Test the 'extra_repr' method without content"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
assert cooking_equipment.extra_repr == "[], None"
def test_extra_repr_with_content():
"""Test the 'extra_repr' method with content"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
item_1 = Item(
name="Tomato", item_info=ItemInfo(type=ItemType.Ingredient, name="Tomato")
)
item_2 = Item(
name="Potato", item_info=ItemInfo(type=ItemType.Ingredient, name="Potato")
)
cooking_equipment.content_list.extend([item_1, item_2])
assert cooking_equipment.extra_repr == "[Tomato(), Potato()], None"
def test_get_potential_meal_without_content():
"""Test the 'get_potential_meal' method without content"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
assert cooking_equipment.get_potential_meal() is None
def test_get_potential_meal_with_content():
"""Test the 'get_potential_meal' method with content"""
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
cooking_equipment = CookingEquipment(
transitions={}, name="Pot", item_info=item_info
)
item_1 = Item(
name="Tomato", item_info=ItemInfo(type=ItemType.Ingredient, name="Tomato")
)
cooking_equipment.content_list.append(item_1)
assert cooking_equipment.get_potential_meal() == item_1
item_2 = Item(
name="TomatoSoup", item_info=ItemInfo(type=ItemType.Meal, name="TomatoSoup")
)
cooking_equipment.content_ready = item_2
assert cooking_equipment.get_potential_meal() == item_2
@pytest.fixture
def cooking_equipment():
item_info = ItemInfo(type=ItemType.Meal, name="Soup", seconds=5.0)
return CookingEquipment(transitions={}, name="Pot", item_info=item_info)
def test_reset(cooking_equipment):
"""Test the 'reset' method"""
cooking_equipment.active_transition = {"1": 2}
cooking_equipment.progress_percentage = 1.0
cooking_equipment.progress_equipment = "Here"
cooking_equipment.reset()
assert cooking_equipment.progress_percentage == 0.0
assert cooking_equipment.active_transition is None
assert cooking_equipment.progress_equipment is None
# TODO full transition test with combine, progress etc.
import numpy as np
from cooperative_cuisine.counters import ServingWindow, Dispenser
from cooperative_cuisine.game_items import Item, Plate, ItemInfo, ItemType
from cooperative_cuisine.hooks import Hooks
from cooperative_cuisine.utils import create_init_env_time
def test_serving_window():
class DummyOrderManager:
def serve_meal(self, item, env_time, player) -> bool:
return (isinstance(item, str) and item == "Test123") or item.content_list[
0
].name == "TestMeal"
class DummyPlateDispenser:
plate_received = False
def update_plate_out_of_kitchen(self, env_time):
self.plate_received = True
plate_dispenser = DummyPlateDispenser()
serving_window = ServingWindow(
order_manager=DummyOrderManager(),
meals={"TestMeal", "TestMeal2"},
env_time_func=create_init_env_time,
plate_dispenser=plate_dispenser,
pos=np.array([1.0, 1.0]),
hook=Hooks(None),
)
serving_window.drop_off(item="Test123")
assert (
plate_dispenser.plate_received
), "ServingWindow needs to update plate out of kitchen for ordered meal."
plate_dispenser.plate_received = False
plate = Plate(transitions={}, clean=True, item_info=None)
plate.content_list = [Item(name="TestMeal", item_info=None)]
assert serving_window.can_drop_off(
item=plate
), "ServingWindow could drop off a known meal."
assert (
serving_window.drop_off(item=plate) is None
), "ServingWindow drop_off should return None for a served meal."
assert (
plate_dispenser.plate_received
), "ServingWindow needs to update plate out of kitchen for ordered meal."
plate_dispenser.plate_received = False
plate.content_list = [Item(name="TestMeal2", item_info=None)]
assert serving_window.can_drop_off(
item=plate
), "ServingWindow could drop off a known meal."
assert (
serving_window.drop_off(item=plate) == plate
), "ServingWindow should return the item for not ordered meals."
assert (
serving_window.pick_up() is None
), "Player should not be able to pick something from the ServingWindow."
def test_dispenser():
dispenser = Dispenser(
dispensing=ItemInfo(
type=ItemType.Ingredient,
name="MyIngredient",
seconds=0,
needs=["MySecondIngredient"],
equipment=None,
),
pos=np.array([1.0, 1.0]),
hook=Hooks(None),
undo_dispenser_pickup=False,
)
assert (
dispenser.occupied_by.name == "MyIngredient"
), "Initialized dispenser should be occupied by dispensing item"
assert (
dispenser.pick_up().name == "MyIngredient"
), "Picked up item should be the dispensing item"
assert (
dispenser.occupied_by is not None
), "After pickup a new occupied by should be generated"
assert (
dispenser.occupied_by.name == "MyIngredient"
), "After pick up a new occupied by item should be generated"
assert not dispenser.can_drop_off(
dispenser.pick_up()
), "Config undo_dispenser_pickup==False should stop the player to drop off picked up items"
dispenser.undo_dispenser_pickup = True
assert dispenser.can_drop_off(
dispenser.pick_up()
), "Config undo_dispenser_pickup==True should allow the player to drop off picked up items"
assert (
dispenser.drop_off(dispenser.pick_up()) is None
), "Config undo_dispenser_pickup==True should allow the player to drop off picked up items"
# check combine?
import pytest
from cooperative_cuisine.game_items import ItemInfo, Item, ItemType
@pytest.fixture
def items():
item1_info = ItemInfo(type=ItemType.Ingredient, name="Tomato")
item1 = Item("Tomato", item1_info)
item2_info = ItemInfo(type=ItemType.Ingredient, name="Onion")
item2 = Item("Onion", item2_info)
item1_duplicate = Item("Tomato", item1_info)
return item1, item1_info, item1_duplicate, item2, item2_info
def test_init(items):
item1, item1_info, _, _, _ = items
assert item1.name == "Tomato"
assert item1.item_info == item1_info
assert item1.progress_equipment is None
assert item1.progress_percentage == 0.0
def test_repr(items):
item1, _, _, _, _ = items
assert str(item1) == "Tomato()"
def test_eq(items):
item1, _, item1_duplicate, item2, _ = items
assert item1 == item1_duplicate
assert item1 != item2
def test_can_combine(items):
item1, _, _, item2, _ = items
assert not item1.can_combine(item2)
def test_combine(items):
item1, _, _, item2, _ = items
assert item1.combine(item2) is None
def test_progress(items):
item1, _, _, _, _ = items
item1.progress_equipment = "Oven"
item1.progress("Oven", 0.2)
assert item1.progress_percentage == 0.2
item1.progress("Oven", 0.1)
assert item1.progress_percentage == pytest.approx(0.3)
item1.progress("NotOven", 0.2)
assert item1.progress_percentage == pytest.approx(0.3)
assert item1.progress_equipment == "Oven"
def test_reset(items):
item1, _, _, _, _ = items
item1.progress_equipment = "Oven"
item1.progress("Oven", 0.2)
item1.reset()
assert item1.progress_equipment is None
assert item1.progress_percentage == 0.0
......@@ -12,7 +12,17 @@ from cooperative_cuisine.environment import (
InterActionData,
)
from cooperative_cuisine.game_items import Item, ItemInfo, ItemType
from cooperative_cuisine.game_server import PlayerRequestType
from cooperative_cuisine.hooks import Hooks
from cooperative_cuisine.server_results import (
PlayerInfo,
CreateEnvResult,
PlayerRequestResult,
)
from cooperative_cuisine.state_representation import (
StateRepresentation,
create_json_schema,
)
from cooperative_cuisine.utils import create_init_env_time
layouts_folder = ROOT_DIR / "configs" / "layouts"
......@@ -118,6 +128,10 @@ def test_player_movement_speed(env_config, layout_empty_config, item_info):
np.linalg.norm(expected - env.players[player_name].pos), 0
), "Performed movement do not move the player as expected."
assert StateRepresentation.model_validate_json(
json_data=env.get_json_state(player_id="1")
), "json state does not match expected StateRepresentation."
def test_player_reach(env_config, layout_empty_config, item_info):
env = Environment(env_config, layout_empty_config, item_info, as_files=False)
......@@ -281,3 +295,18 @@ def test_time_limit():
env.step(passed_time_2)
assert env.game_ended, "Game has ended now."
def test_json_schema():
assert isinstance(create_json_schema(), dict)
def test_server_result_definition():
plater_info = PlayerInfo(client_id="123", player_hash="234567890", player_id="0")
CreateEnvResult(env_id="123344", player_info={"0": plater_info}, recipe_graphs=[])
PlayerRequestResult(
request_type=PlayerRequestType.READY,
status=200,
msg="123",
player_hash="1234324",
)
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