Files
ordinaceprojekt/SběrDatRůzné/SudokuKiller/NOTES.md
T
Vladimir Buzalka c083e8e79a notebookvb
2026-05-08 22:38:36 +02:00

108 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
```javascript
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 110 (z webu), uložena v `difficulty`.
## MySQL — sdílená tabulka `puzzles`
Strukturovaná data:
- `game_type` = `'killer_sudoku'` / `'killer_sudoku_gt'`
- `difficulty` = `'1'``'10'`
- `puzzle` = klece ve formátu `sum,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ů (131 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`):
1. **Bílé pozadí**
2. **Čísla řešení** (jen pro řešovou variantu, šedě)
3. **Tečkované ohraničení klecí** — odsazené dovnitř buněk o `cell * 0.10`, slévání segmentů v rámci stejné klece (jeden `c.line()` přes víc buněk → pattern teček neresetuje)
4. **Tenká plná mřížka** — všechny řádky/sloupce, šedě (překryje přesahy tečkovaných v křížení)
5. **Tlusté čáry 3×3** + obvod, černě
6. **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 bar
- `mysql_db` (lokální Knihovny) — DB připojení
## Použití
```bash
# 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
```