3.8 KiB
SudokuKiller — technické poznámky
Hlavní skripty
| Skript | Popis |
|---|---|
stahni_killer_structured.py |
Stáhne strukturovaná data (cage definice + řešení) z dailykillersudoku.com do MySQL tabulky puzzles. Průběžně ukládá zálohu do killer_structured_data.json |
vykresli_killer_sudoku.py |
Vygeneruje PDF z dat v MySQL — Killer Sudoku zadání + řešení, vektorové, vzhledem identické s originálem z webu |
Ostatní (stará pipeline s PDF bloby, průzkumné skripty, testovací PDF) je v podadresáři Testy/.
Zdroj dat
Web: https://www.dailykillersudoku.com/
Každý puzzle má stránku /puzzle/{N} s inline JSON daty v HTML:
DKS.puzzle = new DKS.Puzzle({
"id": 376,
"date": "2009-05-04",
"difficulty": 4,
"board_base64": "AZoACQAE...",
"solution_base64": "AJoICQIG...",
"puzzle_type": 1
})
Dekódování base64
board_base64
- 2 bajty header (puzzle_type, flags)
- 81 × 2 bajty = 162 bajtů — cage ID pro každou buňku (uint16 big-endian)
- N bajtů — součet pro každou klec (1 bajt = max 255)
solution_base64
- 2 bajty header
- 81 bajtů — čísla řešení (řádek po řádku)
Typy puzzle
| puzzle_type | game_type v DB | Popis |
|---|---|---|
| 1 | killer_sudoku |
Killer Sudoku — klece se součty |
| 2 | killer_sudoku_gt |
Greater-Than Killer Sudoku — klece + nerovnosti |
Obtížnost
Škála 1–10 (z webu), uložena v difficulty.
MySQL — sdílená tabulka puzzles
Strukturovaná data:
game_type='killer_sudoku'/'killer_sudoku_gt'difficulty='1'až'10'puzzle= klece ve formátusum,r0c1r0c2|sum,r3c4r3c5|...(VARCHAR(1000))solution= flat string 81 číslic (VARCHAR(1000))extra={"grid_size": 9, "puzzle_number": 376, "original_difficulty": 4}source='dailykillersudoku.com'
Pozor: puzzle a solution byly původně VARCHAR(200) — nedostačovalo, cage stringy mají až ~500 znaků. Sloupce rozšířeny na VARCHAR(1000).
Stav stažených dat
- ~28 700 puzzlů (1–31 416)
- Killer Sudoku: ~17 200, Greater-Than: ~11 500
- Zdrojová data v
killer_structured_data.json(záloha pro případ MySQL chyby)
PDF rendering — pořadí vrstev
Klíčové pro vzhled identický s originálem z webu (vykresli_killer_sudoku.py):
- Bílé pozadí
- Čísla řešení (jen pro řešovou variantu, šedě)
- Tečkované ohraničení klecí — odsazené dovnitř buněk o
cell * 0.10, slévání segmentů v rámci stejné klece (jedenc.line()přes víc buněk → pattern teček neresetuje) - Tenká plná mřížka — všechny řádky/sloupce, šedě (překryje přesahy tečkovaných v křížení)
- Tlusté čáry 3×3 + obvod, černě
- Popisky součtů — bíle podsvícené, ArialBold
Vnější vs vnitřní rohy klecí
Při slévání tečkovaných segmentů endpoints buďto zkrátit o inset (vnější roh) nebo prodloužit o inset (vnitřní roh — kde klec zahýbá L-tvarem).
Detekce: pro horizontální segment top borderu od sloupce s do co (exclusive):
- Levý konec vnitřní roh =
cage_map[r][s-1] == cid→ prodloužit - Pravý konec vnitřní roh =
cage_map[r][co] == cid→ prodloužit
Bez tohoto fixu se na vnitřních rozích L-tvarů objevují viditelné mezery.
Závislosti
requests— HTTP fetch (bez Playwright, data jsou inline v HTML)reportlab— PDF generation (vektorová grafika)tqdm— progress barmysql_db(lokální Knihovny) — DB připojení
Použití
# Stažení dat (s pokračováním z JSON pokud existuje)
python stahni_killer_structured.py --run
# Pouze import už stažených JSON dat do MySQL
python stahni_killer_structured.py --import
# Vygenerování PDF pro puzzle 31414
python vykresli_killer_sudoku.py