# Go Games Collection

*[Читать по-русски](README.md)*

A collection of console card and board games in Go with a text UI (TUI) built on [Bubble Tea](https://github.com/charmbracelet/bubbletea). Play against bots (except solitaire, which is single-player) right in your terminal.

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

## Games in the collection

| Game | Players | Highlights |
|---|---|---|
| **Tonk** | 1 human + 3 bots | Money system: bankroll, ante, bankruptcy and bot replacement |
| **Durak (Russian Fool)** | 2–6 | Full throw-in variant (any player can throw in, not just the attacker) |
| **Blackjack** | 1–6 (solo works too) | Everyone plays the dealer separately; hit/stand/double |
| **101** | 2–6 | Empty your hand first; reaching 101 penalty points eliminates you |
| **1000 (Thousand)** | strictly 3 | Bidding, the widow, tricks and marriages with a dynamic trump |
| **Klondike Solitaire** | 1 (no bots) | Classic solitaire with move undo |
| **Checkers** | 1 human + bot | Russian draughts, minimax bot with 2 difficulty levels |
| **Chess** | 1 human + bot | Full rules: castling, en passant, checkmate/stalemate; minimax bot with 2 difficulty levels |
| **Corpse-Starch Box** | 1 (no bots) | Incremental game in the spirit of Candy Box 2, Warhammer 40000 flavor; the only game in the collection with a save file |
| **Go** | 1 human + bot | Choice of 9x9/13x13/19x19 board, 3 heuristic bot difficulty levels, area scoring |
| **Minesweeper** | 1 (no bots) | Classic presets (Beginner/Intermediate/Expert), guaranteed-safe first click, chording |
| **Wayfarer** | 1 (no bots) | Text-based space trading inspired by Elite: 512 systems, trading, turn-based combat, 8 story quests; save file |
| **Tic-Tac-Toe** | 1 human + bot | 3 difficulty levels, including an unbeatable full-search one |
| **Nardy (Backgammon)** | 1 human + bot | Choice of short or long nardy rules, 3 bot difficulty levels |
| **The Royal Game of Ur** | 1 human + bot | One of the oldest known board games (~2600 BCE), Finkel's rule reconstruction, 3 difficulty levels |
| **Senet** | 1 human + bot | Ancient Egyptian game (~3500 BCE), a consolidated rule reconstruction, 3 difficulty levels |
| **Texas Hold'em** | 2-6 players | Full No-Limit elimination tournament with side pots; each bot's difficulty is assigned randomly |

Each game comes with its own set of deliberately chosen simplifications where the original has too many regional rule variants (for example, "1000" is only implemented for 3 players, and Durak doesn't include the "ace marriage" or barrel rule). The full list of rules and simplifications is in the app's own "Rules" section or via `--help`.

## Running it

Requires Go 1.22+.

```bash
go run .                 # open the collection menu
go run . --help          # show the rules for every game without entering the TUI
go run . -sim            # headless Tonk bot simulation (for balance testing)
go run . -sim-durak      # same, for Durak
go run . -sim-blackjack  # same, for Blackjack
go run . -sim-101        # same, for 101
go run . -sim-1000       # same, for Thousand
```

Or build a binary:

```bash
go build -o games .
./games
```

## Interface language

On first launch (and at any point afterward, via the "Язык / Language" menu item) you can choose Russian or English. This switches the entire interface: the menu, settings screens, hints and messages in each of the 12 games, rules text, and bot names. For the CLI, the rules language is set explicitly: `--help` for Russian, `--help-en` for English.

## General menu controls

- `↑↓` / `k j` — navigate menu items
- `enter` — select / confirm
- `esc` / `q` — back
- Inside a game, `q` always returns to the menu (it doesn't close the program); `ctrl+c` quits the app entirely

Some games have a settings screen before they start: ante and bankroll (Tonk), number of players (Durak, 101), number of players + bet (Blackjack), bot difficulty (Checkers).

Controls for a specific game aren't duplicated here — they're always shown at the bottom of that game's own screen, and are also available in full via the "Rules" menu item or `--help`.

## Project structure

Each game is a self-contained set of 3 files (engine / bot / TUI) plus tests; shared infrastructure (menu, cards, deck) lives separately.

```
card.go, deck.go        — shared card types and the standard 52-card deck
menu.go, banner.go      — main menu, ASCII banner, game settings screens
rules.go                — rules text for every game (for the TUI and --help)
main.go                 — entry point, -sim-* flags, --help

game.go, bot.go,        — Tonk: engine, three bot difficulty levels,
bot_heuristics.go,         bankruptcy and bot replacement, TUI
tui.go, player.go,
meld.go

durak_*.go              — Durak: engine with full throw-ins, bot, TUI

blackjack_*.go          — Blackjack: dealer engine, bot, TUI

oneohone_*.go           — 101: engine, bot, TUI

thousand_*.go           — Thousand: bidding/tricks/marriages engine, bot, TUI

klondike_*.go           — Klondike: solitaire engine with move undo, TUI
                           (no bots — there's no one else to play)

checkers_*.go           — Checkers: Russian draughts engine, minimax bot, TUI
chess_*.go              — Chess: engine with castling/en passant, minimax bot, TUI
corpsestarch_*.go       — Corpse-Starch Box: incremental engine that unlocks
                           sections as resources accumulate, real-time TUI,
                           JSON save/load (the only game in the collection with
                           progress that persists between runs; no bots)
go_*.go                 — Go: engine with groups/liberties/ko rule/area
                           scoring, heuristic bot with 3 difficulty levels
                           (no lookahead search — genuinely strong Go play
                           needs Monte Carlo/neural nets), choice of
                           9x9/13x13/19x19 board, TUI
minesweeper_*.go        — Minesweeper: engine with a guaranteed-safe first
                           move, cascading reveal and chording, three classic
                           field size presets (no bots)
wayfarer_*.go,           — Wayfarer: text-based space trading (galaxy/trading/
translations_wayfarer*.go  combat/quests), inspired by Elite but not a copy of
                           it; 8 branching story quests, save file (no bots —
                           opponents inside the game are one-off encounters
                           during travel, not persistent rivals);
                           wayfarer_quest_loader.go can load additional quests
                           from .yaml files in a quests/ directory — see
                           example_quests/
third_party/yaml.v3      — YAML parsing library (github.com/go-yaml/yaml),
                           manually vendored locally because the sandbox's
                           network restrictions block the normal Go module
                           proxy (go.mod references it via a replace directive)

*_test.go                — tests (rules unit tests + stress simulations of
                            full bot games)
```

## Testing

```bash
go test ./...           # the whole package
go test ./... -v        # verbose output for every test
```

The package has 786 tests: unit tests for game logic (dealing, moves, scoring, edge cases like king captures, a marriage on the first trick, castling out of check or a pinned piece, an actual ko diagram in Go, chording in Minesweeper, full playability of all 8 Wayfarer quests) and separate stress tests that run hundreds to thousands of simulated bot games in a row — these are specifically written to catch rare hangs, card loss/duplication, and other subtle bugs that aren't always visible in a single manual test.

## Known simplifications

Traditional card games usually have many regional rule variants. Where a choice was made deliberately (not by mistake), it's explicitly commented in the corresponding `*_game.go` file and repeated in that game's rules text. In short:

- **Durak** — full rules (any player can throw in, not just the attacker).
- **101** — an ace skips a turn, a 6/7/king of spades gives penalty cards; a 10 doesn't reverse turn order. A queen can be played on anything and lets you call a suit for the next play; an eight must be covered by a matching-suit card or another eight (chaining) — otherwise you draw from the stock until you can.
- **1000** — only for 3 players (the 2-player/4-player versions have different kitty/dealer mechanics). Five additional house rules are implemented: barrel (880 points, 3 attempts, -120 penalty), golden round (first 3 hands of the match — opponents' points doubled), dump truck/"samosval" (an exact hit on ±555 points resets the score — not a general cap), ace marriage (all 4 aces, 200 points, doesn't change trump), blind game (a fixed bid of 120 with no bidding, everything doubled). All five have noticeable regional variance; one specific, widely-used variant of each was chosen — see the in-game rules text for details.
- **Klondike** — draws one card at a time, unlimited redeals; no returning cards from the foundation back into play. You can move either the entire built sequence between columns or any portion of it from the bottom (adjust the count with ↑/↓ after selecting a source column).
- **Checkers** — Russian rules (a man captures in any direction, "flying" kings), no official 15/30-move draw rules — replaced with a simple limit of 60 half-moves without a capture.
- **Chess** — full rules, including castling (with attacked-square checks) and en passant; pawn promotion is always automatic to a queen (no piece choice); threefold repetition isn't implemented — replaced with a simplified limit on half-moves without a capture or pawn move.
- **Corpse-Starch Box** — not a card game, but an incremental (idle/clicker) genre in the spirit of Candy Box 2, reimagined in a grim far-future setting; the only game in the collection with a save file (auto-saving every 15 seconds and on quit), with an honest accrual of passive income for the time the game was closed.
- **Go** — the basic rules (liberties, capturing, suicidal moves, simple ko) are fully implemented; NOT implemented: a dead-stone-removal phase before scoring (you need to actually capture hopeless enemy stones before passing twice, or the score will be wrong) and triple position repetition (superko). The bot at all three difficulty levels is heuristic, with no lookahead search through the game tree: genuinely strong Go play requires Monte Carlo search or neural-network position evaluation, which is beyond the scope of this project.
- **Minesweeper** — the first move is guaranteed safe not just for itself but for all its neighbors too (a bit more generous than the classic rule, which only excludes the clicked cell itself) — done deliberately so the first move usually opens up a noticeable area right away instead of a single bare number.
- **Wayfarer** — inspired by Elite, but deliberately not a copy of it: its own (not byte-for-byte) galaxy generation algorithm, and no honest real-time 3D flight — travel and dangerous encounters are resolved through text with choices instead of flying a cockpit. The name and all terminology are original, to avoid overlapping with the Elite trademark. Easter egg: just like the original, where you could change the generator's seed numbers in the code, here you can regenerate the entire galaxy by creating a `.env` file next to the executable with the line `WAYFARER_GALAXY_SEED=<number>` — no code changes needed. Beyond the 8 built-in quests, you can add your own via `.yaml` files in a `quests/` directory — see `example_quests/lost_satellite.yaml` for an example and detailed format description. Intergalactic jumps use explicit coordinates (galaxy + system number) instead of a random destination, with a preview of the target before you leave. Combat: two missile types (regular and homing) alongside the laser, thermal decoys against homing missiles, dodging against regular ones, and symmetric directional shields (fore/aft/left/right) — for both you and the enemy; attacks are now targeted (you choose which of the enemy's four shields to strike), and a hint about which direction the enemy is approaching from for their next attack is shown ahead of time, narrowing down where their strike is likely to land.
- **Nardy** — one specific, widely-used ruleset is implemented for each variant (short and long); the doubling cube isn't implemented, a special rule allowing two checkers off the head on the first move with certain doubles (found in some long nardy rulesets) isn't implemented, and the restriction against fully blocking all 15 of the opponent's checkers with a six-point prime isn't enforced as a separate check either — regions disagree even on this.
- **The Royal Game of Ur** — implements Irving Finkel's reconstruction; other historians (Masters, Murray) propose a different path around the board — a competing reconstruction, not the single correct one.
- **Senet** — the original rules haven't survived in any source; one consolidated reconstruction (drawing on Kendall and Jéquier) is implemented out of several that exist. The "overshoot bounces back" rule for squares 28/29/30 isn't implemented — sources disagree on this detail, and the simpler version was chosen (missing the exact roll just doesn't let the piece bear off).
- **Texas Hold'em** — blinds are fixed (they don't increase over the tournament); under strict tournament rules a short all-in raise for less than a full raise shouldn't reopen betting for players who've already acted — this game doesn't draw that distinction. The bots don't use an honest GTO solver — hand-strength estimation via Monte Carlo simulation plus pot odds, not perfect play.
