# Go Games Collection

*[Read this in English](README.en.md)*

Коллекция консольных карточных игр и настольных игр на Go с текстовым интерфейсом (TUI) на [Bubble Tea](https://github.com/charmbracelet/bubbletea). Играете против ботов (кроме пасьянса — он на одного) прямо в терминале.

```
  ____  ___     ____    _    __  __ _____ ____
 / ___|/ _ \   / ___|  / \  |  \/  | ____/ ___|
| |  _| | | | | |  _  / _ \ | |\/| |  _| \___ \
| |_| | |_| | | |_| |/ ___ \| |  | | |___ ___) |
 \____|\___/   \____/_/   \_\_|  |_|_____|____/
  ____ ___  _     _     _____ ____ _____ ___ ___  _   _
 / ___/ _ \| |   | |   | ____/ ___|_   _|_ _/ _ \| \ | |
| |  | | | | |   | |   |  _|| |     | |  | | | | |  \| |
| |__| |_| | |___| |___| |__| |___  | |  | | |_| | |\  |
 \____\___/|_____|_____|_____\____| |_| |___\___/|_| \_|
```

## Игры в коллекции

| Игра | Игроков | Особенности |
|---|---|---|
| **Тонк (Tonk)** | 1 человек + 3 бота | Денежная система: капитал, ставка, банкротство и замена бота |
| **Дурак (Durak)** | 2–6 | Полноценное подкидывание любым игроком (не только атакующим) |
| **Блэкджек (Blackjack)** | 1–6 (можно соло) | Каждый играет против дилера отдельно, hit/stand/double |
| **101** | 2–6 | Избавься от карт первым; выбывание по достижении 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 уровня сложности |
| **Техасский Холдем (Texas Hold'em)** | 2-6 игроков | Полноценный турнир No-Limit с выбыванием и сайд-потами; уровень каждого бота назначается случайно |

Каждая игра — со своим набором специально подобранных упрощений там, где у оригинала слишком много вариантов правил (например, «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        # подробный вывод по каждому тесту
```

В пакете 786 тестов: юнит-тесты игровой логики (раздача, ходы, подсчёт очков, крайние случаи вроде взятия дамкой, марьяжа на первой взятке, рокировки под шахом или связанной фигуры, реальной диаграммы ко в Го, хорды в Сапёре, полной прохождимости всех 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 не реализовано — источники расходятся в этом нюансе, выбран более простой вариант (промах просто не даёт снять шашку).
- **Техасский Холдем** — блайнды фиксированы (без роста по ходу турнира); короткий олл-ин рейзом меньше полного размера предыдущего рейза, по строгим турнирным правилам, не должен заново открывать торги уже походившим игрокам — эта игра такого разграничения не делает. Боты не используют честного GTO-решателя — оценка силы руки методом Монте-Карло плюс шансы банка, не идеальная игра.
