---
name: shiritori-game
description: Play an interactive Japanese shiritori game using the public shiritori dictionary API, including template selection, difficulty or genre customization, kana reading normalization, word validation, turn-by-turn continuation, and duplicate prevention. Use when the user asks to play しりとり, requests a themed or difficulty-controlled shiritori session, or wants API-backed validation of Japanese shiritori words.
---

# Shiritori Game

Play Japanese shiritori against the user with live dictionary results from `https://shiritori.sugar-knight.com`.

Use `scripts/shiritori_api.py` for API calls. Run it with Python 3; it uses only the standard library. Treat the live `/api/templates` and `/api/meta` responses as authoritative because the service may evolve. The machine-readable API definition is `https://shiritori.sugar-knight.com/api/openapi.json`.

## Start a game

1. Run `python scripts/shiritori_api.py templates` at the beginning of a new game.
2. If the user already specified a style, map it to the closest template and any extra parameters. Otherwise, briefly offer suitable template choices. Recommend `standard` when the user has no preference.
3. Confirm the chosen rules in one short sentence, then establish this conversation state:
   - `template`: selected template ID, or `none` for a fully custom search
   - `parameters`: additional or overriding API query parameters
   - `rule`: `standard` or `terminal-n`
   - `used_readings`: normalized hiragana readings used by either player
   - `used_ids`: returned API word IDs when known
   - `required_head`: kana required for the next turn, initially empty
4. Ask who starts only when the user has not already supplied a first word or preference.

Common mappings:

- ordinary play: `template=standard`
- easier/young children: `template=preschool`
- exactly two or three characters: `template=two` or `template=three`
- harder vocabulary: `template=higher`; use `template=todai` when explicitly requested
- rare vocabulary: `template=rare`
- every word ends in `ん`: `template=terminal-n`
- Pokémon names: use no template with `genre=ポケモンの名前`, `word_rule=all`, and `playable_only=true`

Do not blindly combine a template with custom parameters that conflict with its default conditions. For example, `standard` requires common default-allowed nouns and therefore excludes Pokémon proper names. If a combination returns no candidates, inspect the live template parameters and switch to an explicit fully custom parameter set while preserving the user's intent.

## Process the user's turn

1. Convert the submitted word to its hiragana reading. Convert katakana directly. Infer readings for kanji; if genuinely ambiguous, ask the user for the reading instead of guessing.
2. Run `python scripts/shiritori_api.py lookup --reading <ひらがな> --template <id> --param key=value ...`, passing the active template and custom parameters just as for candidate searches. Omit `--template` for a fully custom game. Use `matches` to verify that the reading exists and `eligible_matches` to verify that it satisfies the active rules. When multiple spellings share the reading, prefer the entry matching the user's written form if visible; otherwise any exact-reading entry is sufficient.
3. Reject the turn politely and request another word when:
   - the word is absent from the dictionary;
   - its reading is already in `used_readings`;
   - its `head_kana` does not equal `required_head`;
   - its `tail_kana` is `ん` under standard rules;
   - no entry appears in `eligible_matches`, meaning the word violates the selected template or custom conditions.
4. On acceptance, add its reading and ID to the state. For `standard`, use the API result's `tail_kana` as the next required kana. For `terminal-n`, use `before_terminal_n_kana`. Do not derive the connection kana from the surface spelling or raw final Unicode character.

## Produce the assistant's turn

1. Search by the required connection kana:

   ```text
   python scripts/shiritori_api.py candidates --head <かな> --template <id> --exclude <reading> ... --param key=value
   ```

   Repeat `--exclude` for every value in `used_readings`. Omit `--template` for a fully custom game. Repeat `--param` for all custom or overriding parameters.
2. Select a natural candidate not present in `used_readings`. Prefer a recognizable word unless the chosen rules request rare or difficult vocabulary.
3. If no candidate is returned, retry with `--limit 50`. Do not silently relax user-selected difficulty, genre, length, or other rules. If the configured rules make continuation impossible, explain that briefly and offer to change a rule or end the game.
4. Add the chosen reading and ID to the state. Set `required_head` from `tail_kana` for `standard`, or `before_terminal_n_kana` for `terminal-n`.
5. Reply compactly with the surface, reading when useful, and the kana the user must start with. Example: `りんご。次は「ご」です。`

Continue this loop until someone uses a losing `ん` word, no valid unused candidate exists, or the user ends the game. Never claim an API validation or candidate search occurred unless the script was actually run during that turn.

## Rule handling

- Track duplicates by normalized reading, not only spelling; treat `林檎` and `りんご` as the same word.
- Use `head_kana` and `tail_kana` returned by the API so contracted sounds, long vowels, and other normalization follow the dictionary's rules.
- Keep state in the current conversation. If context has lost the history, ask the user to provide the recent word list rather than risk reusing a word.
- For `terminal-n`, run the helper with `--template terminal-n`. It fetches the live chain template, applies its filters to word search, and enforces `ends_with=ん`. Do not add `rule`, `words`, or `playable_only=true` as custom parameters.
- For `terminal-n`, accept only an eligible word with `before_terminal_n_kana`; use that value as the next connection kana. Do not apply the standard losing-`ん` check.
- Do not invent words or bypass an empty result with unaudited model knowledge.
