feat: complete human-vs-human gameplay end to end

This commit is contained in:
2026-08-29 21:31:21 +03:00
parent e77d9d62c7
commit 650ade2726
7 changed files with 237 additions and 13 deletions
+5 -3
View File
@@ -16,7 +16,7 @@ All numeric fields are decimal JSON integers, never strings.
| `gameId`, `version` | unsigned 32-bit integer |
| `x`, `y` | integer 09 |
| `name` | 120 scalar values, at most 80 UTF-8 bytes |
| `board` | exactly 100 ASCII cells: `0` unknown/water, `1` own ship, `2` miss, `3` hit |
| `board` | exactly 100 ASCII cells: `0` unknown/water, `1` revealed ship, `2` miss, `3` hit, `4` sunk hit |
Every state-changing request has `token` and `gameId`; they must precede any
mutation validation. A stale `gameId` is rejected as `STALE_GAME`.
@@ -66,12 +66,14 @@ The HTTP state response and WebSocket `state` event use this single 512-byte
maximum schema:
```json
{"type":"state","version":17,"gameId":4,"phase":"in_progress","mode":"human","viewer":"player1","turn":"player2","boards":["000...100 cells...","000...100 cells..."],"wins":[0,0]}
{"type":"state","version":17,"gameId":4,"phase":"in_progress","mode":"human","viewer":"player1","turn":"player2","boards":["000...100 cells...","000...100 cells..."],"wins":[0,0],"winner":null,"statistics":[[3,2,1,1],[4,1,3,0]]}
```
`boards[0]` belongs to player 1 and `boards[1]` to player 2. The presenter
replaces every unauthorized unhit ship with `0`. In `finished`, both boards may
contain `1`. No other event contains a board.
contain `1`. `winner` is `null` until `finished`, then player index `0` or `1`.
Each compact statistics tuple is `[shots,hits,misses,shipsSunk]`. No other event
contains a board.
## WebSocket