diff --git a/assets/baked_croissant.png b/assets/baked_croissant.png new file mode 100644 index 000000000..53d6c6048 Binary files /dev/null and b/assets/baked_croissant.png differ diff --git a/assets/batter_station.png b/assets/batter_station.png new file mode 100644 index 000000000..4513f3362 Binary files /dev/null and b/assets/batter_station.png differ diff --git a/assets/battered_shrimp.png b/assets/battered_shrimp.png new file mode 100644 index 000000000..f0e2fba19 Binary files /dev/null and b/assets/battered_shrimp.png differ diff --git a/assets/bun.png b/assets/bun.png new file mode 100644 index 000000000..bda54cee6 Binary files /dev/null and b/assets/bun.png differ diff --git a/assets/croissant.png b/assets/croissant.png new file mode 100644 index 000000000..1f94951d6 Binary files /dev/null and b/assets/croissant.png differ diff --git a/assets/dough.png b/assets/dough.png new file mode 100644 index 000000000..f3fba02d4 Binary files /dev/null and b/assets/dough.png differ diff --git a/assets/fried_shrimp.png b/assets/fried_shrimp.png new file mode 100644 index 000000000..3e8615291 Binary files /dev/null and b/assets/fried_shrimp.png differ diff --git a/assets/grill.png b/assets/grill.png new file mode 100644 index 000000000..b0eed152e Binary files /dev/null and b/assets/grill.png differ diff --git a/assets/grilledhotdog.png b/assets/grilledhotdog.png new file mode 100644 index 000000000..5e90ea9e8 Binary files /dev/null and b/assets/grilledhotdog.png differ diff --git a/assets/grilledsalmon.png b/assets/grilledsalmon.png new file mode 100644 index 000000000..93affb257 Binary files /dev/null and b/assets/grilledsalmon.png differ diff --git a/assets/grilledsaltedsalmon.png b/assets/grilledsaltedsalmon.png new file mode 100644 index 000000000..e11a57420 Binary files /dev/null and b/assets/grilledsaltedsalmon.png differ diff --git a/assets/hotdog.png b/assets/hotdog.png new file mode 100644 index 000000000..844f80697 Binary files /dev/null and b/assets/hotdog.png differ diff --git a/assets/ketchup_hotdog.png b/assets/ketchup_hotdog.png new file mode 100644 index 000000000..4f9d1977a Binary files /dev/null and b/assets/ketchup_hotdog.png differ diff --git a/assets/ketchup_mustard_hotdog.png b/assets/ketchup_mustard_hotdog.png new file mode 100644 index 000000000..433a6cd36 Binary files /dev/null and b/assets/ketchup_mustard_hotdog.png differ diff --git a/assets/ketchupbottle.png b/assets/ketchupbottle.png new file mode 100644 index 000000000..6978dd14c Binary files /dev/null and b/assets/ketchupbottle.png differ diff --git a/assets/mustard_hotdog.png b/assets/mustard_hotdog.png new file mode 100644 index 000000000..2485107ba Binary files /dev/null and b/assets/mustard_hotdog.png differ diff --git a/assets/mustardbottle.png b/assets/mustardbottle.png new file mode 100644 index 000000000..6874beaf9 Binary files /dev/null and b/assets/mustardbottle.png differ diff --git a/assets/oven.png b/assets/oven.png new file mode 100644 index 000000000..8223bf2d2 Binary files /dev/null and b/assets/oven.png differ diff --git a/assets/oven_on.png b/assets/oven_on.png new file mode 100644 index 000000000..a80993fde Binary files /dev/null and b/assets/oven_on.png differ diff --git a/assets/roastedturkey.png b/assets/roastedturkey.png new file mode 100644 index 000000000..3f24b5107 Binary files /dev/null and b/assets/roastedturkey.png differ diff --git a/assets/rollingpin.png b/assets/rollingpin.png new file mode 100644 index 000000000..97dbf8b70 Binary files /dev/null and b/assets/rollingpin.png differ diff --git a/assets/salmon.png b/assets/salmon.png new file mode 100644 index 000000000..d95bd8aee Binary files /dev/null and b/assets/salmon.png differ diff --git a/assets/salt.png b/assets/salt.png new file mode 100644 index 000000000..749f73542 Binary files /dev/null and b/assets/salt.png differ diff --git a/assets/shrimp.png b/assets/shrimp.png new file mode 100644 index 000000000..fba4d9e93 Binary files /dev/null and b/assets/shrimp.png differ diff --git a/assets/tileset/tileset_counter/tileset_counter.png b/assets/tileset/tileset_counter/tileset_counter.png index e9480d69b..52fdd065c 100644 Binary files a/assets/tileset/tileset_counter/tileset_counter.png and b/assets/tileset/tileset_counter/tileset_counter.png differ diff --git a/assets/tileset/tileset_table/tileset_table.png b/assets/tileset/tileset_table/tileset_table.png index 3e1c71207..f36d09b07 100644 Binary files a/assets/tileset/tileset_table/tileset_table.png and b/assets/tileset/tileset_table/tileset_table.png differ diff --git a/assets/toastedbun.png b/assets/toastedbun.png new file mode 100644 index 000000000..1b2f18ea7 Binary files /dev/null and b/assets/toastedbun.png differ diff --git a/assets/triangle.png b/assets/triangle.png new file mode 100644 index 000000000..42982e6fe Binary files /dev/null and b/assets/triangle.png differ diff --git a/assets/turkey.png b/assets/turkey.png new file mode 100644 index 000000000..c58687a42 Binary files /dev/null and b/assets/turkey.png differ diff --git a/backend/state.py b/backend/state.py index 421aed8b9..f3ea35244 100644 --- a/backend/state.py +++ b/backend/state.py @@ -438,6 +438,5 @@ def step(self, actions, clock): if self.movement.mode == Mode.TRAVERSE: self.current_player = self.next_player() - return self, False \ No newline at end of file diff --git a/domain/input.json b/domain/input.json index e6c384e6b..5af11a8cd 100644 --- a/domain/input.json +++ b/domain/input.json @@ -35,6 +35,20 @@ "click_on": "s1" } }, + { + "name": "pick-up-condiment", + "input_instructions": { + "button": "left", + "click_on": "s1" + } + }, + { + "name": "place-condiment", + "input_instructions": { + "button": "left", + "click_on": "s1" + } + }, { "name": "stack", "input_instructions": { @@ -51,6 +65,27 @@ } ], "keyboard_actions": [ + { + "name": "put-in-oven", + "input_instructions": { + "key": "p", + "at": "s1" + } + }, + { + "name": "take-out-item", + "input_instructions": { + "key": "p", + "at": "s1" + } + }, + { + "name": "batter", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, { "name": "cook", "input_instructions": { @@ -58,6 +93,41 @@ "at": "s1" } }, + { + "name": "cook-on-oven", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "grill", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "toast", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "roast", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "bake", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, { "name": "cut", "input_instructions": { @@ -86,6 +156,13 @@ "at": "s1" } }, + { + "name": "boil-water-on-oven", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, { "name": "add-to", "input_instructions": { @@ -106,6 +183,41 @@ "key": "space", "at": null } + }, + { + "name": "add-ketchup", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "add-mustard", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "add-salt", + "input_instructions": { + "key": "e", + "at": "s1" + } + }, + { + "name": "roll-triangle", + "input_instructions": { + "key": "t", + "at": "s1" + } + }, + { + "name": "shape", + "input_instructions": { + "key": "m", + "at": "s1" + } } ] } \ No newline at end of file diff --git a/domain/robotouille.json b/domain/robotouille.json index fa5687a32..34e9e233d 100644 --- a/domain/robotouille.json +++ b/domain/robotouille.json @@ -4,7 +4,7 @@ "input_json": "domain/input.json", - "object_types": ["station", "item", "player", "container", "meal"], + "object_types": ["station", "item", "player", "container", "meal", "condiment"], "predicate_defs": [ { @@ -15,6 +15,10 @@ "name": "isstove", "param_types": ["station"] }, + { + "name": "isoven", + "param_types": ["station"] + }, { "name": "isboard", "param_types": ["station"] @@ -27,6 +31,18 @@ "name": "issink", "param_types": ["station"] }, + { + "name": "isgrill", + "param_types": ["station"] + }, + { + "name": "isbatter_station", + "param_types": ["station"] + }, + { + "name": "oven_on", + "param_types": ["station"] + }, { "name": "isrobot", "param_types": ["player"] @@ -71,6 +87,22 @@ "name": "ispotato", "param_types": ["item"] }, + { + "name": "iscroissant", + "param_types": ["item"] + }, + { + "name": "isrollingpin", + "param_types": ["item"] + }, + { + "name": "istriangle", + "param_types": ["item"] + }, + { + "name": "iscircle", + "param_types": ["item"] + }, { "name": "isfryable", "param_types": ["item"] @@ -79,6 +111,10 @@ "name": "isfryableifcut", "param_types": ["item"] }, + { + "name": "isfryableifbattered", + "param_types": ["item"] + }, { "name": "isfried", "param_types": ["item"] @@ -99,6 +135,110 @@ "name": "iscut", "param_types": ["item"] }, + { + "name": "ishotdog", + "param_types": ["item"] + }, + { + "name": "isbun", + "param_types": ["item"] + }, + { + "name": "issalmon", + "param_types": ["item"] + }, + { + "name": "isturkey", + "param_types": ["item"] + }, + { + "name": "isshrimp", + "param_types": ["item"] + }, + { + "name": "isgrillable", + "param_types": ["item"] + }, + { + "name": "istoastable", + "param_types": ["item"] + }, + { + "name": "isroastable", + "param_types": ["item"] + }, + { + "name": "isbatterable", + "param_types": ["item"] + }, + { + "name": "isbakeable", + "param_types": ["item"] + }, + { + "name": "isrollable", + "param_types": ["item"] + }, + { + "name": "isshapeable", + "param_types": ["item"] + }, + { + "name": "isshapeableiftriangle", + "param_types": ["item"] + }, + { + "name": "isgrilled", + "param_types": ["item"] + }, + { + "name": "istoasted", + "param_types": ["item"] + }, + { + "name": "isroasted", + "param_types": ["item"] + }, + { + "name": "isbattered", + "param_types": ["item"] + }, + { + "name": "isbaked", + "param_types": ["item"] + }, + { + "name": "isrolled", + "param_types": ["item"] + }, + { + "name": "isshaped", + "param_types": ["item"] + }, + { + "name": "has_salt", + "param_types": ["item"] + }, + { + "name": "has_ketchup", + "param_types": ["item"] + }, + { + "name": "has_mustard", + "param_types": ["item"] + }, + { + "name": "has_ketchup_mustard", + "param_types": ["item"] + }, + { + "name": "can_add_salt", + "param_types": ["item"] + }, + { + "name": "saltifgrilled", + "param_types": ["item"] + }, { "name": "ispot", "param_types": ["container"] @@ -135,10 +275,26 @@ "name": "container_empty", "param_types": ["container"] }, + { + "name": "isketchup", + "param_types": ["condiment"] + }, + { + "name": "ismustard", + "param_types": ["condiment"] + }, + { + "name": "issalt", + "param_types": ["condiment"] + }, { "name": "item_on", "param_types": ["item", "station"] }, + { + "name": "item_in", + "param_types": ["item", "station"] + }, { "name": "vacant", "param_types": ["station"] @@ -159,6 +315,10 @@ "name": "has_container", "param_types": ["player", "container"] }, + { + "name": "has_condiment", + "param_types": ["player", "condiment"] + }, { "name": "in", "param_types": ["meal", "container"] @@ -170,6 +330,10 @@ { "name": "container_at", "param_types": ["container", "station"] + }, + { + "name": "condiment_at", + "param_types": ["condiment", "station"] } ], @@ -308,6 +472,142 @@ ], "sfx": [] }, + { + "name": "put-in-oven", + "precons": [ + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "isoven", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "oven_on", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "item_in", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "item_on", + "params": ["i1", "s1"], + "is_true": false + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + }, + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": false + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": false + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + } + ], + "sfx": [] + }, + { + "name": "take-out-item", + "precons": [ + { + "predicate": "isoven", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "item_in", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "item_in", + "params": ["i1", "s1"], + "is_true": false + }, + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": true + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": false + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": false + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": false + } + ], + "sfx": [] + }, { "name": "pick-up-container", "precons": [ @@ -395,22 +695,108 @@ "sfx": [] }, { - "name": "cook", + "name": "pick-up-condiment", "precons": [ { - "predicate": "isstove", - "params": ["s1"], + "predicate": "nothing", + "params": ["p1"], "is_true": true }, { - "predicate": "iscookable", - "params": ["i1"], + "predicate": "condiment_at", + "params": ["cd1", "s1"], "is_true": true }, { - "predicate": "item_on", - "params": ["i1", "s1"], - "is_true": true + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": true + }, + { + "predicate": "condiment_at", + "params": ["cd1", "s1"], + "is_true": false + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": false + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": true + } + ], + "sfx": [] + }, + { + "name": "place-condiment", + "precons": [ + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + }, + { + "predicate": "condiment_at", + "params": ["cd1", "s1"], + "is_true": true + }, + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": false + }, + { + "predicate": "station_empty", + "params": ["s1"], + "is_true": false + } + ], + "sfx": [] + }, + { + "name": "cook", + "precons": [ + { + "predicate": "isstove", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "iscookable", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "item_on", + "params": ["i1", "s1"], + "is_true": true }, { "predicate": "loc", @@ -459,15 +845,15 @@ ] }, { - "name": "cut", + "name": "cook-on-oven", "precons": [ { - "predicate": "isboard", + "predicate": "isoven", "params": ["s1"], "is_true": true }, { - "predicate": "iscuttable", + "predicate": "iscookable", "params": ["i1"], "is_true": true }, @@ -494,55 +880,44 @@ ], "immediate_fx": [], "sfx": [ - { - "type": "repetitive", - "param": "i1", - "fx": [ - { - "predicate": "iscut", - "params": ["i1"], - "is_true": true - } - ], - "sfx": [] - }, { "type": "conditional", "param": "i1", "conditions": [ { - "predicate": "isfryableifcut", - "params": ["i1"], - "is_true": true - }, - { - "predicate": "iscut", - "params": ["i1"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true } ], - "fx": [ + "fx": [], + "sfx": [ { - "predicate": "isfryable", - "params": ["i1"], - "is_true": true + "type": "delayed", + "param": "i1", + "fx": [ + { + "predicate": "iscooked", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] } - ], - "sfx": [] + ] } ] - }, { - "name": "fry", + "name": "grill", "precons": [ { - "predicate": "isfryer", + "predicate": "isgrill", "params": ["s1"], "is_true": true }, { - "predicate": "isfryable", + "predicate": "isgrillable", "params": ["i1"], "is_true": true }, @@ -586,7 +961,7 @@ "param": "i1", "fx": [ { - "predicate": "isfried", + "predicate": "isgrilled", "params": ["i1"], "is_true": true } @@ -594,35 +969,59 @@ "sfx": [] } ] + }, + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "saltifgrilled", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "isgrilled", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "can_add_salt", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] } ] }, { - "name": "fill-pot", + "name": "toast", "precons": [ { - "predicate": "ispot", - "params": ["c1"], + "predicate": "isgrill", + "params": ["s1"], "is_true": true }, { - "predicate": "issink", - "params": ["s1"], + "predicate": "istoastable", + "params": ["i1"], "is_true": true }, { - "predicate": "loc", - "params": ["p1", "s1"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true }, { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "loc", + "params": ["p1", "s1"], "is_true": true }, { - "predicate": "container_empty", - "params": ["c1"], + "predicate": "clear", + "params": ["i1"], "is_true": true }, { @@ -631,15 +1030,15 @@ "is_true": true } ], - "immediate_fx":[], + "immediate_fx": [], "sfx": [ { "type": "conditional", - "param": "c1", + "param": "i1", "conditions": [ { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true } ], @@ -647,68 +1046,46 @@ "sfx": [ { "type": "delayed", - "param": "c1", - "fx": [], - "sfx": [ + "param": "i1", + "fx": [ { - "type": "creation", - "param": "c1", - "created_obj": { - "name": "water", - "type": "meal", - "param": "m1" - }, - "fx": [ - { - "predicate": "iswater", - "params": ["m1"], - "is_true": true - }, - { - "predicate": "in", - "params": ["m1", "c1"], - "is_true": true - }, - { - "predicate": "container_empty", - "params": ["c1"], - "is_true": false - } - ], - "sfx": [] + "predicate": "istoasted", + "params": ["i1"], + "is_true": true } - ] + ], + "sfx": [] } ] } ] }, { - "name": "boil-water", + "name": "roast", "precons": [ { - "predicate": "ispot", - "params": ["c1"], + "predicate": "isoven", + "params": ["s1"], "is_true": true }, { - "predicate": "iswater", - "params": ["m1"], + "predicate": "oven_on", + "params": ["s1"], "is_true": true }, { - "predicate": "in", - "params": ["m1", "c1"], + "predicate": "isroastable", + "params": ["i1"], "is_true": true }, { - "predicate": "isstove", - "params": ["s1"], + "predicate": "item_in", + "params": ["i1", "s1"], "is_true": true }, { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "item_at", + "params": ["i1", "s1"], "is_true": true }, { @@ -716,6 +1093,11 @@ "params": ["p1", "s1"], "is_true": true }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + }, { "predicate": "nothing", "params": ["p1"], @@ -726,11 +1108,11 @@ "sfx": [ { "type": "conditional", - "param": "m1", + "param": "i1", "conditions": [ { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "item_in", + "params": ["i1", "s1"], "is_true": true } ], @@ -738,12 +1120,22 @@ "sfx": [ { "type": "delayed", - "param": "m1", + "param": "i1", "fx": [ { - "predicate": "isboiling", - "params": ["m1"], + "predicate": "isroasted", + "params": ["i1"], "is_true": true + }, + { + "predicate": "isroastable", + "params": ["i1"], + "is_true": false + }, + { + "predicate": "oven_on", + "params": ["s1"], + "is_true": false } ], "sfx": [] @@ -753,54 +1145,42 @@ ] }, { - "name": "add-to", + "name": "bake", "precons": [ { - "predicate": "ispot", - "params": ["c1"], + "predicate": "isoven", + "params": ["s1"], "is_true": true }, { - "predicate": "addedto", - "params": ["i1", "m1"], - "is_true": false + "predicate": "oven_on", + "params": ["s1"], + "is_true": true }, { - "predicate": "in", - "params": ["m1", "c1"], - "is_true": true - }, - { - "predicate": "iscut", + "predicate": "isbakeable", "params": ["i1"], "is_true": true }, { - "predicate": "loc", - "params": ["p1", "s1"], + "predicate": "item_in", + "params": ["i1", "s1"], "is_true": true }, { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "item_at", + "params": ["i1", "s1"], "is_true": true }, { - "predicate": "has_item", - "params": ["p1", "i1"], - "is_true": true - } - ], - "immediate_fx": [ - { - "predicate": "addedto", - "params": ["i1", "m1"], + "predicate": "loc", + "params": ["p1", "s1"], "is_true": true }, { - "predicate": "has_item", - "params": ["p1", "i1"], - "is_true": false + "predicate": "clear", + "params": ["i1"], + "is_true": true }, { "predicate": "nothing", @@ -808,29 +1188,62 @@ "is_true": true } ], - "sfx": [] + "immediate_fx": [], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "item_in", + "params": ["i1", "s1"], + "is_true": true + } + ], + "fx": [], + "sfx": [ + { + "type": "delayed", + "param": "i1", + "fx": [ + { + "predicate": "isbaked", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "isbakeable", + "params": ["i1"], + "is_true": false + }, + { + "predicate": "oven_on", + "params": ["s1"], + "is_true": false + } + ], + "sfx": [] + } + ] + } + ] }, { - "name": "fill-bowl", + "name": "cut", "precons": [ { - "predicate": "isbowl", - "params": ["c1"], - "is_true": true - }, - { - "predicate": "ispot", - "params": ["c2"], + "predicate": "isboard", + "params": ["s1"], "is_true": true }, { - "predicate": "container_at", - "params": ["c1", "s1"], + "predicate": "iscuttable", + "params": ["i1"], "is_true": true }, { - "predicate": "in", - "params": ["m1", "c2"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true }, { @@ -839,51 +1252,68 @@ "is_true": true }, { - "predicate": "container_empty", - "params": ["c1"], + "predicate": "clear", + "params": ["i1"], "is_true": true }, { - "predicate": "has_container", - "params": ["p1", "c2"], + "predicate": "nothing", + "params": ["p1"], "is_true": true } ], - "immediate_fx": [ - { - "predicate": "in", - "params": ["m1", "c1"], - "is_true": true - }, - { - "predicate": "in", - "params": ["m1", "c2"], - "is_true": false - }, + "immediate_fx": [], + "sfx": [ { - "predicate": "container_empty", - "params": ["c1"], - "is_true": false + "type": "repetitive", + "param": "i1", + "fx": [ + { + "predicate": "iscut", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] }, { - "predicate": "container_empty", - "params": ["c2"], - "is_true": true + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "isfryableifcut", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "iscut", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "isfryable", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] } - ], - "sfx": [] + ] + }, { - "name": "stack", + "name": "batter", "precons": [ { - "predicate": "has_item", - "params": ["p1", "i1"], + "predicate": "isbatterable", + "params": ["i1"], "is_true": true }, { - "predicate": "clear", - "params": ["i2"], + "predicate": "isbatter_station", + "params": ["s1"], "is_true": true }, { @@ -892,15 +1322,8 @@ "is_true": true }, { - "predicate": "item_at", - "params": ["i2", "s1"], - "is_true": true - } - ], - "immediate_fx": [ - { - "predicate": "nothing", - "params": ["p1"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true }, { @@ -908,45 +1331,62 @@ "params": ["i1", "s1"], "is_true": true }, - { - "predicate": "atop", - "params": ["i1", "i2"], - "is_true": true - }, { "predicate": "clear", "params": ["i1"], "is_true": true - }, - { - "predicate": "clear", - "params": ["i2"], - "is_true": false - }, + } + ], + "immediate_fx": [ { - "predicate": "has_item", - "params": ["p1", "i1"], - "is_true": false + "predicate": "isbattered", + "params": ["i1"], + "is_true": true } ], - "sfx": [] + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "isfryableifbattered", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "isbattered", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "isfryable", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] + } + ] }, { - "name": "unstack", + "name": "fry", "precons": [ { - "predicate": "nothing", - "params": ["p1"], + "predicate": "isfryer", + "params": ["s1"], "is_true": true }, { - "predicate": "clear", + "predicate": "isfryable", "params": ["i1"], "is_true": true }, { - "predicate": "atop", - "params": ["i1", "i2"], + "predicate": "item_on", + "params": ["i1", "s1"], "is_true": true }, { @@ -954,56 +1394,842 @@ "params": ["p1", "s1"], "is_true": true }, - { - "predicate": "item_at", - "params": ["i1", "s1"], - "is_true": true - }, - { - "predicate": "item_at", - "params": ["i2", "s1"], - "is_true": true - } - ], - "immediate_fx": [ - { - "predicate": "has_item", - "params": ["p1", "i1"], - "is_true": true - }, { "predicate": "clear", - "params": ["i2"], + "params": ["i1"], "is_true": true }, { "predicate": "nothing", "params": ["p1"], - "is_true": false - }, - { - "predicate": "atop", - "params": ["i1", "i2"], - "is_true": false - }, - { - "predicate": "clear", - "params": ["i1"], - "is_true": false - }, - { - "predicate": "item_at", - "params": ["i1", "s1"], - "is_true": false + "is_true": true } ], - "sfx": [] - }, - { - "name": "wait", - "precons": [], "immediate_fx": [], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "item_on", + "params": ["i1", "s1"], + "is_true": true + } + ], + "fx": [], + "sfx": [ + { + "type": "delayed", + "param": "i1", + "fx": [ + { + "predicate": "isfried", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] + } + ] + } + ] + }, + { + "name": "fill-pot", + "precons": [ + { + "predicate": "ispot", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "issink", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + }, + { + "predicate": "container_empty", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + } + ], + "immediate_fx":[], + "sfx": [ + { + "type": "conditional", + "param": "c1", + "conditions": [ + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + } + ], + "fx": [], + "sfx": [ + { + "type": "delayed", + "param": "c1", + "fx": [], + "sfx": [ + { + "type": "creation", + "param": "c1", + "created_obj": { + "name": "water", + "type": "meal", + "param": "m1" + }, + "fx": [ + { + "predicate": "iswater", + "params": ["m1"], + "is_true": true + }, + { + "predicate": "in", + "params": ["m1", "c1"], + "is_true": true + }, + { + "predicate": "container_empty", + "params": ["c1"], + "is_true": false + } + ], + "sfx": [] + } + ] + } + ] + } + ] + }, + { + "name": "boil-water", + "precons": [ + { + "predicate": "ispot", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "iswater", + "params": ["m1"], + "is_true": true + }, + { + "predicate": "in", + "params": ["m1", "c1"], + "is_true": true + }, + { + "predicate": "isstove", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + } + ], + "immediate_fx": [], + "sfx": [ + { + "type": "conditional", + "param": "m1", + "conditions": [ + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + } + ], + "fx": [], + "sfx": [ + { + "type": "delayed", + "param": "m1", + "fx": [ + { + "predicate": "isboiling", + "params": ["m1"], + "is_true": true + } + ], + "sfx": [] + } + ] + } + ] + }, + { + "name": "boil-water-on-oven", + "precons": [ + { + "predicate": "ispot", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "iswater", + "params": ["m1"], + "is_true": true + }, + { + "predicate": "in", + "params": ["m1", "c1"], + "is_true": true + }, + { + "predicate": "isoven", + "params": ["s1"], + "is_true": true + }, + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + } + ], + "immediate_fx": [], + "sfx": [ + { + "type": "conditional", + "param": "m1", + "conditions": [ + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + } + ], + "fx": [], + "sfx": [ + { + "type": "delayed", + "param": "m1", + "fx": [ + { + "predicate": "isboiling", + "params": ["m1"], + "is_true": true + } + ], + "sfx": [] + } + ] + } + ] + }, + { + "name": "add-to", + "precons": [ + { + "predicate": "ispot", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "addedto", + "params": ["i1", "m1"], + "is_true": false + }, + { + "predicate": "in", + "params": ["m1", "c1"], + "is_true": true + }, + { + "predicate": "iscut", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + }, + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "addedto", + "params": ["i1", "m1"], + "is_true": true + }, + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": false + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + } + ], + "sfx": [] + }, + { + "name": "fill-bowl", + "precons": [ + { + "predicate": "isbowl", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "ispot", + "params": ["c2"], + "is_true": true + }, + { + "predicate": "container_at", + "params": ["c1", "s1"], + "is_true": true + }, + { + "predicate": "in", + "params": ["m1", "c2"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "container_empty", + "params": ["c1"], + "is_true": true + }, + { + "predicate": "has_container", + "params": ["p1", "c2"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "in", + "params": ["m1", "c1"], + "is_true": true + }, + { + "predicate": "in", + "params": ["m1", "c2"], + "is_true": false + }, + { + "predicate": "container_empty", + "params": ["c1"], + "is_true": false + }, + { + "predicate": "container_empty", + "params": ["c2"], + "is_true": true + } + ], + "sfx": [] + }, + { + "name": "stack", + "precons": [ + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i2"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i2", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "atop", + "params": ["i1", "i2"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i2"], + "is_true": false + }, + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": false + } + ], + "sfx": [] + }, + { + "name": "unstack", + "precons": [ + { + "predicate": "nothing", + "params": ["p1"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "atop", + "params": ["i1", "i2"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i2", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "has_item", + "params": ["p1", "i1"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i2"], + "is_true": true + }, + { + "predicate": "nothing", + "params": ["p1"], + "is_true": false + }, + { + "predicate": "atop", + "params": ["i1", "i2"], + "is_true": false + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": false + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": false + } + ], + "sfx": [] + }, + { + "name": "wait", + "precons": [], + "immediate_fx": [], + "sfx": [] + }, + { + "name": "add-ketchup", + "precons": [ + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": true + }, + { + "predicate": "isketchup", + "params": ["cd1"], + "is_true": true + }, + { + "predicate": "isgrilled", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "has_ketchup", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "has_mustard", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "has_ketchup_mustard", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "has_ketchup", + "params": ["i1"], + "is_true": false + }, + { + "predicate": "has_mustard", + "params": ["i1"], + "is_true": false + } + ], + "sfx": [] + } + ] + }, + { + "name": "add-mustard", + "precons": [ + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": true + }, + { + "predicate": "ismustard", + "params": ["cd1"], + "is_true": true + }, + { + "predicate": "isgrilled", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "has_mustard", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "has_ketchup", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "has_ketchup_mustard", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "has_ketchup", + "params": ["i1"], + "is_true": false + }, + { + "predicate": "has_mustard", + "params": ["i1"], + "is_true": false + } + ], + "sfx": [] + } + ] + }, + { + "name": "add-salt", + "precons": [ + { + "predicate": "has_condiment", + "params": ["p1", "cd1"], + "is_true": true + }, + { + "predicate": "issalt", + "params": ["cd1"], + "is_true": true + }, + { + "predicate": "can_add_salt", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "has_salt", + "params": ["i1"], + "is_true": true + } + ], "sfx": [] + }, + { + "name": "roll-triangle", + "precons": [ + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "isrollable", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "has_item", + "params": ["p1", "i2"], + "is_true": true + }, + { + "predicate": "isrollingpin", + "params": ["i2"], + "is_true": true + }, + { + "predicate": "clear", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "istable", + "params": ["s1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "istriangle", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "isshapeableiftriangle", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "isshapeable", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [] + } + ] + }, + { + "name": "shape", + "precons": [ + { + "predicate": "item_at", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "item_on", + "params": ["i1", "s1"], + "is_true": true + }, + { + "predicate": "loc", + "params": ["p1", "s1"], + "is_true": true + }, + { + "predicate": "isshapeable", + "params": ["i1"], + "is_true": true + } + ], + "immediate_fx": [ + { + "predicate": "isshaped", + "params": ["i1"], + "is_true": true + } + ], + "sfx": [ + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "iscroissant", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "isbakeable", + "params": ["i1"], + "is_true": true + }, + { + "predicate": "istriangle", + "params": ["i1"], + "is_true": false + } + ], + "sfx": [] + }, + { + "type": "conditional", + "param": "i1", + "conditions": [ + { + "predicate": "iscircle", + "params": ["i1"], + "is_true": true + } + ], + "fx": [ + { + "predicate": "iscircle", + "params": ["i1"], + "is_true": false + } + ], + "sfx": [] + } + ] } ] } \ No newline at end of file diff --git a/environments/env_generator/builder.py b/environments/env_generator/builder.py index 387d15644..1719dd308 100644 --- a/environments/env_generator/builder.py +++ b/environments/env_generator/builder.py @@ -3,7 +3,7 @@ import os import copy import itertools -from .object_enums import Item, Player, Station, Container, Meal, str_to_typed_enum, TYPES +from .object_enums import Item, Player, Station, Container, Meal, Condiment, str_to_typed_enum, TYPES from .procedural_generator import randomize_environment import random @@ -15,8 +15,9 @@ PLAYER_FIELD = "players" MEAL_FIELD = "meals" CONTAINER_FIELD = "containers" +CONDIMENT_FIELD = "condiments" -ENTITY_FIELDS = [STATION_FIELD, ITEM_FIELD, PLAYER_FIELD, CONTAINER_FIELD, MEAL_FIELD] +ENTITY_FIELDS = [STATION_FIELD, ITEM_FIELD, PLAYER_FIELD, CONTAINER_FIELD, MEAL_FIELD, CONDIMENT_FIELD] def entity_to_entity_field(entity): """ @@ -44,6 +45,7 @@ def entity_to_entity_field(entity): elif isinstance(typed_enum, Player): return PLAYER_FIELD elif isinstance(typed_enum, Meal): return MEAL_FIELD elif isinstance(typed_enum, Container): return CONTAINER_FIELD + elif isinstance(typed_enum, Condiment): return CONDIMENT_FIELD except ValueError: # Convert wild card entities into entity fields if entity == STATION_FIELD[:-1]: return STATION_FIELD @@ -51,6 +53,7 @@ def entity_to_entity_field(entity): elif entity == PLAYER_FIELD[:-1]: return PLAYER_FIELD elif entity == MEAL_FIELD[:-1]: return MEAL_FIELD elif entity == CONTAINER_FIELD[:-1]: return CONTAINER_FIELD + elif entity == CONDIMENT_FIELD[:-1]: return CONDIMENT_FIELD raise ValueError(f"Cannot convert {entity} into an entity field.") def load_environment(json_filename, seed=None): diff --git a/environments/env_generator/examples/assemble_hotdogs.json b/environments/env_generator/examples/assemble_hotdogs.json new file mode 100644 index 000000000..90da5f238 --- /dev/null +++ b/environments/env_generator/examples/assemble_hotdogs.json @@ -0,0 +1,99 @@ +{ + "version": "1.0.0", + "width": 5, + "height": 5, + "config": { + "num_cuts": { + "lettuce": 3, + "default": 3 + }, + "cook_time": { + "hotdog": 3, + "bun": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "table", + "x": 1, + "y": 1 + }, + { + "name": "table", + "x": 2, + "y": 1 + }, + { + "name": "table", + "x": 3, + "y": 1 + } + ], + "items": [ + { + "name": "bun", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["istoasted","istoastable"] + }, + { + "name": "hotdog", + "x": 1, + "y": 1, + "stack-level": 0, + "predicates": ["isgrilled","isgrillable"] + }, + { + "name": "hotdog", + "x": 3, + "y": 1, + "stack-level": 0, + "predicates": ["isgrilled","isgrillable"] + }, + { + "name": "bun", + "x": 2, + "y": 1, + "stack-level": 0, + "predicates": ["istoasted","istoastable"] + } + ], + "players": [ + { + "name": "robot", + "x": 0, + "y": 0, + "direction": [0, 1] + } + ], + "goal_description": "Put together two hot dogs.", + "goal": [ + { + "predicate": "atop", + "args": ["hotdog", "bun"], + "ids": [1, 2] + }, + { + "predicate": "item_on", + "args": ["bun", "table"], + "ids": [2, 3] + }, + { + "predicate": "atop", + "args": ["hotdog", "bun"], + "ids": [4, 5] + }, + { + "predicate": "item_on", + "args": ["bun", "table"], + "ids": [5, 6] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/bake_croissants.json b/environments/env_generator/examples/bake_croissants.json new file mode 100644 index 000000000..f1881441e --- /dev/null +++ b/environments/env_generator/examples/bake_croissants.json @@ -0,0 +1,84 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "croissant": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "oven", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "oven", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "croissant", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isshaped","isbakeable"], + "id": "a" + }, + { + "name": "croissant", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isshaped","isbakeable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Bake two croissants.", + "goal": [ + { + "predicate": "isbaked", + "args": ["croissant"], + "ids": ["a"] + }, + { + "predicate": "isbaked", + "args": ["croissant"], + "ids": ["b"] + }, + { + "predicate": "item_at", + "args": ["croissant", "table"], + "ids": ["a", 1] + }, + { + "predicate": "item_at", + "args": ["croissant", "table"], + "ids": ["b", 2] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/batter_shrimp.json b/environments/env_generator/examples/batter_shrimp.json new file mode 100644 index 000000000..cff8606f9 --- /dev/null +++ b/environments/env_generator/examples/batter_shrimp.json @@ -0,0 +1,73 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "batter_station", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "batter_station", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "shrimp", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isbatterable", "isfryableifbattered"], + "id": "a" + }, + { + "name": "shrimp", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isbatterable", "isfryableifbattered"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Batter two shrimps.", + "goal": [ + { + "predicate": "isbattered", + "args": ["shrimp"], + "ids": ["a"] + }, + { + "predicate": "isbattered", + "args": ["shrimp"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/fry_shrimp.json b/environments/env_generator/examples/fry_shrimp.json new file mode 100644 index 000000000..0700b3403 --- /dev/null +++ b/environments/env_generator/examples/fry_shrimp.json @@ -0,0 +1,73 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "fryer", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "fryer", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "shrimp", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isbattered", "isfryable"], + "id": "a" + }, + { + "name": "shrimp", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isbattered", "isfryable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Fry two battered shrimps.", + "goal": [ + { + "predicate": "isfried", + "args": ["shrimp"], + "ids": ["a"] + }, + { + "predicate": "isfried", + "args": ["shrimp"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/grill_hotdogs.json b/environments/env_generator/examples/grill_hotdogs.json new file mode 100644 index 000000000..34139e1d8 --- /dev/null +++ b/environments/env_generator/examples/grill_hotdogs.json @@ -0,0 +1,73 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "grill", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "hotdog", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "a" + }, + { + "name": "hotdog", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal": [ + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/grill_salmons.json b/environments/env_generator/examples/grill_salmons.json new file mode 100644 index 000000000..49738f844 --- /dev/null +++ b/environments/env_generator/examples/grill_salmons.json @@ -0,0 +1,74 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "salmon": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "grill", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "salmon", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable", "saltifgrilled"], + "id": "a" + }, + { + "name": "salmon", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isgrillable", "saltifgrilled"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Grill two salmons.", + "goal": [ + { + "predicate": "isgrilled", + "args": ["salmon"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["salmon"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/ketchup_hotdog.json b/environments/env_generator/examples/ketchup_hotdog.json new file mode 100644 index 000000000..ccba228ef --- /dev/null +++ b/environments/env_generator/examples/ketchup_hotdog.json @@ -0,0 +1,75 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0 + } + ], + "items": [ + { + "name": "hotdog", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "a" + } + ], + "condiments": [ + { + "name": "ketchupbottle", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isketchup"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Cook a hot dog and add ketchup on it.", + "goal": [ + { + "predicate": "has_ketchup", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["a"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/ketchup_mustard_hotdog.json b/environments/env_generator/examples/ketchup_mustard_hotdog.json new file mode 100644 index 000000000..9751a83c1 --- /dev/null +++ b/environments/env_generator/examples/ketchup_mustard_hotdog.json @@ -0,0 +1,82 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0 + } + ], + "items": [ + { + "name": "hotdog", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "a" + } + ], + "condiments": [ + { + "name": "ketchupbottle", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isketchup"], + "id": "b" + }, + { + "name": "mustardbottle", + "x": 2, + "y": 0, + "stack-level": 0, + "predicates": ["ismustard"] + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Cook a hot dog and add ketchup and mustard on it.", + "goal": [ + { + "predicate": "has_ketchup_mustard", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["a"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_croissant.json b/environments/env_generator/examples/make_croissant.json new file mode 100644 index 000000000..68cf31a2e --- /dev/null +++ b/environments/env_generator/examples/make_croissant.json @@ -0,0 +1,73 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "croissant": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "oven", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "croissant", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isrollable","isshapeableiftriangle"], + "id": "a" + }, + { + "name": "rollingpin", + "x": 0, + "y": 0, + "stack-level": 0, + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Roll dough into triangle, shape dough into croissant, and bake the croissant.", + "goal": [ + { + "predicate": "isbaked", + "args": ["croissant"], + "ids": ["a"] + }, + { + "predicate": "item_at", + "args": ["croissant", "table"], + "ids": ["a", 1] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_croissant_dough.json b/environments/env_generator/examples/make_croissant_dough.json new file mode 100644 index 000000000..8bfc8306e --- /dev/null +++ b/environments/env_generator/examples/make_croissant_dough.json @@ -0,0 +1,72 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "table", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "stove", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "croissant", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isrollable", "isshapeableiftriangle"], + "id": "a" + }, + { + "name": "rollingpin", + "x": 0, + "y": 0, + "stack-level": 0, + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Roll the dough into a triangle and shape that into croissant.", + "goal": [ + { + "predicate": "isshaped", + "args": ["croissant"], + "ids": ["a"] + }, + { + "predicate": "item_on", + "args": ["rollingpin", "table"], + "ids": ["b", 1] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_fried_shrimp.json b/environments/env_generator/examples/make_fried_shrimp.json new file mode 100644 index 000000000..0dc3c5463 --- /dev/null +++ b/environments/env_generator/examples/make_fried_shrimp.json @@ -0,0 +1,74 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "shrimp": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "batter_station", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "fryer", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "shrimp", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isbatterable", "isfryableifbattered"], + "id": "a" + }, + { + "name": "shrimp", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isbatterable", "isfryableifbattered"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Batter two shrimp and fry two battered shrimps", + "goal": [ + { + "predicate": "isfried", + "args": ["shrimp"], + "ids": ["a"] + }, + { + "predicate": "isfried", + "args": ["shrimp"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_hotdog.json b/environments/env_generator/examples/make_hotdog.json new file mode 100644 index 000000000..31b2e5c34 --- /dev/null +++ b/environments/env_generator/examples/make_hotdog.json @@ -0,0 +1,84 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "bun": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "grill", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "bun", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["istoastable"], + "id": "a" + }, + { + "name": "hotdog", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal": [ + { + "predicate": "istoasted", + "args": ["bun"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["b"] + }, + { + "predicate": "atop", + "args": ["hotdog","bun"], + "ids": ["b", "a"] + }, + { + "predicate": "item_on", + "args": ["bun", "table"], + "ids": ["a", 1] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_ketchup_mustard_hotdog.json b/environments/env_generator/examples/make_ketchup_mustard_hotdog.json new file mode 100644 index 000000000..e82a44b4b --- /dev/null +++ b/environments/env_generator/examples/make_ketchup_mustard_hotdog.json @@ -0,0 +1,111 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "bun": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0 + }, + { + "name": "table", + "x": 0, + "y": 2 + } + ], + "items": [ + { + "name": "hotdog", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "a" + }, + { + "name": "bun", + "x": 0, + "y": 2, + "stack-level": 0, + "predicates": ["istoastable"], + "id": "b" + } + ], + "condiments": [ + { + "name": "ketchupbottle", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isketchup"], + "id": "b" + }, + { + "name": "mustardbottle", + "x": 2, + "y": 0, + "stack-level": 0, + "predicates": ["ismustard"] + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Make a hot dog and add ketchup and mustard on it.", + "goal": [ + { + "predicate": "has_ketchup_mustard", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "atop", + "args": ["hotdog", "bun"], + "ids": ["a", "b"] + }, + { + "predicate": "item_on", + "args": ["bun", "table"], + "ids": ["b", 1] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "istoasted", + "args": ["bun"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/make_salted_salmon.json b/environments/env_generator/examples/make_salted_salmon.json new file mode 100644 index 000000000..8180e78d0 --- /dev/null +++ b/environments/env_generator/examples/make_salted_salmon.json @@ -0,0 +1,75 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "salmon": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0 + } + ], + "items": [ + { + "name": "salmon", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable", "saltifgrilled"], + "id": "a" + } + ], + "condiments": [ + { + "name": "salt", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["issalt"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Grill a salmon and add salt to it.", + "goal": [ + { + "predicate": "has_salt", + "args": ["salmon"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["salmon"], + "ids": ["a"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/mustard_hotdog.json b/environments/env_generator/examples/mustard_hotdog.json new file mode 100644 index 000000000..68c075cd6 --- /dev/null +++ b/environments/env_generator/examples/mustard_hotdog.json @@ -0,0 +1,75 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "hotdog": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0 + } + ], + "items": [ + { + "name": "hotdog", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isgrillable"], + "id": "a" + } + ], + "condiments": [ + { + "name": "mustardbottle", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["ismustard"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Cook a hot dog and add mustard on it.", + "goal": [ + { + "predicate": "has_mustard", + "args": ["hotdog"], + "ids": ["a"] + }, + { + "predicate": "isgrilled", + "args": ["hotdog"], + "ids": ["a"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/roast_turkeys.json b/environments/env_generator/examples/roast_turkeys.json new file mode 100644 index 000000000..da3631458 --- /dev/null +++ b/environments/env_generator/examples/roast_turkeys.json @@ -0,0 +1,84 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "turkey": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "oven", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "oven", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "turkey", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["isroastable"], + "id": "a" + }, + { + "name": "turkey", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["isroastable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Roast two turkeys.", + "goal": [ + { + "predicate": "isroasted", + "args": ["turkey"], + "ids": ["a"] + }, + { + "predicate": "isroasted", + "args": ["turkey"], + "ids": ["b"] + }, + { + "predicate": "item_at", + "args": ["turkey", "table"], + "ids": ["a", 1] + }, + { + "predicate": "item_at", + "args": ["turkey", "table"], + "ids": ["b", 2] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/shape_croissant.json b/environments/env_generator/examples/shape_croissant.json new file mode 100644 index 000000000..6bd2e07c6 --- /dev/null +++ b/environments/env_generator/examples/shape_croissant.json @@ -0,0 +1,60 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "table", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "table", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "croissant", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["istriangle", "isshapeable"], + "id": "a" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal description": "Shape the triangle dough into a croissant.", + "goal": [ + { + "predicate": "isshaped", + "args": ["croissant"], + "ids": ["a"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/examples/toast_bun.json b/environments/env_generator/examples/toast_bun.json new file mode 100644 index 000000000..0b809acd9 --- /dev/null +++ b/environments/env_generator/examples/toast_bun.json @@ -0,0 +1,73 @@ +{ + "version": "1.0.0", + "width": 3, + "height": 3, + "config": { + "cook_time": { + "bun": 3, + "default": 3 + } + }, + "stations": [ + { + "name": "table", + "x": 0, + "y": 1 + }, + { + "name": "grill", + "x": 2, + "y": 1, + "id": "A" + }, + { + "name": "table", + "x": 0, + "y": 0 + }, + { + "name": "grill", + "x": 2, + "y": 0, + "id": "B" + } + ], + "items": [ + { + "name": "bun", + "x": 0, + "y": 1, + "stack-level": 0, + "predicates": ["istoastable"], + "id": "a" + }, + { + "name": "bun", + "x": 0, + "y": 0, + "stack-level": 0, + "predicates": ["istoastable"], + "id": "b" + } + ], + "players": [ + { + "name": "robot", + "x": 1, + "y": 0, + "direction": [-1, 0] + } + ], + "goal": [ + { + "predicate": "istoasted", + "args": ["bun"], + "ids": ["a"] + }, + { + "predicate": "istoasted", + "args": ["bun"], + "ids": ["b"] + } + ] +} \ No newline at end of file diff --git a/environments/env_generator/object_enums.py b/environments/env_generator/object_enums.py index 0ba495f58..2a7b6383f 100644 --- a/environments/env_generator/object_enums.py +++ b/environments/env_generator/object_enums.py @@ -11,6 +11,13 @@ class Item(Enum): ONION = "onion" CHICKEN = "chicken" POTATO = "potato" + HOTDOG = "hotdog" + BUN = "bun" + SALMON = "salmon" + TURKEY = "turkey" + SHRIMP = "shrimp" + CROISSANT = "croissant" + ROLLINGPIN = "rollingpin" class Player(Enum): ROBOT = "robot" @@ -18,11 +25,14 @@ class Player(Enum): class Station(Enum): BOARD = "board" STOVE = "stove" + OVEN = "oven" TABLE = "table" FRYER = "fryer" SINK = "sink" COUNTER = "counter" BLENDER = "blender" + GRILL = "grill" + BATTER_STATION = "batter_station" class Container(Enum): POT = "pot" @@ -34,7 +44,11 @@ class Meal(Enum): BOILING_WATER = "boiling_water" SOUP = "soup" -TYPES = {"item": Item, "player": Player, "station": Station, "container": Container, "meal": Meal} +class Condiment(Enum): + KETCHUP = "ketchupbottle" + MUSTARD = "mustardbottle" + SALT = "salt" +TYPES = {"item": Item, "player": Player, "station": Station, "container": Container, "meal": Meal, "condiment": Condiment} def str_to_typed_enum(s): """ @@ -49,7 +63,7 @@ def str_to_typed_enum(s): Returns: typed_enum (Enum): Enum of the string. """ - for typed_enum in [Item, Player, Station, Container, Meal]: + for typed_enum in [Item, Player, Station, Container, Meal, Condiment]: try: return typed_enum(s) except ValueError: diff --git a/renderer/canvas.py b/renderer/canvas.py index 203aecafb..401a58680 100644 --- a/renderer/canvas.py +++ b/renderer/canvas.py @@ -114,7 +114,7 @@ def _choose_item_asset(self, item_image_name, obs): item_config = self.config["item"]["entities"][item_image_name] - # Find the the asset with most matches to current game state. If two or + # Find the asset with most matches to current game state. If two or # more assets have the same number of matches, the default asset is used. max_matches = 0 asset_config = item_config["assets"] @@ -132,7 +132,10 @@ def _choose_item_asset(self, item_image_name, obs): chosen_asset = asset_config[asset]["asset"] elif matches == max_matches: chosen_asset = asset_config["default"] - + # if asset == "grilled": + # for predicate in asset_config[asset]: + # if predicate in item_predicates: + # return asset_config[asset][predicate]["asset"] return chosen_asset def _draw_item_image(self, surface, item_name, obs, position): @@ -395,6 +398,23 @@ def _draw_container_image(self, surface, container_name, obs, position): self._draw_image(surface, f"{container_image_name}", position + self.pix_square_size * x_scale_factor, self.pix_square_size * y_scale_factor) + def _draw_condiment_image(self, surface, condiment_name, obs, position): + """ + Helper to draw a condiment image on the canvas. + + Args: + surface (pygame.Surface): Surface to draw on + condiment_name (str): Name of the condiment + obs (List[Literal]): Game state predicates + position (np.array): (x, y) position of the condiment (with pix_square_size factor accounted for) + """ + trimmed_condiment_name, condiment_ID = trim_item_ID(condiment_name) + condiment_image_name = self.config["condiment"]["entities"][trimmed_condiment_name]["assets"]["default"] + x_scale_factor = self.config["condiment"]["constants"]["X_SCALE_FACTOR"] + y_scale_factor = self.config["condiment"]["constants"]["Y_SCALE_FACTOR"] + + self._draw_image(surface, f"{condiment_image_name}", position + self.pix_square_size * x_scale_factor, self.pix_square_size * y_scale_factor) + def _draw_floor(self, surface): """ Draw the floor on the canvas. @@ -424,7 +444,7 @@ def _draw_floor(self, surface): self._draw_tiles(surface, sprites, self.ground_matrix) - def _draw_furniture(self, surface): + def _draw_furniture(self, surface, obs): """ Draw the furniture on the canvas. @@ -435,14 +455,14 @@ def _draw_furniture(self, surface): # load ground tile data self.furniture_tileset = self._load_tiles(self.config["floor"]["furniture"]) abstract_tile_matrix = self.tiling["furniture"] - abstract_tile_matrix = self._extract_stations_to_furniture(abstract_tile_matrix) + abstract_tile_matrix = self._extract_stations_to_furniture(abstract_tile_matrix, obs) self.furniture_matrix = self._parse_abstract_tile_matrix(abstract_tile_matrix, self.furniture_tileset) sprites = self.furniture_tileset["sprites"] self._draw_tiles(surface, sprites, self.furniture_matrix) - def _choose_station_asset(self, station_image_name): + def _choose_station_asset(self, station_image_name, obs): """ Helper function to get the asset name of a station. Stations imagery can either be images or tiles. Images are preferred over tiles. @@ -455,16 +475,42 @@ def _choose_station_asset(self, station_image_name): asset and "type" is "image" if the station is represented by an image or "tile" if represented by a tile """ - station_image_name, _ = trim_item_ID(station_image_name) + # Get the name of the station and store its id + station_image_name, station_id = trim_item_ID(station_image_name) station_config = self.config["station"]["entities"][station_image_name] + + # Get predicates of station in current game state + station_predicates = [] + for literal, is_true in obs.predicates.items(): + if is_true and literal.params[0].name == station_image_name + station_id: + station_predicates.append(literal.name) + + # Find the asset with most matches to current game state. If two or + # more assets have the same number of matches, the default asset is used. if "default" in station_config["assets"]: - return {"name": station_config["assets"]["default"], "type": "image"} + max_matches = 0 + asset_config = station_config["assets"] + chosen_asset = asset_config["default"] + for asset in asset_config: + if asset == "default": + continue + matches = 0 + for predicate in asset_config[asset]["predicates"]: + if predicate in station_predicates: + matches += 1 + if all(predicate in station_predicates for predicate in asset_config[asset]["predicates"]): + if matches > max_matches: + max_matches = matches + chosen_asset = asset_config[asset]["asset"] + elif matches == max_matches: + chosen_asset = asset_config["default"] + return {"name": chosen_asset, "type": "image"} elif "tile" in station_config["assets"]: return {"name": station_config["assets"]["tile"], "type": "tile"} else: raise RuntimeError("Empty station asset config: " + station_config) - def _draw_stations(self, surface): + def _draw_stations(self, surface, obs): """ Draws the stations on the canvas. @@ -479,7 +525,7 @@ def _draw_stations(self, surface): for i, row in enumerate(self.layout): for j, col in enumerate(row): if col is not None: - asset_info = self._choose_station_asset(col) + asset_info = self._choose_station_asset(col, obs) if asset_info["type"] == "image": name, _ = trim_item_ID(col) offset = self.config["station"]["entities"][name]["constants"].get("STATION_OFFSET", station_offset) @@ -530,6 +576,7 @@ def _draw_player(self, surface, obs): robot_image_name = robot_sprite[player_obj.sprite_value] held_item_name = None held_container_name = None + held_condiment_name = None # Draw the player self._draw_image(surface, robot_image_name, player_pos * self.pix_square_size, self.pix_square_size) @@ -539,11 +586,16 @@ def _draw_player(self, surface, obs): held_item_name = literal.params[1].name if is_true and literal.name == "has_container" and literal.params[0].name == player.name: held_container_name = literal.params[1].name + if is_true and literal.name == "has_condiment" and literal.params[0].name == player.name: + held_condiment_name = literal.params[1].name # Draw the item or container the player is holding if held_item_name: self._draw_item_image(surface, held_item_name, obs, player_pos * self.pix_square_size) if held_container_name: self._draw_container_image(surface, held_container_name, obs, player_pos * self.pix_square_size) + if held_condiment_name: + self._draw_condiment_image(surface, held_condiment_name, obs, player_pos * self.pix_square_size) + def _draw_item(self, surface, obs): """ @@ -615,6 +667,28 @@ def _draw_container(self, surface, obs): name, _ = trim_item_ID(container) container_pos[1] -= self.config["container"]["entities"][name]["constants"].get("STATION_CONTAINER_OFFSET", station_container_offset) self._draw_container_image(surface, container, obs, container_pos * self.pix_square_size) + + def _draw_condiment(self, surface, obs): + """ + This helper draws condiments on the canvas. + + Args: + surface (pygame.Surface): Surface to draw on + obs (State): Game state predicates + + Side effects: + Draws the condiments to surface + """ + station_condiment_offset = self.config["condiment"]["constants"]["STATION_CONDIMENT_OFFSET"] + for literal, is_true in obs.predicates.items(): + station_condiment_offset = self.config["condiment"]["constants"]["STATION_CONDIMENT_OFFSET"] + if is_true and literal.name == "condiment_at": + condiment = literal.params[0].name + station = literal.params[1].name + condiment_pos = self._get_station_position(station) + name, _ = trim_item_ID(condiment) + condiment_pos[1] -= self.config["condiment"]["entities"][name]["constants"].get("STATION_CONDIMENT_OFFSET", station_condiment_offset) + self._draw_condiment_image(surface, condiment, obs, condiment_pos * self.pix_square_size) def _add_platforms_underneath_stations(self, stations, abstract_tile_matrix): """ @@ -660,7 +734,7 @@ def _add_platforms_underneath_stations(self, stations, abstract_tile_matrix): else: abstract_tile_matrix[x][y] = underneath - def _extract_stations_to_furniture(self, abstract_tile_matrix): + def _extract_stations_to_furniture(self, abstract_tile_matrix, obs): """ Searches for all stations with single letter names and places corresponding tiles in the furniture layer. It is assumed that stations with single letter names wish to undergo this processing step. @@ -679,7 +753,7 @@ def _extract_stations_to_furniture(self, abstract_tile_matrix): for i, row in enumerate(self.layout): for j, col in enumerate(row): if col is not None: - asset_info = self._choose_station_asset(col) + asset_info = self._choose_station_asset(col, obs) if asset_info["type"] == "tile": abstract_tile_matrix[i][j] = asset_info["name"] else: @@ -697,8 +771,9 @@ def draw_to_surface(self, surface, obs): obs (List[Literal]): Game state predicates """ self._draw_floor(surface) - self._draw_furniture(surface) - self._draw_stations(surface) + self._draw_furniture(surface, obs) + self._draw_stations(surface, obs) self._draw_player(surface, obs) self._draw_item(surface, obs) self._draw_container(surface, obs) + self._draw_condiment(surface, obs) diff --git a/renderer/configuration/robotouille_config.json b/renderer/configuration/robotouille_config.json index c36474dd8..89249d3a9 100644 --- a/renderer/configuration/robotouille_config.json +++ b/renderer/configuration/robotouille_config.json @@ -27,7 +27,10 @@ "assets": { "default": "bottombun.png" }, - "constants": {} + "constants": { + "X_SCALE_FACTOR": 0.50, + "Y_SCALE_FACTOR": 0.1 + } }, "topbun": { "assets": { @@ -41,6 +44,16 @@ }, "constants": {} }, + "bun": { + "assets": { + "default": "bun.png", + "toasted": { + "asset": "toastedbun.png", + "predicates": ["istoasted"] + } + }, + "constants": {} + }, "cheese": { "assets": { "default": "cheese.png" @@ -73,6 +86,95 @@ }, "constants": {} }, + "hotdog": { + "assets": { + "default": "hotdog.png", + "grilled": { + "asset": "grilledhotdog.png", + "predicates": ["isgrilled"], + "has_ketchup": { + "asset": "ketchup_hotdog.png", + "predicates": ["has_ketchup"] + }, + "has_mustard": { + "asset": "mustard_hotdog.png", + "predicates": ["has_mustard"] + }, + "has_ketchup_mustard": { + "asset": "ketchup_mustard_hotdog.png", + "predicates": ["has_ketchup_mustard"] + } + } + }, + "constants": { + "STACK_OFFSET": -0.1 + } + }, + "turkey": { + "assets": { + "default": "turkey.png", + "roasted": { + "asset": "roastedturkey.png", + "predicates": ["isroasted"] + } + }, + "constants": {} + }, + "salmon": { + "assets": { + "default": "salmon.png", + "grilled": { + "asset": "grilledsalmon.png", + "predicates": ["isgrilled"] + }, + "has_salt": { + "asset": "grilledsaltedsalmon.png", + "predicates": ["isgrilled","has_salt"] + } + }, + "constants": {} + }, + "shrimp": { + "assets": { + "default": "shrimp.png", + "battered": { + "asset": "battered_shrimp.png", + "predicates": ["isbattered"] + }, + "fried": { + "asset": "fried_shrimp.png", + "predicates": ["isbattered","isfried"] + } + }, + "constants": { + "STACK_OFFSET": -0.1 + } + }, + + "croissant": { + "assets": { + "default": "dough.png", + "triangle": { + "asset": "triangle.png", + "predicates": ["istriangle"] + }, + "shaped": { + "asset": "croissant.png", + "predicates": ["isshaped"] + }, + "baked": { + "asset": "baked_croissant.png", + "predicates": ["isshaped","isbaked"] + } + }, + "constants": {} + }, + "rollingpin": { + "assets": { + "default": "rollingpin.png" + }, + "constants": {} + }, "lettuce": { "assets": { "default": "lettuce.png", @@ -145,6 +247,31 @@ }, "constants": {} }, + "oven": { + "assets": { + "default": "oven.png", + "oven_on": { + "asset": "oven_on.png", + "predicates": ["oven_on"] + } + }, + "constants": {} + }, + "batter_station": { + "assets": { + "default": "batter_station.png" + }, + "constants": { + "STATION_OFFSET": 0.16, + "underneath": "T" + } + }, + "grill": { + "assets": { + "default": "grill.png" + }, + "constants": {} + }, "table": { "assets": { "tile": "T" @@ -237,6 +364,36 @@ } } } + }, + "condiment": { + "constants": { + "STATION_CONDIMENT_OFFSET" : 0.25, + "X_SCALE_FACTOR": 0.125, + "Y_SCALE_FACTOR": 0.75 + }, + "entities": { + "ketchupbottle": { + "assets": { + "default": "ketchupbottle.png", + "predicates": ["isketchup"] + }, + "constants": {} + }, + "mustardbottle": { + "assets": { + "default": "mustardbottle.png", + "predicates": ["ismustard"] + }, + "constants": {} + }, + "salt": { + "assets": { + "default": "salt.png", + "predicates": ["issalt"] + }, + "constants": {} + } + } } diff --git a/robotouille/env.py b/robotouille/env.py index df01422ca..32029923e 100644 --- a/robotouille/env.py +++ b/robotouille/env.py @@ -100,9 +100,15 @@ def build_station_location_predicates(environment_dict): pred = Predicate().initialize("vacant", ["station"], [station_obj]) predicates.append(pred) match = False - # Check if there are any items or containers at the station - for field in ["items", "containers"]: - predicate = "item_at" if field == "items" else "container_at" + # Check if there are any items, containers, or condiments at the station + for field in ["items", "containers", "condiments"]: + if field == "items": + predicate = "item_at" + elif field == "containers": + predicate = "container_at" + else: + predicate = "condiment_at" + # predicate = "item_at" if field == "items" else "container_at" for entity in environment_dict.get(field, []): x = entity["x"] y = entity["y"] @@ -112,7 +118,7 @@ def build_station_location_predicates(environment_dict): pred = Predicate().initialize(predicate, [field[:-1], "station"], [obj, station_obj]) predicates.append(pred) match = True - # If no items or containers are at the station, add a station_empty predicate + # If no items, containers, or condiments are at the station, add a station_empty predicate if not match: pred = Predicate().initialize("station_empty", ["station"], [station_obj]) predicates.append(pred) @@ -151,6 +157,14 @@ def build_player_location_predicates(environment_dict): predicates.append(pred) match = True break + if not match and environment_dict.get("condiments"): + for condiment in environment_dict["condiments"]: + if player["x"] == condiment["x"] and player["y"] == condiment["y"]: + obj = Object(condiment["name"], "condiment") + pred = Predicate().initialize("has_condiment", ["player", "condiment"], [player_obj, obj]) + predicates.append(pred) + match = True + break if not match: pred = Predicate().initialize("nothing", ["player"], [player_obj]) predicates.append(pred)