thermoprint-homework/jobs/chess_puzzle.py
2025-12-23 14:03:21 +01:00

86 lines
2.7 KiB
Python

import random
try:
import chess
except ImportError:
chess = None
from .base import Job
class ChessPuzzleJob(Job):
def get_name(self):
return "SACHOVE ULOHY"
def print_body(self, p):
if chess is None:
p.text("CHYBA: Neni nainstalovana knihovna 'chess'.\n")
p.text("Spust: pip install chess\n\n")
return
fen, instruction, solution = self.generate_puzzle()
p.text(f"{instruction}\n\n")
self.print_board(p, fen)
p.text("\n")
p.text("Legenda: K=Kral, Q=Dama, R=Vez\n")
p.text(" B=Strelec, N=Jezdec, P=Pesec\n")
p.text(" (Velka=Bily, mala=Cerny)\n\n")
p.text("Reseni (naskenuj):\n")
p.qr(solution, size=6, native=True)
def generate_puzzle(self):
"""
Simulates a random game until a 'Mate in 1' situation arises.
"""
while True:
board = chess.Board()
# Play up to 120 ply (60 moves)
for _ in range(120):
if board.is_game_over():
break
legal_moves = list(board.legal_moves)
random.shuffle(legal_moves)
# Check if any move leads to immediate checkmate
for move in legal_moves:
board.push(move)
if board.is_checkmate():
# Found a puzzle!
board.pop() # Revert to state before mate
solution = board.san(move)
turn = "Bily" if board.turn == chess.WHITE else "Cerny"
return board.fen(), f"{turn} na tahu. Mat jednim tahem.", solution
board.pop()
# No mate found, play a random move to progress the game
if legal_moves:
board.push(random.choice(legal_moves))
else:
break
def print_board(self, p, fen):
board_str = fen.split(' ')[0]
rows = board_str.split('/')
# Center the board
p.set(align='center')
# Top border
p.text(" +-----------------+\n")
for i, row in enumerate(rows):
rank = 8 - i
line = f"{rank} | "
for char in row:
if char.isdigit():
count = int(char)
line += ". " * count
else:
line += f"{char} "
line += "|\n"
p.text(line)
p.text(" +-----------------+\n")
p.text(" a b c d e f g h\n")
p.set(align='left')