thermoprint-homework/jobs/word_search.py
2025-12-23 23:17:27 +01:00

143 lines
5.5 KiB
Python

import random
import time
import textwrap
from jobs.czech_words import CZECH_WORDS
class WordSearchJob:
def __init__(self):
self.width = 14
self.height = 14
self.hidden_phrase = "TAJENKA"
self.words_to_find = []
self.grid = []
def get_name(self):
return "Word Search (Osmismerka)"
def configure(self):
print("\n--- Configure Word Search ---")
phrase = input("Enter hidden phrase (default: TAJENKA): ").strip().upper()
if phrase:
self.hidden_phrase = "".join(c for c in phrase if c.isalnum())
else:
self.hidden_phrase = "TAJENKA"
self.width = len(self.hidden_phrase) + 2
self.height = len(self.hidden_phrase) + 2
size = int(input(f"Enter size (default: {self.width}): ").strip())
if size:
self.width = size
self.height = size
if self.width < 5:
self.width = 5
self.height = 5
if self.width > 40:
self.width = 40
self.height = 40
def run(self, printer):
# Directions: Right, Down, Diag-Down-Right
directions = [(0, 1), (1, 0), (1, 1)]
target_empty = len(self.hidden_phrase)
# Retry loop to ensure perfect fill (no leftover letters)
for attempt in range(20):
# Initialize grid
self.grid = [['' for _ in range(self.width)] for _ in range(self.height)]
used_mask = [[False for _ in range(self.width)] for _ in range(self.height)]
# Filter words that fit in the grid
available_words = [w for w in CZECH_WORDS if len(w) <= self.width and len(w) <= self.height]
random.shuffle(available_words)
self.words_to_find = []
total_cells = self.width * self.height
current_empty = total_cells
# Try to place words until we reach target_empty
for word in available_words:
if current_empty == target_empty:
break
placed = False
attempts = 0
while not placed and attempts < 50:
attempts += 1
direction = random.choice(directions)
dr, dc = direction
# Determine bounds
if dr == 0: # Horizontal
r = random.randint(0, self.height - 1)
c = random.randint(0, self.width - len(word))
elif dc == 0: # Vertical
r = random.randint(0, self.height - len(word))
c = random.randint(0, self.width - 1)
else: # Diagonal
r = random.randint(0, self.height - len(word))
c = random.randint(0, self.width - len(word))
# Check collision
fits = True
temp_new_cells = 0
for i, char in enumerate(word):
nr, nc = r + i*dr, c + i*dc
# Cell must be empty OR contain the same letter
if self.grid[nr][nc] != '' and self.grid[nr][nc] != char:
fits = False
break
if self.grid[nr][nc] == '':
temp_new_cells += 1
if fits:
# Check if this overfills
if current_empty - temp_new_cells < target_empty:
continue
# Place it
for i, char in enumerate(word):
nr, nc = r + i*dr, c + i*dc
if self.grid[nr][nc] == '':
current_empty -= 1
self.grid[nr][nc] = char
used_mask[nr][nc] = True
self.words_to_find.append(word)
placed = True
if current_empty == target_empty:
break
# Fill remaining spots with hidden phrase
empty_slots = []
for r in range(self.height):
for c in range(self.width):
if not used_mask[r][c]:
empty_slots.append((r, c))
phrase_idx = 0
for r, c in empty_slots:
if phrase_idx < len(self.hidden_phrase):
self.grid[r][c] = self.hidden_phrase[phrase_idx]
phrase_idx += 1
else:
# Fill with random letters if phrase is done (extra filler)
self.grid[r][c] = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
# Print Header
printer.text("OSMISMĚRKA\n")
printer.text("Najdi slova a přečti tajenku!\n")
if current_empty != target_empty:
printer.text(f"Tajenka má {len(self.hidden_phrase)} písmen.\n")
printer.text("\n")
# Print Grid
for r in range(self.height):
line = " ".join(self.grid[r])
printer.text(line + "\n")
time.sleep(0.05)
printer.text("\nSlova k hledání:\n")
words_str = ", ".join(sorted(self.words_to_find))
printer.text(textwrap.fill(words_str, width=42) + "\n")
printer.text("\n\n")
printer.cut()