Files
ordinaceprojekt/SběrDatRůzné/DailySudoku/vykresli_sudoku.py
T
Vladimir Buzalka 5bfd4176e4 notebookvb
2026-05-09 08:25:18 +02:00

155 lines
4.5 KiB
Python
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.
"""
Vykreslí Sudoku puzzle do PDF z dat v MySQL tabulce puzzles.
"""
import json
import os
import sys
from pathlib import Path
sys.stdout.reconfigure(encoding="utf-8")
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "Knihovny"))
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen.canvas import Canvas
from mysql_db import connect_mysql
_fonts_dir = os.path.join(os.environ.get("WINDIR", r"C:\Windows"), "Fonts")
pdfmetrics.registerFont(TTFont("Arial", os.path.join(_fonts_dir, "arial.ttf")))
pdfmetrics.registerFont(TTFont("ArialBold", os.path.join(_fonts_dir, "arialbd.ttf")))
OUTPUT = Path(__file__).parent / "test_sudoku.pdf"
def draw_sudoku(c: Canvas, x0: float, y0: float, cell: float,
board: str, title: str = "", show_solution: bool = False,
solution: str = ""):
num_font = max(cell * 0.5, 7)
given_font = max(cell * 0.5, 7)
thin = 0.5
thick = 2.2
if title:
c.setFont("ArialBold", 12)
c.drawString(x0, y0 + 5, title)
# Bílé pozadí
c.setFillColor(colors.white)
c.rect(x0, y0 - 9 * cell, 9 * cell, 9 * cell, fill=1, stroke=0)
# Číslice
for i in range(81):
row = i // 9
col = i % 9
cx = x0 + col * cell + cell / 2
cy = y0 - (row + 1) * cell + cell * 0.3
ch = board[i]
if ch != ".":
c.setFillColor(colors.black)
c.setFont("ArialBold", given_font)
c.drawCentredString(cx, cy, ch)
elif show_solution and solution:
c.setFillColor(colors.Color(0.4, 0.4, 0.4))
c.setFont("Arial", num_font)
c.drawCentredString(cx, cy, solution[i])
# Tenké čáry
c.setStrokeColor(colors.Color(0.6, 0.6, 0.6))
c.setLineWidth(thin)
for i in range(1, 9):
if i % 3 == 0:
continue
c.line(x0, y0 - i * cell, x0 + 9 * cell, y0 - i * cell)
c.line(x0 + i * cell, y0, x0 + i * cell, y0 - 9 * cell)
# Tlusté čáry (3×3 bloky + vnější okraj)
c.setStrokeColor(colors.black)
c.setLineWidth(thick)
for i in range(0, 10, 3):
c.line(x0, y0 - i * cell, x0 + 9 * cell, y0 - i * cell)
c.line(x0 + i * cell, y0, x0 + i * cell, y0 - 9 * cell)
def generate_pdf(puzzles: list[dict], output_path: Path):
"""puzzles: difficulty, puzzle, solution, puzzle_date"""
BOARD_CM = 11
SOL_CM = 6
GAP = 1.5 * cm
page_w, page_h = A4
c = Canvas(str(output_path), pagesize=A4)
for i in range(0, len(puzzles), 2):
for j, p in enumerate(puzzles[i:i + 2]):
cell = BOARD_CM * cm / 9
board = 9 * cell
x0 = (page_w - board) / 2
y0 = page_h - 2 * cm - j * (BOARD_CM * cm + 3 * cm)
draw_sudoku(c, x0, y0, cell, p["puzzle"],
f"Sudoku {p['difficulty'].capitalize()}{p['puzzle_date']}")
c.showPage()
c.setFont("ArialBold", 14)
c.drawCentredString(page_w / 2, page_h - 2 * cm, "Řešení")
y_cursor = page_h - 3.5 * cm
for p in puzzles:
sol_cell = SOL_CM * cm / 9
sol_board = 9 * sol_cell
x0 = (page_w - sol_board) / 2
draw_sudoku(c, x0, y_cursor, sol_cell, p["puzzle"],
p["difficulty"].capitalize(), show_solution=True, solution=p["solution"])
y_cursor -= sol_board + GAP
c.showPage()
c.save()
def main():
conn = connect_mysql(database="puzzle")
cur = conn.cursor()
cur.execute(
"SELECT difficulty, puzzle, solution FROM puzzles "
"WHERE game_type='sudoku' AND puzzle_date='2026-05-08' "
"ORDER BY FIELD(difficulty, 'easy', 'medium', 'hard', 'expert') "
"LIMIT 1"
)
row = cur.fetchone()
cur.close()
conn.close()
if not row:
print("Žádná data.")
return
difficulty, board, solution = row
page_w, page_h = A4
board_cm = 11
cell = board_cm * cm / 9
board_px = 9 * cell
c = Canvas(str(OUTPUT), pagesize=A4)
# Zadání
x0 = (page_w - board_px) / 2
y0 = page_h - 2 * cm
draw_sudoku(c, x0, y0, cell, board,
f"Sudoku {difficulty.capitalize()} — 2026-05-08")
# Řešení
y0_sol = y0 - board_px - 3 * cm
draw_sudoku(c, x0, y0_sol, cell, board,
"Řešení", show_solution=True, solution=solution)
c.save()
print(f"PDF uloženo: {OUTPUT}")
if __name__ == "__main__":
main()