sissississi's picture
Add RL training environment with OpenEnv backend
bc52096
"""Task definitions for origami RL training.
Each task defines a target shape as a reference FOLD crease pattern.
The LLM must discover a crease pattern that folds into the same shape.
"""
TASKS: dict[str, dict] = {
"triangle": {
"name": "triangle",
"description": "Fold the paper in half diagonally to make a triangle",
"difficulty": 1,
"paper": {"width": 1.0, "height": 1.0},
"target_fold": {
"vertices_coords": [[0, 0], [1, 0], [1, 1], [0, 1]],
"edges_vertices": [[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]],
"edges_assignment": ["B", "B", "B", "B", "V"],
"edges_foldAngle": [0, 0, 0, 0, 180],
"faces_vertices": [[0, 1, 2], [0, 2, 3]],
},
},
"half_fold": {
"name": "half_fold",
"description": "Fold the paper in half horizontally",
"difficulty": 1,
"paper": {"width": 1.0, "height": 1.0},
"target_fold": {
"vertices_coords": [
[0, 0], [1, 0], [1, 1], [0, 1], [0, 0.5], [1, 0.5],
],
"edges_vertices": [
[0, 1], [1, 5], [5, 2], [2, 3], [3, 4], [4, 0],
[4, 5],
],
"edges_assignment": ["B", "B", "B", "B", "B", "B", "V"],
"edges_foldAngle": [0, 0, 0, 0, 0, 0, 180],
"faces_vertices": [[0, 1, 5, 4], [4, 5, 2, 3]],
},
},
"quarter_fold": {
"name": "quarter_fold",
"description": "Fold the paper into quarters (two perpendicular folds)",
"difficulty": 2,
"paper": {"width": 1.0, "height": 1.0},
"target_fold": {
"vertices_coords": [
[0, 0], [0.5, 0], [1, 0],
[0, 0.5], [0.5, 0.5], [1, 0.5],
[0, 1], [0.5, 1], [1, 1],
],
"edges_vertices": [
[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0],
[1, 4], [4, 7],
[3, 4], [4, 5],
],
"edges_assignment": [
"B", "B", "B", "B", "B", "B", "B", "B",
"V", "V", "V", "V",
],
"edges_foldAngle": [
0, 0, 0, 0, 0, 0, 0, 0,
180, 180, 180, 180,
],
"faces_vertices": [
[0, 1, 4, 3],
[1, 2, 5, 4],
[3, 4, 7, 6],
[4, 5, 8, 7],
],
},
},
"letter_fold": {
"name": "letter_fold",
"description": "Tri-fold the paper like a letter (two parallel folds)",
"difficulty": 2,
"paper": {"width": 1.0, "height": 1.0},
"target_fold": {
"vertices_coords": [
[0, 0], [1, 0],
[0, 1/3], [1, 1/3],
[0, 2/3], [1, 2/3],
[0, 1], [1, 1],
],
"edges_vertices": [
[0, 1], [1, 3], [3, 5], [5, 7], [7, 6], [6, 4], [4, 2], [2, 0],
[2, 3],
[4, 5],
],
"edges_assignment": [
"B", "B", "B", "B", "B", "B", "B", "B",
"V", "M",
],
"edges_foldAngle": [
0, 0, 0, 0, 0, 0, 0, 0,
180, -180,
],
"faces_vertices": [
[0, 1, 3, 2],
[2, 3, 5, 4],
[4, 5, 7, 6],
],
},
},
# --- Optigami patterns (from lib/patterns.ts) ---
"waterbomb": {
"name": "waterbomb",
"description": "Create a waterbomb base with valley folds on diagonals and mountain folds on midlines of a square sheet",
"difficulty": 3,
"paper": {"width": 2.0, "height": 2.0},
"target_fold": {
"vertices_coords": [
[-1, 1], [0, 1], [1, 1],
[-1, 0], [0, 0], [1, 0],
[-1, -1], [0, -1], [1, -1],
],
"edges_vertices": [
[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0],
[0, 4], [2, 4], [6, 4], [8, 4],
[1, 4], [3, 4], [5, 4], [7, 4],
],
"edges_assignment": [
"B", "B", "B", "B", "B", "B", "B", "B",
"V", "V", "V", "V",
"M", "M", "M", "M",
],
"edges_foldAngle": [
0, 0, 0, 0, 0, 0, 0, 0,
180, 180, 180, 180,
-180, -180, -180, -180,
],
"faces_vertices": [
[0, 1, 4], [1, 2, 4],
[2, 5, 4], [5, 8, 4],
[8, 7, 4], [7, 6, 4],
[6, 3, 4], [3, 0, 4],
],
},
},
"accordion": {
"name": "accordion",
"description": "Make an accordion (zig-zag) fold with alternating mountain and valley creases like a paper fan",
"difficulty": 2,
"paper": {"width": 2.0, "height": 2.0},
"target_fold": {
"vertices_coords": [
[-1, 1], [-0.5, 1], [0, 1], [0.5, 1], [1, 1],
[-1, -1], [-0.5, -1], [0, -1], [0.5, -1], [1, -1],
],
"edges_vertices": [
[0, 1], [1, 2], [2, 3], [3, 4],
[5, 6], [6, 7], [7, 8], [8, 9],
[0, 5], [4, 9],
[1, 6], [2, 7], [3, 8],
],
"edges_assignment": [
"B", "B", "B", "B",
"B", "B", "B", "B",
"B", "B",
"V", "M", "V",
],
"edges_foldAngle": [
0, 0, 0, 0,
0, 0, 0, 0,
0, 0,
180, -180, 180,
],
"faces_vertices": [
[0, 1, 6, 5], [1, 2, 7, 6],
[2, 3, 8, 7], [3, 4, 9, 8],
],
},
},
"miura_ori": {
"name": "miura_ori",
"description": "Create a Miura-ori tessellation fold pattern on a 2x2 grid with offset zigzag vertices",
"difficulty": 3,
"paper": {"width": 2.0, "height": 2.0},
"target_fold": {
"vertices_coords": [
[-1, 1], [0, 1.2], [1, 1],
[-1, 0], [0, 0.2], [1, 0],
[-1, -1], [0, -0.8], [1, -1],
],
"edges_vertices": [
[0, 1], [1, 2], [2, 5], [5, 8], [8, 7], [7, 6], [6, 3], [3, 0],
[1, 4], [4, 7],
[3, 4], [4, 5],
],
"edges_assignment": [
"B", "B", "B", "B", "B", "B", "B", "B",
"M", "M",
"V", "M",
],
"edges_foldAngle": [
0, 0, 0, 0, 0, 0, 0, 0,
-180, -180,
180, -180,
],
"faces_vertices": [
[0, 1, 4, 3], [1, 2, 5, 4],
[3, 4, 7, 6], [4, 5, 8, 7],
],
},
},
}
def get_task(name: str | None = None) -> dict:
"""Get a task by name. Defaults to 'triangle'."""
if name is None:
name = "triangle"
if name not in TASKS:
raise ValueError(f"Unknown task '{name}'. Available: {list(TASKS.keys())}")
return TASKS[name]
def list_tasks() -> list[str]:
"""List all available task names."""
return list(TASKS.keys())