Configurations
One of the most powerful features of PuzzleClone is its separation of a puzzle's logic from its instance.
- The Specification File (
spec.yaml
) is the blueprint—it defines the puzzle's structure, rules, and how to randomize it. - The Configuration is the build plan—it's a complete record of every random choice made for one specific puzzle instance.
When you have both the blueprint and the build plan, you can perfectly recreate a unique puzzle. This separation offers two key advantages:
-
Verifiability: How do you know your complex
spec.yaml
is correct? You can generate a puzzle from your seed puzzle's known parameters, creating a configuration file. Then, use that configuration to generate a new puzzle. If the new puzzle and its answer match your original seed puzzle, your blueprint is correct. It's the ultimate sanity check. -
Flexibility: Imagine you want to translate a puzzle into another language or change its theme (e.g., from students to wizards) without altering the core logic. Configurations make this trivial. You can reuse the exact same logical "build plan" with a new "blueprint" that only changes the descriptive text, guaranteeing 100% logical consistency.
Anatomy of a Configuration
Every puzzle generated by PuzzleClone includes a config
field that stores its unique build plan. This configuration captures two types of information:
-
Variable Values: All the final values of the variables defined in your
vars
block are stored as simple key-value pairs.json "p_num": 10, "select_num": 6, "names": ["Laura", "Corey", "Austin", ...]
-
The domains and the randomization pools for generating derived symbols, dynamic conditions, and options of multiple-choice questions. They will be stored as a dict in the format of
{"domain": <domain>, "pool": <pool>}
- For Single-Template Items: The
pool
is a list where each entry corresponds to a generated item (e.g., one condition). Each item is a 3D list following the[dimension][source][selection]
hierarchy. - For Multi-Template Items: The
pool
is a list of objects, each pinpointing the exact template used and the selections made for it:{"template_id": <index>, "config": [[...]]}
. - Index vs. Value (
__
Notation): This is a crucial detail. In thepool
, a value wrapped in double underscores is an index, not a literal value."__0__"
means: "the 0-th item from the source list" (e.g., the first student's name)."0"
means: "the literal integer value 0".
- For Single-Template Items: The
Configuration-Based Puzzle Generation
You can instruct PuzzleClone to skip all randomization and deterministically build a puzzle using a specific configuration file. This is perfect for verifying, translating, or re-theming puzzles.
The command is:
python translator.py -d <spec_path> -g <config_path> -o <output_path>
This will use the blueprint from <spec_path>
but follow the exact build plan from <config_path>
, producing a perfect clone and saving it to <output_path>
.
Mixing Determinism with Randomness
Sometimes, you want a mix: use most of an existing configuration but re-randomize a few specific variables.
Use Case: You have 1000 puzzles about students generated in Chinese. You want to create the exact same 1000 puzzles, with the same underlying logic, but in English and with new, randomized English names.
- Create a new
spec_en.yaml
where you translate all thedesc
fields to English. In thevars
section, change thenames
variable to use an English name generator. - Use the following command, which adds the
--use-spec-vars
flag:
python translator.py -d spec_en.yaml -g config_zh.json -o puzzle_en.json --use-spec-vars names
This command tells PuzzleClone:
"Use
spec_en.yaml
as the blueprint andconfig_zh.json
as the build plan. However, for thenames
variable specifically, ignore the value in the config file and generate a new one based on the rules inspec_en.yaml
. For everything else, follow the config."
This powerful feature allows you to precisely control which parts of a puzzle are cloned and which are freshly generated.