go_games_collection/README.md

159 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Go Games Collection
*[Read this in English](README.en.md)*
Коллекция консольных карточных игр и настольных игр на Go с текстовым интерфейсом (TUI) на [Bubble Tea](https://github.com/charmbracelet/bubbletea). Играете против ботов (кроме пасьянса — он на одного) прямо в терминале.
```
____ ___ ____ _ __ __ _____ ____
/ ___|/ _ \ / ___| / \ | \/ | ____/ ___|
| | _| | | | | | _ / _ \ | |\/| | _| \___ \
| |_| | |_| | | |_| |/ ___ \| | | | |___ ___) |
\____|\___/ \____/_/ \_\_| |_|_____|____/
____ ___ _ _ _____ ____ _____ ___ ___ _ _
/ ___/ _ \| | | | | ____/ ___|_ _|_ _/ _ \| \ | |
| | | | | | | | | | _|| | | | | | | | | \| |
| |__| |_| | |___| |___| |__| |___ | | | | |_| | |\ |
\____\___/|_____|_____|_____\____| |_| |___\___/|_| \_|
```
## Игры в коллекции
| Игра | Игроков | Особенности |
|---|---|---|
| **Тонк (Tonk)** | 1 человек + 3 бота | Денежная система: капитал, ставка, банкротство и замена бота |
| **Дурак (Durak)** | 26 | Полноценное подкидывание любым игроком (не только атакующим) |
| **Блэкджек (Blackjack)** | 16 (можно соло) | Каждый играет против дилера отдельно, hit/stand/double |
| **101** | 26 | Избавься от карт первым; выбывание по достижении 101 очка |
| **1000 (Тысяча)** | строго 3 | Торги, прикуп, взятки и марьяжи с динамическим козырем |
| **Косынка (Klondike)** | 1 (без ботов) | Классический пасьянс с отменой хода |
| **Шашки (Checkers)** | 1 человек + бот | Русские шашки, бот на минимаксе с 2 уровнями сложности |
| **Шахматы (Chess)** | 1 человек + бот | Полные правила: рокировка, взятие на проходе, мат/пат; бот на минимаксе с 2 уровнями сложности |
| **Трупные батончики (Corpse-Starch Box)** | 1 (без ботов) | Инкрементальная игра в духе Candy Box 2, антураж Warhammer 40000; единственная игра коллекции с сохранением на диск |
| **Го (Go)** | 1 человек + бот | Доска 9x9/13x13/19x19 на выбор, 3 уровня сложности эвристического бота, площадной подсчёт очков |
| **Сапёр (Minesweeper)** | 1 (без ботов) | Классические пресеты (Новичок/Любитель/Эксперт), гарантированно безопасный первый ход, хорда |
| **Странник (Wayfarer)** | 1 (без ботов) | Текстовая космоторговля в духе Elite: 512 систем, торговля, пошаговый бой, 8 сюжетных квестов; сохранение на диск |
| **Крестики-нолики (Tic-Tac-Toe)** | 1 человек + бот | 3 уровня сложности, включая непобедимый (полный перебор) |
| **Нарды (Nardy)** | 1 человек + бот | Короткие или длинные нарды на выбор, 3 уровня сложности бота |
| **Игра Ур (Royal Game of Ur)** | 1 человек + бот | Одна из древнейших настольных игр (~2600 до н.э.), реконструкция правил Финкеля, 3 уровня сложности |
| **Сенет (Senet)** | 1 человек + бот | Древнеегипетская игра (~3500 до н.э.), консолидированная реконструкция правил, 3 уровня сложности |
Каждая игра — со своим набором специально подобранных упрощений там, где у оригинала слишком много вариантов правил (например, «1000» реализована только на троих, а Дурак — без «тузового марьяжа» и бочки). Полный список правил и упрощений — в разделе «Правила» самого приложения или через `--help`.
## Запуск
Требуется Go 1.22+.
```bash
go run . # открыть меню коллекции
go run . --help # показать правила всех игр, не заходя в TUI
go run . -sim # headless-симуляция ботов Тонка (для проверки баланса)
go run . -sim-durak # то же для Дурака
go run . -sim-blackjack # то же для Блэкджека
go run . -sim-101 # то же для 101
go run . -sim-1000 # то же для Тысячи
```
Или собрать бинарник:
```bash
go build -o games .
./games
```
## Язык интерфейса
При первом запуске (и в любой момент позже — через пункт «Язык / Language» в главном меню) можно выбрать русский или английский. Меняется весь интерфейс: меню, экраны настроек, подсказки и сообщения в каждой из 12 игр, тексты правил и имена ботов. Для CLI-режима язык правил задаётся явно: `--help` — русский, `--help-en` — английский.
## Общее управление в меню
- `↑↓` / `k j` — навигация по пунктам меню
- `enter` — выбрать / подтвердить
- `esc` / `q` — назад
- Внутри игры `q` всегда возвращает в меню (не закрывает программу); `ctrl+c` закрывает приложение целиком
У части игр перед стартом есть экран настроек: ставка и капитал (Тонк), число игроков (Дурак, 101), число игроков + ставка (Блэкджек), уровень сложности бота (Шашки).
Управление в конкретной игре не дублируется здесь — оно всегда показано внизу экрана самой игры, а также доступно целиком через пункт «Правила» в меню или `--help`.
## Структура проекта
Каждая игра — самостоятельный набор из 3 файлов (движок / бот / TUI) плюс тесты; общая для всех инфраструктура (меню, карты, колода) вынесена отдельно.
```
card.go, deck.go — общие типы карт и стандартная колода на 52 карты
menu.go, banner.go — главное меню, ASCII-баннер, экраны настроек игр
rules.go — тексты правил всех игр (для TUI и --help)
main.go — точка входа, флаги -sim-*, --help
game.go, bot.go, — Тонк: движок, боты трёх уровней сложности,
bot_heuristics.go, банкротство и замена бота, TUI
tui.go, player.go,
meld.go
durak_*.go — Дурак: движок с полным подкидыванием, бот, TUI
blackjack_*.go — Блэкджек: движок дилера, бот, TUI
oneohone_*.go — 101: движок, бот, TUI
thousand_*.go — 1000: движок торгов/взяток/марьяжей, бот, TUI
klondike_*.go — Косынка: движок пасьянса с отменой хода, TUI
(ботов нет — играть некому, кроме человека)
checkers_*.go — Шашки: движок русских шашек, бот на минимаксе, TUI
chess_*.go — Шахматы: движок с рокировкой/взятием на проходе, бот на минимаксе, TUI
corpsestarch_*.go — Трупные батончики: инкрементальный движок с открытием
разделов по накоплению ресурса, TUI на реальном времени,
сохранение/загрузка в JSON (единственная игра коллекции
с прогрессом между запусками; без ботов)
go_*.go — Го: движок с группами/свободами/правилом ко/площадным
подсчётом очков, эвристический бот на 3 уровня сложности
(без поиска вперёд — честная сильная игра требует
Monte-Carlo/нейросети), доска 9x9/13x13/19x19 на выбор, TUI
minesweeper_*.go — Сапёр: движок с гарантированно безопасным первым ходом,
каскадным открытием и хордой, три классических пресета
размера поля (без ботов)
wayfarer_*.go, — Странник: текстовая космоторговля (галактика/торговля/
translations_wayfarer*.go бой/квесты), вдохновлена Elite, но не копирует её; 8
сюжетных квестов с ветвлениями, сохранение на диск
(без ботов — соперники внутри игры не постоянные, а
разовые встречи в пути); wayfarer_quest_loader.go
умеет подгружать дополнительные квесты из .yaml
файлов в директории quests/ — см. example_quests/
third_party/yaml.v3 — библиотека разбора YAML (github.com/go-yaml/yaml),
вручную вендорена локально из-за сетевых ограничений
песочницы на обычный Go-прокси (go.mod ссылается на
неё через replace)
*_test.go — тесты (юнит-тесты правил + стресс-симуляции
полных партий ботами)
```
## Тестирование
```bash
go test ./... # весь пакет
go test ./... -v # подробный вывод по каждому тесту
```
В пакете 726 тестов: юнит-тесты игровой логики (раздача, ходы, подсчёт очков, крайние случаи вроде взятия дамкой, марьяжа на первой взятке, рокировки под шахом или связанной фигуры, реальной диаграммы ко в Го, хорды в Сапёре, полной прохождимости всех 8 квестов Странника) и отдельные стресс-тесты, прогоняющие сотни-тысячи симулированных партий ботами подряд — они специально написаны, чтобы ловить редкие зависания, потерю/дублирование карт и прочие тонкие баги, которые не всегда видны в единичном ручном тесте.
## Известные упрощения
У традиционных карточных игр обычно много региональных вариантов правил. Там, где выбор был сделан осознанно (а не по ошибке), это явно прокомментировано в соответствующем `*_game.go` и продублировано в тексте правил игры. Коротко:
- **Дурак** — полные правила (подкидывать может любой игрок, не только атакующий).
- **101** — туз пропускает ход, 6/7/пиковый король дают штрафные карты; десятка не меняет направление хода. Дама кладётся на что угодно и позволяет назвать масть для следующего хода; восьмёрку обязательно нужно покрыть той же масти картой или другой восьмёркой (цепочка), иначе — брать из колоды, пока не найдётся подходящая.
- **1000** — только на 3 игроков (у игры вдвоём/вчетвером другая механика прикупа и сдающего). Реализованы пять дополнительных договорённостей: бочка (880 очков, 3 попытки, штраф 120), золотой кон (первые 3 раздачи матча — очки соперников удвоены), самосвал (точное попадание в ±555 очков обнуляет счёт — не общий потолок), тузовый марьяж (все 4 туза, 200 очков, козырь не меняется), игра втёмную (фиксированная заявка 120 без торгов, всё удвоено). У всех пяти — заметные региональные разночтения; выбран один конкретный распространённый вариант каждой, подробности — в тексте правил игры.
- **Косынка** — добор по одной карте, неограниченные пересдачи; возврата карт с фундамента в игру нет. Между колоннами можно переносить как всю собранную последовательность, так и любую её часть с конца (число карт регулируется стрелками ↑/↓ после выбора колонны-источника).
- **Шашки** — русские правила (взятие в любом направлении простой шашкой, «летающая» дамка), без официальных 15/30-ходовых правил ничьей — вместо них простой лимит в 60 полуходов без взятий.
- **Шахматы** — полные правила, включая рокировку (с проверкой атакованных полей) и взятие на проходе; превращение пешки всегда автоматически в ферзя (без выбора фигуры); троекратное повторение позиции не реализовано — вместо него упрощённый лимит по числу полуходов без взятий/ходов пешками.
- **Трупные батончики** — не карточная игра, а инкрементальный (idle/clicker) жанр в духе Candy Box 2, переосмысленный в антураже мрачного далёкого будущего; единственная игра коллекции с сохранением на диск (автоматически каждые 15 секунд и при выходе), с честным начислением пассивного дохода за время, пока партия была закрыта.
- **Го** — базовые правила (свободы, взятие, самоубийственный ход, простое ко) реализованы полностью; НЕ реализованы: фаза удаления мёртвых камней перед подсчётом (нужно реально взять безнадёжные камни соперника до двух пасов подряд, иначе счёт будет неверным) и тройное повторение позиции (супер-ко). Бот на всех трёх уровнях сложности — эвристический, без поиска вперёд по дереву партии: честная сильная игра в Го требует Monte-Carlo поиска или нейросетевой оценки позиции, что выходит за рамки этого проекта.
- **Сапёр** — первый ход гарантированно безопасен не только сам по себе, но и все его соседи (чуть щедрее классического правила, где исключается только сама кликнутая клетка) — сделано специально, чтобы первый ход обычно сразу открывал заметную область, а не голую цифру.
- **Странник** — вдохновлён Elite, но сознательно не копирует её: собственный (не побайтовый) алгоритм генерации галактики, честного 3D-полёта в реальном времени нет — перелёты и опасные встречи разрешаются текстом с выбором вместо полёта в кокпите. Название и вся терминология авторские, чтобы не пересекаться с товарным знаком Elite. Пасхалка: как и в оригинале, где числа генератора можно было поменять в коде, здесь всю галактику можно перегенерировать заново, создав `.env` рядом с исполняемым файлом со строкой `WAYFARER_GALAXY_SEED=<число>` — без правки кода коллекции. Помимо 8 встроенных квестов можно добавлять собственные через `.yaml` файлы в директории `quests/` — см. `example_quests/lost_satellite.yaml` за примером и подробным описанием формата. Межгалактический прыжок — по явным координатам (галактика + номер системы), а не случайный, с превью цели ещё до вылета. Бой: два вида ракет (обычные и самонаводящиеся) в дополнение к лазеру, тепловые ловушки против самонаводящихся, уклонение от обычных, и симметричные направленные щиты (нос/хвост/левый борт/правый борт) — как у игрока, так и у врага; атака теперь прицельная (выбираете, в какой из четырёх щитов врага бить), а подсказка о том, откуда заходит враг для следующего удара, показывается заранее и сужает вероятные направления его атаки.
- **Нарды** — реализован один конкретный, распространённый набор правил каждого варианта (короткие и длинные); куб удвоения ставок не реализован, особое правило снятия двух шашек с головы первым ходом при некоторых дублях (встречается в части сводов правил длинных нард) не реализовано, ограничение на полную блокировку всех 15 шашек соперника шестью подряд занятыми пунктами тоже не реализовано отдельной проверкой — регионы расходятся даже в этом.
- **Игра Ур** — реализована реконструкция Ирвинга Финкеля; другие историки (Мастерс, Мюррей) предлагают иной путь по доске — конкурирующая реконструкция, не единственно верная.
- **Сенет** — подлинные правила игры не сохранились ни в одном источнике; реализована одна консолидированная реконструкция (по Кендаллу и Жекье) из нескольких существующих. Правило "перелёт с отскоком назад" на клетках 28/29/30 не реализовано — источники расходятся в этом нюансе, выбран более простой вариант (промах просто не даёт снять шашку).