Initial commit from Openverse UI

This commit is contained in:
2025-11-25 13:02:22 +00:00
commit 6580f8e929
3 changed files with 562 additions and 0 deletions

248
README.md Normal file
View File

@@ -0,0 +1,248 @@
# GAME DESIGN DOCUMENT — *“DUEL OF SIGNS: A ROCKPAPERSCISSORS TOURNAMENT”*
---
## 1. Concept Paragraph
**Concept:**
*Duel of Signs* is a deterministic, text-based tournament between two contenders — called **Signmasters** — who compete through successive matches of an expanded **RockPaperScissors** variant. The universe is a ceremonial arena where hand-sign duels determine dominance. Each player secretly chooses one of three signs (`[Rock]`, `[Paper]`, `[Scissors]`) per round. The goal is to win a majority of rounds in a predefined number of matches. Players can also invoke the `[Predict:<Sign>]` token to gamble on the opponents next move for bonus points. This design is **entirely unrelated to any negotiation or trading scenario**; it contains no resource bargaining, currency, or offers — only symbolic duels and prediction tactics.
---
## 2. Roles and Win Condition
**Roles:**
- **Player A:** Signmaster 1
- **Player B:** Signmaster 2
Each behaves symmetrically.
**Primary Objective:**
Earn more **tournament points** than the opponent after all rounds have concluded.
**Scoring:**
- Win a duel → +2 points
- Draw a duel → +1 point
- Loss → 0 points
- Correct use of `[Predict:<Sign>]` (if correct) → +1 bonus point
- Incorrect prediction → 1 penalty point
**Decision Rule:**
At the end of the final round:
- Higher score → **Winner**
- Equal scores → **Draw**
---
## 3. Turn Structure and Determinism
Each **round** has two **turns** (one per player in sequential mode).
The game proceeds through a fixed **number of rounds**, e.g., `5`.
Turn order alternates each round (A starts odd rounds, B starts even).
After both have chosen, the system resolves the duel deterministically:
- Rock beats Scissors
- Scissors beats Paper
- Paper beats Rock
All scoring and predictions apply deterministically without randomness.
A **random seed** is used only for reproducibility during environment reset (e.g., for deciding initial starting player or generating tournament metadata). Given the same seed, the entire match sequence will replay exactly.
---
## 4. Action Grammar (MachineParsable)
### 4.1 Allowed Action Tokens
| Action Type | Token Format | Semantic Meaning |
|--------------|---------------|------------------|
| Play Sign | `[Play:Rock]`, `[Play:Paper]`, `[Play:Scissors]` | Commit to a sign |
| Predict | `[Predict:Rock]`, `[Predict:Paper]`, `[Predict:Scissors]` | Attempt to forecast opponents next Play sign |
| Concede | `[Concede]` | Forfeit the match immediately |
### 4.2 Formal Grammar
Regular expressions (expressed textually):
```
PLAY_TOKEN = r'^\[Play:(Rock|Paper|Scissors)\]$'
PREDICT_TOKEN = r'^\[Predict:(Rock|Paper|Scissors)\]$'
CONCEDE_TOKEN = r'^\[Concede\]$'
```
**Valid examples:**
-`[Play:Rock]` → valid play
-`[Predict:Paper]` → valid prediction
**Invalid examples:**
-`[Play: Stones]` → invalid sign (unrecognized subtype)
-`[PredictPaper]` → missing colon and brackets, invalid format
-`[yield]` → token not in allowed action set
---
## 5. Game State Schema
```json
{
"tournament_name": "Grand Duels 2077",
"seed": 123,
"round_index": 3,
"max_rounds": 5,
"turn_order": ["PlayerA", "PlayerB"],
"players": {
"PlayerA": {
"score": 5,
"last_action": "[Play:Rock]",
"predicted_action": "[Predict:Paper]",
"round_wins": 2
},
"PlayerB": {
"score": 4,
"last_action": "[Play:Scissors]",
"predicted_action": null,
"round_wins": 1
}
},
"round_history": [
{
"round": 1,
"PlayerA_action": "[Play:Rock]",
"PlayerB_action": "[Play:Paper]",
"winner": "PlayerB"
},
{
"round": 2,
"PlayerA_action": "[Predict:Scissors]",
"PlayerB_action": "[Play:Scissors]",
"winner": "Draw"
}
],
"current_turn": "PlayerB",
"status": "active",
"winner": null,
"observation_log": [
"Round 1: PlayerA played Rock; PlayerB played Paper → PlayerB wins.",
"Round 2: PlayerA predicted Scissors correctly."
]
}
```
---
## 6. Initialization Rules
- **Seed**: A reproducible integer input for deterministic setup.
- **Starting Player**: Chooses first mover by fixed or seeded rule (e.g., even seed → PlayerA starts).
- **Scores & History**: Zeroed at start.
- **Observations:** Each player receives an opening message:
- Tournament title
- Number of rounds
- Their player role (A or B)
- Reminder of available actions and scoring system.
---
## 7. Validation and Error Handling
When an action is received (content extracted from inside `\boxed{}`):
**Validation Steps:**
1. Confirm the format matches one of the regex tokens.
2. Confirm its the players turn.
3. Ensure they havent already played a `[Play:*]` or `[Predict:*]` in this round (disallow duplicates).
4. If `[Concede]`, mark immediate terminal outcome.
**Invalid Move Reasons:**
- “Unrecognized token format.”
- “It is not your turn.”
- “Duplicate action this round.”
- “Concession not allowed after round resolution.”
If invalid, `set_invalid_move(player, reason)` will be triggered and the opponent **automatically wins** the match.
---
## 8. Terminal Conditions and Scoring
**Terminal checks per turn:**
1. If both players have legal `[Play:*]` actions, resolve round outcome:
- Update scores
- Record to `round_history`
- Increment `round_index`
2. If `[Concede]` action is made → opponent receives **instant win**
3. If `round_index > max_rounds` → tournament ends
**Endgame Scoring:**
- `winner = player with higher score`
- if equal → `"Draw"`
**Tiebreakers (if desired extension):**
If tied, compare number of individual round wins; if still tied, declare draw.
---
## 9. Player Prompt Specification
**Prompt Identity Blurb:**
> You are a Signmaster in the grand arena of *Duel of Signs.* Each round, you must choose a hand sign to defeat your opponent or attempt a daring prediction for extra points.
**Prompt Contents:**
- Current round, scores, and last known actions.
- Reminder of valid action format and consequences.
- Scoring recap.
- End instruction:
“Put your final answer within `\boxed{}` at the end of your response.”
**Allowed Actions:**
```
[Play:Rock]
[Play:Paper]
[Play:Scissors]
[Predict:Rock]
[Predict:Paper]
[Predict:Scissors]
[Concede]
```
**Example Valid Response:**
```
I think Paper will protect me from Rock.
\boxed{[Play:Paper]}
```
**Example Invalid Response:**
```
I choose to play paper.
\boxed{PlayPaper}
```
→ invalid because brackets and colon missing.
**Helper extraction rule:**
`\_extract_answer_content(self, action: str) -> str`
Parses text inside `\boxed{}` and returns only the internal token string for validation and step logic.
---
## 10. API Mapping Plan
| API Method | Purpose | Reads / Writes | Outcome |
|-------------|----------|----------------|----------|
| **reset(seed=None)** | Initialize tournament state using provided or default seed. Create base observations and metadata. | Writes: `seed`, `tournament_name`, `round_index=1`, `players` fields. | Returns initial observation to both players. |
| **step(player_action)** | Process one players turn. Validate syntax and legality. Update game state accordingly. If round complete, compute duel result. | Reads: `current_turn`, `players[...]`, `round_history`. Writes: `scores`, `round_index`, `winner`, `status`. | Returns new observations, and signals win/draw when terminal. |
| **_generate_player_prompt(player_id)** | Builds contextual textual prompt per player at their turn. Displays current scores, allowed tokens, round state, and format examples. | Reads: full `game_state`. | Returns formatted text prompt for model or user. |
---
## 11. CopyCheck Against the Example
- **Theme & Objective:** Completely distinct — ceremonial handsign duels rather than negotiation or trading.
- **Entities & Resources:** Signs, rounds, scores; no goods, offers, or currencies.
- **Prompt Text:** Focused on symbolic combat, prediction bonuses, and deterministic scoring.
- **Game State Keys:** (`tournament_name`, `round_index`, `round_history`, `predicted_action`, `round_wins`, etc.) — all unique to this design.
---
**End of “Duel of Signs” Game Design Document**