# botWebWars A FastAPI and React-based web arena featuring a real-time **64 × 64 grid** with coordinates ranging from `(0, 0)` to `(64, 64)`. Players/bots register with their name, color, and strength, remember everywhere they have been, seek other bots to form **Parties**, take turns moving around the arena, and engage in **3-bout D20 tactical battles**. --- ## Features ### 1. Bot Location Memory & Awareness - **Location Awareness**: - Every bot knows its current coordinate `(x, y)` and tracks a memory history of all coordinates it has visited. - Queryable via `GET /api/players/{player_id}/memory`. - Enables bots to remember if they have visited a location before to avoid looping and explore unvisited territory. - **Bot Seeking & Radar**: - Bots can actively seek other bots via `GET /api/players/{player_id}/radar`. - Scans for nearest friendly/neutral bots to recruit into a party, or detects enemy squads to engage in battle. ### 2. Parties & Squad Formations - **Goal & Linked Connectivity**: - Bots seek each other out to join together as a **Party**. - All party members must be within **1 distance** of each other (Chebyshev distance $\le 1$, including diagonals and cardinals), forming linked connections (clusters or single-file lines). - Bots must agree on a **Party Leader**. - **Party Strength**: - Each bot has a default **strength of 1**. - Total party strength is the sum of all bots in the party: $$\text{Party Strength} = \sum_{b \in \text{Party}} \text{bot.strength}$$ - **Leader Group Movement**: - The Party Leader controls the movement for the entire squad. - All party members translate together in the chosen direction (preserving their relative shape and linked adjacency). - If any party member's path is blocked by an outside bot or boundary wall, the entire group move is prevented. - Non-leader party members cannot move independently. ### 3. 3-Bout D20 Battle Mechanics & Scoring Rules - **Engagement**: - When two opposing parties engage (move into adjacent contact or call battle), a battle must be fought. - **3-Bout Resolution with D20 Roll Multiplier**: - Each battle consists of **3 bouts**. - In each bout, both parties roll a **20-sided die (D20)** (random number from 1 to 20). - The roll acts as a multiplier on the party's total strength: $$\text{Bout Score} = \text{Party Strength} \times \text{D20 Roll}$$ - The party with the higher bout score wins that bout. - The overall battle winner is the party that scores the higher outcome across the 3 bouts. - **Battle Scoring Rules**: - **Winning Party Leader**: Receives **+2 points**. - **Rest of Winning Party**: Each member receives **+1 point**. - **Losing Party Leader**: Receives **-1 point**, loses leadership, and respawns at a random free position. - **Rest of Losing Party**: Loses **0 points** (scores remain unchanged). - **Surrender & Absorption**: - The **remainder of the defeated party joins the winning party**! - Surviving bots have their party affiliation updated to the winning party. - The winning squad grows in size and increases its total strength, and the round continues. ### 4. Turn-Based 8-Directional Movement - **8 Directions**: - Cardinal: `UP`, `DOWN`, `LEFT`, `RIGHT` - Diagonal: `UP_LEFT`, `UP_RIGHT`, `DOWN_LEFT`, `DOWN_RIGHT` - **Collision & Wall Avoidance**: - Cannot break through boundary walls `[0..64, 0..64]`. - Cannot move into cells occupied by outside bots. --- ## REST API Endpoints ### Intelligence & Memory Endpoints - `GET /api/players/{player_id}/memory`: Retrieve a bot's current location, count of visited locations, and visited coordinates history. - `GET /api/players/{player_id}/radar`: Scan for nearby bots, calculate distances, classify allies vs enemies, and provide recommended navigation direction (`seek_join`, `engage_battle`, `explore_unvisited`). ### Party & Battle Endpoints - `POST /api/parties`: Form a party directly. - Body: `{"member_ids": ["bot_1", "bot_2"], "leader_id": "bot_1", "name": "Squadrons"}` - `GET /api/parties`: List all active parties, leaders, members, and total strength. - `POST /api/parties/{party_id}/defeat`: Trigger party defeat. - `POST /api/battles/fight`: Initiate a 3-bout D20 battle between two adjacent parties/bots. - Body: `{"challenger_id": "bot_1", "defender_id": "bot_2"}` - Awards **+2 pts** to winning leader, **+1 pt** to winning members, **-1 pt** to losing leader, **0 pts lost** for losing members, and absorbs surviving bots into the winning squad! ### Movement & Turn Endpoints - `GET /api/players/{player_id}/available-moves`: Checks availability of all 8 directions (for a solo bot or the whole party if leader). - `GET /api/players/{player_id}/check-move?direction={DIR}`: Check single direction. - `POST /api/players/{player_id}/move`: Move bot or entire party if leader. Automatically detects and resolves battles upon engagement. - `POST /api/players/{player_id}/pass`: Pass turn to next player. - `GET /api/turn`: Get current turn status, round number, and turn queue. ### Player & Board Endpoints - `POST /api/players`: Register a new player with `name`, `color`, and optional `strength` (default 1). - `GET /api/players`: List active players and their scores. - `GET /api/board`: Full board state, player positions, parties, and turn data. - `POST /api/board/reset`: Clear board, players, and parties. - `/ws`: Real-time WebSocket connection broadcasting player joins, squad movements, party formations, 3-bout D20 battles, defeats, and turn changes. --- ## Quick Start with Docker ```bash # Build and run with Docker Compose docker compose up --build ``` Open [http://localhost:8000](http://localhost:8000) in your browser. ### Running Backend Test Suite ```bash docker run --rm botwebwars:test pytest backend/tests ```