Files
composable-evidence-states-…/data/generate_scenes.py
T
2026-10-01 22:16:29 +08:00

53 lines
2.1 KiB
Python

from __future__ import annotations
import random
from typing import Any
from data.schema import COLORS, OBJECT_IDS, RELATIONS, SHAPES, Fact, SceneObject
def _relation(first: SceneObject, second: SceneObject, rng: random.Random) -> Fact:
relation = rng.choice(RELATIONS)
if relation == "left_of":
first = SceneObject(first.object_id, first.color, first.shape, 55, 112)
second = SceneObject(second.object_id, second.color, second.shape, 169, 112)
elif relation == "right_of":
first = SceneObject(first.object_id, first.color, first.shape, 169, 112)
second = SceneObject(second.object_id, second.color, second.shape, 55, 112)
elif relation == "above":
first = SceneObject(first.object_id, first.color, first.shape, 112, 55)
second = SceneObject(second.object_id, second.color, second.shape, 112, 169)
else:
first = SceneObject(first.object_id, first.color, first.shape, 112, 169)
second = SceneObject(second.object_id, second.color, second.shape, 112, 55)
return Fact(first.object_id, relation, second.object_id), first, second
def generate_scene(scene_id: int, seed: int, num_objects: int = 2) -> dict[str, Any]:
if num_objects != 2:
raise ValueError("The stage-one MVP currently supports exactly two objects.")
rng = random.Random((seed * 1_000_003) + scene_id)
colors = rng.sample(COLORS, k=num_objects)
shapes = rng.sample(SHAPES, k=num_objects)
objects = [
SceneObject(OBJECT_IDS[index], colors[index], shapes[index], 0, 0)
for index in range(num_objects)
]
relation, first, second = _relation(objects[0], objects[1], rng)
objects = [first, second]
facts = []
for item in objects:
facts.extend(
[
Fact(item.object_id, "color", item.color),
Fact(item.object_id, "shape", item.shape),
]
)
facts.append(relation)
return {
"scene_id": f"scene-{scene_id:07d}",
"objects": [item.to_dict() for item in objects],
"visual_facts": [fact.to_dict() for fact in facts],
}