Initial commit from Openverse UI

This commit is contained in:
2025-11-21 09:44:15 +00:00
commit 9d4755a5fc
3 changed files with 478 additions and 0 deletions

212
README.md Normal file
View File

@@ -0,0 +1,212 @@
# Game Design Document: **"Maze Conquerors"**
---
## 1. Concept Paragraph
**Maze Conquerors** is a deterministic, turn-based strategy game where two rival explorers traverse a shifting labyrinth to collect mystical runes scattered across the grid. Each turn, a player can **move**, **scan**, or **claim** spaces within the maze to gain strategic advantage. The maze itself is a fixed grid seeded at initialization to ensure reproducibility. The players cannot see the whole maze initially—they progressively reveal it through scanning or movement. The objective is to collect more runes than the opponent before the turn limit is reached or one player becomes trapped.
This design is **entirely unrelated** to any negotiation or commerce environment; it deals solely with spatial planning, exploration, and deterministic turn resolution.
---
## 2. Roles and Win Condition
- **Roles:**
- Two players: **Explorer A** and **Explorer B**, each beginning at opposite edges of the maze.
- **Player Objective:**
- Navigate the grid to collect as many **Runes** as possible.
- Avoid getting trapped in dead ends or blocked paths.
- **Win Condition:**
- The game ends when the turn limit is reached **OR** both players have no valid moves left.
- The winner is the player with **more collected runes**.
- If both have the same number of runes, the winner is the one **closer to the Maze Core** (measured as Manhattan distance).
- If still tied, the game is declared a **draw**.
---
## 3. Turn Structure and Determinism
- **Turn Order:**
- Explorer A acts first on odd-numbered turns; Explorer B on even-numbered turns.
- **Turn Limit:**
- Default: 30 turns (modifiable via environment configuration).
- **Determinism:**
- All maze generation and rune placements are produced using a seeded random generator during `reset(seed)` to guarantee reproducibility of identical sequences.
---
## 4. Action Grammar (Machine-Parseable)
The content within `\boxed{{}}` defines the action. Each action must strictly follow one of the grammars below.
### **Allowed Action Tokens**
| Action Type | Grammar Format | Example Valid | Example Invalid | Invalidity Reason |
|--------------|----------------|----------------|------------------|
| **[Move:<direction>]** | `^\\[Move:(up|down|left|right)\\]$` | `[Move:up]` | `[Move:upper]` | "upper" not a valid direction |
| **[Scan:<radius>]** | `^\\[Scan:[1-3]\\]$` | `[Scan:2]` | `[Scan:5]` | radius out of allowed range |
| **[Claim]** | `^\\[Claim\\]$` | `[Claim]` | `[Claim:rune]` | extra parameters not permitted |
| **[Wait]** | `^\\[Wait\\]$` | `[Wait]` | `[Pause]` | Invalid token name |
---
## 5. Game State Schema
```json
{
"global_turn": 7,
"turn_limit": 30,
"maze_dimensions": [7, 7],
"seed": 12345,
"maze_layout": [
["S", ".", ".", "#", ".", ".", "R"],
[".", "#", ".", ".", ".", "#", "."],
[".", ".", "R", ".", ".", ".", "."],
["#", ".", ".", ".", "#", ".", "#"],
[".", "R", ".", ".", ".", "R", "."],
[".", ".", ".", "#", ".", ".", "."],
["R", ".", "#", ".", ".", ".", "G"]
],
"players": {
"ExplorerA": {
"position": [0, 0],
"runes_collected": 2,
"moves_remaining": 5,
"visible_tiles": [[0,0],[0,1],[1,0]],
"last_action": "[Move:down]",
"is_trapped": false
},
"ExplorerB": {
"position": [6, 6],
"runes_collected": 3,
"moves_remaining": 5,
"visible_tiles": [[6,6],[6,5],[5,6]],
"last_action": "[Scan:2]",
"is_trapped": false
}
},
"observation_log": [
{"turn":1, "player":"ExplorerA", "action":"[Move:right]", "result":"moved successfully"},
{"turn":1, "player":"ExplorerB", "action":"[Scan:2]", "result":"revealed tiles"}
],
"game_status": "active",
"winner": null
}
```
---
## 6. Initialization Rules
- Maze generated using `maze_dimensions` and `seed`.
- Starting positions: Explorer A at top-left corner `(0,0)`, Explorer B at bottom-right corner `(n-1,n-1)`.
- `runes` are distributed pseudo-randomly on open tiles based on `seed`.
- Each player begins with a 3x3 visible region centered on their starting tile.
- Initial observation: description of immediate surroundings and actions available.
---
## 7. Validation and Error Handling
- If extracted action text fails regex match for any valid token → `Invalid format`.
- If movement direction leads to a wall or outside the grid → `Invalid move: path blocked`.
- If `Scan` exceeds remaining moves or repeats within two consecutive turns → `Invalid scan usage`.
- If `Claim` executed on a cell without rune → `Invalid claim: no rune present`.
- If `Wait` occurs while trapped → allowed but auto-check for terminal trap condition afterward.
Each invalid action triggers `set_invalid_move(player, reason)` and ends that players turn with no state change.
---
## 8. Terminal Conditions and Scoring
**Terminal checks performed at end of each full round:**
1. All players trapped (no legal moves remain) → immediate end.
2. `global_turn` >= `turn_limit` → end game.
3. All runes collected → end game.
**Scoring Rules:**
- Primary: `runes_collected`
- Secondary (tie-break): distance to center (`maze_core` `(n//2, n//2)`)
- Tertiary: earliest to reach current score (fewer turns used wins)
- If all equal → draw.
---
## 9. Player Prompt Specification
Each turn, `_generate_player_prompt` summarizes environment and expectations.
**Prompt Outline:**
- Brief identity blurb and status summary:
- "You are Explorer A, traversing an ancient labyrinth to gather runes before your rival."
- Details of known surroundings (visible tiles, walls, runes, opponent position if visible).
- State remaining turns, runes collected, and possible legal actions.
- Grammar requirement and response format.
**Example Section within Prompt:**
```
Your visible surroundings:
◎ = your position
# = wall
R = rune
. = empty tile
Turn 7 of 30. You have collected 2 runes.
Allowed actions:
[Move:up], [Move:down], [Move:left], [Move:right]
[Scan:13]
[Claim]
[Wait]
Put your final answer within \boxed{{}} at the end of your response.
Example valid response:
I need to get closer to the center and gather more runes.
\boxed{{[Move:right]}}
Example invalid response:
\boxed{{Go right}} ← not matching action grammar
```
**Required Helper:**
Function `_extract_answer_content(self, action: str) -> str` isolates content inside the `\boxed{{}}` for validation and interpretation.
---
## 10. API Mapping Plan
**`reset(seed: int) -> (game_state, observations)`**
- Clears previous game data.
- Generates maze using deterministic seed.
- Initializes players, turns, and logs.
- Returns initial `game_state` and per-player observations.
**`step(action_dict) -> (game_state, observations, rewards, done, info)`**
- Receives both players boxed actions.
- Uses `_extract_answer_content` to parse action text.
- Validates actions, applies successful ones deterministically.
- Updates `maze_layout`, player positions, visibility, and `observation_log`.
- Checks terminal conditions, computes rewards based on runes and outcomes.
- Returns updated game state and next observations.
**`_generate_player_prompt(player)`**
- Builds text described above based on current `game_state`.
- Outlines visible region, remaining turns, and valid command grammar.
---
## 11. Copy-Check Against the Example
All concepts in this document—**maze navigation, runes, explorers, grid movement, scanning, and claiming**—are **unique** and unrelated to any negotiation or offer-making scenarios.
Resource names (`runes`, `maze_layout`, `visible_tiles`, `explorers`) and objectives (spatial exploration, rune collection) are fully original and distinct from any trade or dialog games.
The `game_state` schema, prompt text, and mechanics exclusively belong to this **Maze Conquerors** design.