ipin-vr/ipin_vr/generator.py

74 lines
1.9 KiB
Python
Raw Normal View History

import random
from dataclasses import dataclass
from typing import Optional
from .lexicon import COLORS, LOCATIONS, OBJECTS, VERBS
@dataclass
class Clause:
verb_id: str
object_id: str
location_id: str
color_id: Optional[str]
@dataclass
class Command:
clauses: list[Clause]
level: int
def _render_clause(clause: Clause, first: bool) -> str:
verb = VERBS[clause.verb_id]
if not first:
verb = verb.lower()
obj = OBJECTS[clause.object_id]
parts = [verb]
if clause.color_id is not None:
parts.append(COLORS[clause.color_id][obj["gender"]])
parts.append(obj["acc"])
parts.append(LOCATIONS[clause.location_id])
return " ".join(parts)
def render(command: Command) -> str:
rendered = [
_render_clause(clause, i == 0)
for i, clause in enumerate(command.clauses)
]
return " i ".join(rendered) + "."
def random_command(level: int) -> Command:
verb_ids = list(VERBS)
object_ids = list(OBJECTS)
location_ids = list(LOCATIONS)
color_ids = list(COLORS)
def _clause(object_id: str, use_color: bool) -> Clause:
return Clause(
verb_id=random.choice(verb_ids),
object_id=object_id,
location_id=random.choice(location_ids),
color_id=random.choice(color_ids) if use_color else None,
)
if level == 1:
return Command(clauses=[_clause(random.choice(object_ids), False)], level=1)
if level == 2:
return Command(clauses=[_clause(random.choice(object_ids), True)], level=2)
if level == 3:
obj1 = random.choice(object_ids)
obj2 = random.choice([o for o in object_ids if o != obj1])
clauses = [
_clause(obj1, random.choice([True, False])),
_clause(obj2, random.choice([True, False])),
]
return Command(clauses=clauses, level=3)
raise ValueError(f"Nieznany poziom: {level}")