6 Commits
4 changed files with 73 additions and 24 deletions

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project
`kostky` is a Czech-language terminal CLI game — a Farkle/"tisícovky" dice game variant for multiple players. Single runtime dependency: `tabulate` (for the final results table).
## Commands
```bash
pip install -e ".[dev]" # editable install with mypy + ruff
kostky # run the game (after install)
python -m kostky # run without installing (requires tabulate)
mypy # type-check (strict mode, see pyproject.toml)
ruff check . # lint
```
There are no tests in this repository.
## Architecture
The entire game lives in `kostky/kostky.py` as a single module with module-level mutable state (no classes):
- `hodnoty: dict[str, int]` — scoring table, loaded at import time from `kostky/hodnoty.csv` via `importlib.resources`. Keys are sorted-digit strings representing dice combos (e.g. `"111"` = three ones), values are point totals.
- `players: dict[str, list[int]]` — per-player history of per-turn scores (insertion order == turn order).
- `aggr: dict[str, int]` — per-player running total, used for win checks and the results table.
- `pointer` / `first` — current player's name / the player who started the round (used to detect when a full round has completed in `next_player`/`check_win`).
- `score` — points accumulated *within the current turn*, reset on bust or on banking (`k`).
- `h_bool` — guards re-rolling: you can't roll again until you've banked at least one scoring combination in the current roll sequence.
Control flow is a manual state machine driven by tuples, not exceptions or return codes:
- `evaluate(inp, count, throw)` parses a single line of user input against the current dice state and returns a `data` tuple whose first element is a tag: `"count"` (continue turn with N remaining dice and a throw string), `"msg"` (show an error/message, possibly re-prompting), `"win"`, or `"exit"`.
- `game(data)` is the main loop: it pattern-matches on `data[0]`, prints state, prompts for input, and calls `evaluate` again to get the next `data` tuple. This loop is how every turn — and the whole game — progresses.
- Dice picks are entered as letters (`a`-`f` mapped to position 1-6 via `ord(x)-96`), not digit values; `evaluate` converts letters to positions internally before checking the picked dice values against `hodnoty`.
- Bust detection (`check_value`) checks whether *any* key in `hodnoty` is a substring of the sorted current throw — not a full combinatorial scoring check, so this is the single source of truth for "is this throw dead."
- Win condition (`check_win`) only fires once `pointer` cycles back to `first`, i.e. checked once per full round rather than once per turn, and only declares a winner if exactly one player is alone at/above `final_score`.
`kostky/__main__.py` and the `kostky` console-script entry point (in `pyproject.toml`) both call `kostky.kostky.main()`.
## Scoring data
`kostky/hodnoty.csv` (digit-string-of-dice-values → points) is the single source of truth for scoring and is also documented in tables in `README.md`. If you change one, update the other.
+28 -22
View File
@@ -1,25 +1,28 @@
# kostky
Textová (CLI) hra v kostky pro více hráčů – varianta klasického *Farkle*
(„tisícovky“). Běží celá v terminálu a je napsaná v čistém Pythonu bez
externích závislostí.
(„tisícovky“). Běží celá v terminálu, v Pythonu, s jedinou závislostí
(`tabulate` pro závěrečnou výsledkovou tabulku).
## Požadavky
- Python 3.7+ (hra se spoléhá na zachování pořadí klíčů ve slovníku)
- Žádné externí balíčky – používá se jen standardní knihovna
(`random`, `os`, `re`, `csv`, `collections`, `typing`)
- Python 3.9+
- Závislost `tabulate` (doinstaluje se automaticky při instalaci)
## Spuštění
## Instalace a spuštění
```bash
git clone https://gitea.spacilovi.eu/david/kostky.git
cd kostky
python main.py
pip install .
kostky
```
> Hru spouštěj z adresáře projektu – soubor `hodnoty.csv` (bodovací tabulka)
> se načítá relativní cestou vůči aktuálnímu adresáři.
Případně bez instalace (s nainstalovaným `tabulate`) přes `python -m kostky`,
nebo izolovaně jako CLI nástroj přes `pipx install .`.
> Pro vývoj: `pip install -e ".[dev]"` – editovatelná instalace včetně `mypy`
> a `ruff`.
## Jak se hraje
@@ -31,42 +34,45 @@ python main.py
### Průběh tahu
Na začátku tahu uvidíš cílové skóre, kdo je na tahu (a jeho celkové skóre)
a hod šesti kostkami s očíslovanými pozicemi:
Na začátku tahu uvidíš, kdo je na tahu (s jeho skóre a cílem), a hod šesti
kostkami s písmennými pozicemi:
```
Vítězné skóre: 10000.
Na tahu je Anna (0).
Na tahu je Anna (0/10000).
1, 5, 3, 2, 6, 4
^ ^ ^ ^ ^ ^
1 2 3 4 5 6
a b c d e f
```
Pak zvolíš jednu z akcí:
| Vstup | Akce |
| --- | --- |
| `pozice kostek` | Odložíš vybrané kostky k vyhodnocení (např. `1`, `34`, `123456`). Hodnoty na zvolených pozicích musí dohromady tvořit některou kombinaci z bodovací tabulky. |
| `pozice kostek` | Odložíš vybrané kostky k vyhodnocení – písmeny (např. `a`, `cd`, `abcdef`). Hodnoty na zvolených pozicích musí dohromady tvořit některou kombinaci z bodovací tabulky. |
| `h` | Hodíš znovu zbývajícími kostkami. Povoleno až poté, co v tomto tahu odložíš aspoň jednu bodující kombinaci. |
| `k` | Ukončíš tah, připíšeš si nasbírané skóre a předáš tah dalšímu hráči. |
| `exit` | Předčasně ukončíš celou hru. |
Odkládat můžeš i víc kombinací po sobě – po každém vyhodnocení pokračuješ se
zbývajícími kostkami a body se v rámci tahu sčítají.
### Smůla, hot dice a výhra
### Smůla, hot dice, vynulování a výhra
- **Smůla (bust):** když čerstvý hod neobsahuje žádnou bodující kombinaci,
o body z tohoto tahu přijdeš a tah přechází na dalšího hráče.
- **Hot dice:** když se ti podaří odložit všech šest kostek, dostaneš čerstvý
hod šesti kostkami a pokračuješ ve stejném tahu.
- **Výhra:** po dokončení každého kola se kontroluje, jestli někdo dosáhl
cílového skóre. Vyhrává osamocený lídr nad limitem; při shodě na první
příčce se hraje dál.
- **Vynulování:** tři po sobě jdoucí nulové tahy vynulují tvé celkové skóre.
Počet aktuálních nul se vedle skóre ukazuje jako `x` / `xx`.
- **Výhra:** po dokončení každého kola vyhrává osamocený lídr nad cílovým
skóre; při shodě na první příčce se hraje dál. Na konci se vypíše výsledková
tabulka s pořadím všech hráčů.
## Bodování
Kompletní tabulka je v souboru [`hodnoty.csv`](hodnoty.csv). Kombinace se
vyhodnocuje podle hodnot odložených kostek – na jejich pořadí nezáleží.
Kompletní tabulka je v souboru [`kostky/hodnoty.csv`](kostky/hodnoty.csv).
Kombinace se vyhodnocuje podle hodnot odložených kostek – na jejich pořadí
nezáleží.
### Stejné kostky
@@ -76,7 +82,7 @@ vyhodnocuje podle hodnot odložených kostek – na jejich pořadí nezáleží.
| **2** | – | – | 200 | 400 | 800 | 1600 |
| **3** | – | – | 300 | 600 | 1200 | 2400 |
| **4** | – | – | 400 | 800 | 1600 | 3200 |
| **5** | 50 | – | 500 | 1000 | 2000 | 4000 |
| **5** | 50 | 100 | 500 | 1000 | 2000 | 4000 |
| **6** | – | – | 600 | 1200 | 2400 | 4800 |
(„–“ = daná kombinace samostatně neboduje.)
-1
View File
@@ -24,7 +24,6 @@
444,400
2222,400
333,300
11,200
222,200
1,100
5,50
1 111111 8000
24 444 400
25 2222 400
26 333 300
11 200
27 222 200
28 1 100
29 5 50
+1 -1
View File
@@ -292,7 +292,7 @@ def game(data: tuple) -> None:
count = 6
msg: str = ("Jakou akci chcete provést?\n"
" - Zadejte kombinaci kostek k ponechání (dojde k jejich vyhodnocení): "
"[pozice kostek] (např. 1 nebo 34 nebo 123456).\n"
"[pozice kostek] (např. a nebo cd nebo abcdef).\n"
" - Hodit znovu: [h].\n"
f" - Ukončit hod a ponechat si skóre z tohoto hodu ({score}): [k].\n"
" - Ukončit hru: [exit].\n"