87 lines
2.7 KiB
Python
87 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
|
|
board.pop()
|
|
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') |