Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
41 changes: 41 additions & 0 deletions 04-formats/Samakhvalau-Kruchkou-Mikhnyonok/chess/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Шахматы — инструкция

1. **Связь с Beagle:** состояние партии — не разрозненные файлы под каждый ресурс, а **одна логическая запись** на идентификатор игры (`id` из `?game=...`). Клиент шлёт **кусочки JSON (патчи)**; сервер **склеивает** их с уже сохранённым объектом и перезаписывает один файл.
2. **Две реплики:** можно поднять **два экземпляра** сервера; игроки заходят на **разные порты**; данные либо **общие** (одна папка на диске), либо **раздельные** с явной синхронизацией между репликами.
3. **Синхронизация:** чтобы перенести состояние на другую реплику, достаточно **обменяться содержимым этой одной записи** (GET целиком + POST объединённого состояния или вызов готового эндпоинта синка).

### REST API

| Метод | Путь | Назначение |
|--------|------|------------|
| `GET` | `/beagle/:id` | Прочитать **всё** состояние партии `id` (один JSON). Если файла ещё нет — `{}`. |
| `POST` | `/beagle/:id` | Применить **патч**: тело запроса — JSON; поля **глубоко сливаются** (`deepMerge`) с текущим файлом `games/<id>.json`; ответ — полное состояние после слияния. |
| `POST` | `/beagle/:id/sync` | Тело: `{ "url": "<полный URL GET другой реплики>" }`, например `http://localhost:3000/beagle/my_game`. Сервер **считывает** удалённый JSON, **сливает** с локальным, сохраняет и **отправляет** объединённый объект обратно `POST` на тот же `url`. |

Структура состояния (после работы клиента) включает вложенные объекты, например: `slots` (белые/чёрные сессии), `moves` (ключи вида `0001.json` → объект хода), `state` (например `version`), `undo_request` — всё это **одна** запись в одном файле.

Дополнительно в интерфейсе можно вызвать синхронизацию с другой репликой вручную: в консоли браузера — `chess.syncWithPeer()`.

### Два сервера, каждый игрок на своём

**Вариант A — общее хранилище (удобно локально):** оба процесса без `CHESS_DATA_DIR` пишут в **`games/`**. Запуск:

```bash
PORT=3000 node server.js
PORT=3001 node server.js
```

Оба открывают одну и ту же ссылку, например `http://localhost:3000/?game=demo` и `http://localhost:3001/?game=demo` — слоты и ходы видны с обоих серверов.

**Вариант B — изолированные реплики (как «два Beagle»):** у каждого процесса свой каталог:

```bash
CHESS_DATA_DIR=games_3000 PORT=3000 node server.js
CHESS_DATA_DIR=games_3001 PORT=3001 node server.js
```

Второй игрок перед выбором стороны должен **подтянуть** данные с первой реплики. URL для этого:

`http://localhost:3001/?game=demo&peer=http://localhost:3000`

При загрузке страница вызовет синхронизацию с первой репликой, после чего назначение белых/чёрных будет согласовано. Дальше периодически можно снова вызывать `chess.syncWithPeer()` или дергать `POST /beagle/:id/sync` с сервера/скриптом.
Loading