257 lines
8.4 KiB
Markdown
257 lines
8.4 KiB
Markdown
---
|
||
|
||
# **MazeBound: TextArena Turn-Based Game Design Document**
|
||
|
||
---
|
||
|
||
## 1. Concept Paragraph
|
||
|
||
**MazeBound** is a deterministic, turn-based grid navigation challenge where two explorers compete to reach the **Beacon Core** hidden within a labyrinthine maze. Both start from opposite corners and must navigate through maze pathways by issuing precise movement and scanning commands. Each player sees only tiles within their **visibility radius**, and partial knowledge of the maze is revealed as they explore. Decision-making centers on exploration efficiency and path optimization rather than combat or negotiation.
|
||
**This design has no relation to any negotiation, trading, or resource–bargaining example.** Instead, it is a purely spatial exploration competition built from scratch.
|
||
|
||
---
|
||
|
||
## 2. Roles and Win Condition
|
||
|
||
- **Roles:**
|
||
- **Player A (Explorer Alpha):** Starts in the northwest corner `(0, 0)`.
|
||
- **Player B (Explorer Beta):** Starts in the southeast corner `(N-1, N-1)`.
|
||
|
||
- **Objectives:**
|
||
- Each player tries to reach the **Beacon Core** tile before the opponent.
|
||
|
||
- **Win Condition:**
|
||
- A player **wins** immediately upon entering the Beacon Core’s coordinate.
|
||
- If both reach it on the same turn (deterministically impossible due to alternating turns), the earlier arrival wins.
|
||
- If the turn limit is reached and no one has reached the goal, the winner is the explorer **closest** (by Manhattan distance) to the Beacon Core.
|
||
- If both are equidistant, the result is a **draw**.
|
||
|
||
---
|
||
|
||
## 3. Turn Structure and Determinism
|
||
|
||
- The game proceeds in **strict alternate turns**, starting with Player A.
|
||
- On each turn, a single discrete action is taken by the active player.
|
||
- A global **turn counter** increments after both players have completed their respective turns.
|
||
- **Reproducibility:** Maze layout and Beacon location are generated using a fixed random seed at `reset(seed)`.
|
||
- **Turn Limit:** 40 turns (20 per player). The game ends when either:
|
||
- The Beacon Core is reached, or
|
||
- The turn limit is exhausted.
|
||
|
||
---
|
||
|
||
## 4. Action Grammar (Machine-Parseable)
|
||
|
||
Each player issues a deterministic command encoded as a token or tagged instruction.
|
||
|
||
### Allowed Actions
|
||
|
||
| Action | Format | Meaning |
|
||
|--------|---------|----------|
|
||
| **Move** | `MOVE:<direction>` | Move one cell if no wall in that direction. Directions: `N`, `S`, `E`, `W`. |
|
||
| **Scan** | `SCAN` | Reveal the layout of adjacent cells within visibility radius (does **not** move). |
|
||
| **Pass** | `PASS` | Skip turn voluntarily. |
|
||
|
||
#### Regular Expression Patterns
|
||
|
||
- `MOVE:(N|S|E|W)`
|
||
- `SCAN`
|
||
- `PASS`
|
||
|
||
### Examples
|
||
|
||
| Type | Example | Valid? | Reason |
|
||
|------|----------|--------|--------|
|
||
| Valid | `MOVE:N` | ✅ | Proper MOVE token. |
|
||
| Invalid | `MOVE:NORTH` | ❌ | Invalid direction token; must be N/S/E/W. |
|
||
| Valid | `SCAN` | ✅ | Correct command. |
|
||
| Invalid | `SCAN:W` | ❌ | Must not specify an argument. |
|
||
| Valid | `PASS` | ✅ | Legal pass action. |
|
||
| Invalid | `REST` | ❌ | Token not in action grammar. |
|
||
|
||
---
|
||
|
||
## 5. Game State Schema
|
||
|
||
Example runtime `game_state` (prettified JSON):
|
||
|
||
```json
|
||
{
|
||
"maze_size": 7,
|
||
"turn_number": 3,
|
||
"turn_limit": 40,
|
||
"seed": 12345,
|
||
"beacon_coord": [3, 3],
|
||
"maze_layout": [
|
||
[" ", "#", " ", " ", " ", "#", " "],
|
||
[" ", " ", "#", "#", " ", " ", " "],
|
||
["#", " ", " ", " ", "#", " ", "#"],
|
||
[" ", "#", " ", "B", " ", "#", " "],
|
||
[" ", " ", "#", " ", " ", " ", " "],
|
||
["#", " ", " ", "#", "#", " ", "#"],
|
||
[" ", " ", "#", " ", " ", " ", " "]
|
||
],
|
||
"players": {
|
||
"A": {
|
||
"name": "Explorer Alpha",
|
||
"position": [0, 0],
|
||
"visible_cells": [[0,0],[0,1],[1,0]],
|
||
"discovered_map": {},
|
||
"distance_to_beacon": 6,
|
||
"last_action": "MOVE:E"
|
||
},
|
||
"B": {
|
||
"name": "Explorer Beta",
|
||
"position": [6, 6],
|
||
"visible_cells": [[6,6],[5,6],[6,5]],
|
||
"discovered_map": {},
|
||
"distance_to_beacon": 6,
|
||
"last_action": "SCAN"
|
||
}
|
||
},
|
||
"history": [
|
||
{"turn":1,"player":"A","action":"MOVE:E"},
|
||
{"turn":1,"player":"B","action":"SCAN"},
|
||
{"turn":2,"player":"A","action":"MOVE:S"}
|
||
],
|
||
"winner": null,
|
||
"terminated": false,
|
||
"termination_reason": ""
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Initialization Rules
|
||
|
||
- `maze_layout` and `beacon_coord` generated from a fixed seed to ensure reproducibility.
|
||
- Maze contains open cells `" "` and blocked cells `"#"`.
|
||
- Both players begin with visibility radius = 1.
|
||
- `distance_to_beacon` computed via Manhattan distance.
|
||
- The initial observation to each player includes:
|
||
- Maze size,
|
||
- Their visible section,
|
||
- Their current coordinates,
|
||
- Turn/round count.
|
||
|
||
---
|
||
|
||
## 7. Validation and Error Handling
|
||
|
||
An action is **invalid** if:
|
||
|
||
| Condition | Handling Reason |
|
||
|------------|----------------|
|
||
| Does not match regex grammar | `"UnrecognizedActionFormat"` |
|
||
| MOVE attempts to go into wall | `"BlockedByWall"` |
|
||
| MOVE attempts to exit outer boundary | `"OutOfBounds"` |
|
||
| Player acts out of turn | `"NotYourTurn"` |
|
||
| Any other malformed content (including missing `\boxed{}`) | `"MalformedInput"` |
|
||
|
||
`set_invalid_move` will record the offending action and reason, skip movement effect, and mark that player's turn as consumed.
|
||
|
||
When parsing input, the text inside `\boxed{}` is extracted via `_extract_answer_content(action)` and matched against grammar.
|
||
|
||
---
|
||
|
||
## 8. Terminal Conditions and Scoring
|
||
|
||
**Terminal Checks (in order executed after each action):**
|
||
|
||
1. **Beacon Reached:** If active player's `position == beacon_coord`, set:
|
||
- `terminated = True`
|
||
- `winner = active_player`
|
||
- `termination_reason = "BeaconCaptured"`
|
||
2. **Turn Limit Reached:**
|
||
If `turn_number >= turn_limit`:
|
||
- Compute Manhattan distances.
|
||
- Player with smaller distance wins (`termination_reason = "TimeExpired"`).
|
||
- Equal distance = `"Draw"`; `winner=null; terminated=true`.
|
||
|
||
**Scoring:**
|
||
|
||
- Winner earns `score = 1`
|
||
- Loser earns `score = 0`
|
||
- Both = `0.5` if draw
|
||
|
||
---
|
||
|
||
## 9. Player Prompt Specification
|
||
|
||
### Prompt Outline
|
||
|
||
Each player's prompt presents their current status and available actions.
|
||
|
||
- **Header Identity:**
|
||
“You are an explorer in *MazeBound*, a turn-based labyrinth navigation game. Your goal is to reach the Beacon Core before your opponent.”
|
||
|
||
- **Current Info:**
|
||
- Your coordinates and visible surrounding cells.
|
||
- Number of turns remaining.
|
||
- History of your previous actions.
|
||
|
||
- **Allowed Actions:**
|
||
- `MOVE:N`, `MOVE:S`, `MOVE:E`, `MOVE:W`
|
||
- `SCAN`
|
||
- `PASS`
|
||
|
||
- **Rules Summary:**
|
||
- Movement blocked by walls or edges.
|
||
- `SCAN` reveals nearby cells.
|
||
- Game ends when anyone reaches Beacon Core or turn limit hits.
|
||
- Use `\boxed{}` to provide your exact action.
|
||
|
||
### Example Turn Prompts
|
||
|
||
```
|
||
Example valid response:
|
||
From what I can see, east looks clear. I'll move there.
|
||
\boxed{MOVE:E}
|
||
|
||
Example invalid response:
|
||
I think I’ll go north quickly!
|
||
(Missing box and token structure)
|
||
```
|
||
|
||
### `_extract_answer_content`
|
||
A helper will extract the plain text string inside `\boxed{...}` so the system sees `"MOVE:E"`, `"SCAN"`, etc., for validation and processing.
|
||
|
||
---
|
||
|
||
## 10. API Mapping Plan
|
||
|
||
### `reset(seed=None)`
|
||
- Initialize maze, beacon, players, visibility, and history.
|
||
- Store seed for future reproducibility.
|
||
- Return the initial observation for Player A.
|
||
|
||
### `step(player_id, action)`
|
||
- Extract content from `\boxed{}`.
|
||
- Validate the action; if invalid → `set_invalid_move`.
|
||
- If valid, update player’s position or visibility:
|
||
- For `MOVE`, update coordinates.
|
||
- For `SCAN`, update `visible_cells`.
|
||
- For `PASS`, do nothing but advance turn.
|
||
- Append entry to `history`.
|
||
- Check terminal conditions.
|
||
- Return new `game_state` slice and observation for next player.
|
||
|
||
### `_generate_player_prompt(player_id)`
|
||
- Construct textual prompt as in Section 9.
|
||
- Use `game_state` to render visible environment and turn status.
|
||
- Return prompt string for the chosen player.
|
||
|
||
---
|
||
|
||
## 11. Copy-Check Against the Example
|
||
|
||
- **Theme and Entities:** Maze exploration with explorers and a beacon — **completely distinct** from any negotiation or trading example.
|
||
- **Objective:** Spatial navigation victory, **no discussion or offers**.
|
||
- **Resources:** Maze grid and visibility cells — **not items, money, or agreements**.
|
||
- **Game State Keys:** `maze_layout`, `beacon_coord`, `visible_cells`, etc., are newly invented for this domain.
|
||
- **Prompt Text:** Refers strictly to navigating a labyrinth, not negotiation.
|
||
- **Conclusion:** All systems, terms, and gameplay goals are original to the **MazeBound** design and unrelated to any example.
|
||
|
||
---
|
||
|
||
**End of Design Document** |