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