143 lines
5.5 KiB
Python
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() |