Gerador de caça-palavras
Fonte da imagem: The Word Search
Motivação
Este desafio surgiu da necessidade de criar alguns jogos para crianças, com palavras específicas.
Ao invés de sair à caça de algum site que faça isso automaticamente, pensei em desenvolver eu mesmo a minha solução.
Este código gera uma matriz de letras que pode ser utilizado para montar o caça-palavras.
Atualmente, o código posiciona as palavras horizontalmente (da esquerda para a direita) e verticalmente (de cima para baixo).
Código
Python
"""
Caça Palavras
"""
import itertools
import random
import string
from typing import List
class Tabuleiro:
"""Tabuleiro de Caça-palavras
"""
def __init__(self, palavras: List[str], width: int = 0, height: int = 0):
"""Inicializa o tabuleiro com as palavras escolhidas.
Largura e Altura são automaticamente detectadas"""
self.palavras = [p.upper().strip() for p in palavras]
max_length = (
max((len(p) for p in self.palavras)) + 6
if palavras
else max(width, height)
)
self.width = max(max_length, width)
self.height = max(max_length, height)
random.seed()
random.shuffle(self.palavras)
self.chars = [' ']*self.width*self.height
horizontal = True
for palavra in self.palavras:
if self._try_put_word(palavra, horizontal):
horizontal = not horizontal
else:
self._try_put_word(palavra, not horizontal)
if self.palavras:
self._fill_empty_chars()
def _can_put_word_at(self, word: str, x: int, y: int, horizontal: bool) -> bool:
"""Verifica se uma palavra pode ser inserida na linha ou coluna
em espaços livres ou com caracteres compartilhados com outras
palavras"""
if (horizontal and x+len(word) >= self.width) or (not horizontal and y+len(word) >= self.height):
return False
for index, c in enumerate(list(word)):
e = self._get_char(
x+index, y) if horizontal else self._get_char(x, y+index)
if e not in [' ', c]:
return False
return True
def _try_put_word(self, word: str, horizontal: bool) -> bool:
"""Tenta inserir uma palavra no tabuleiro, procurando por uma
posição disponível"""
cols = list(range(self.width-len(word)))
random.shuffle(cols)
rows = list(range(self.height-len(word)))
random.shuffle(rows)
for col, row in itertools.product(cols, rows):
if self._can_put_word_at(word, col, row, horizontal):
self._put_word_at(word, col, row, horizontal)
return True
return False
def _fill_empty_chars(self):
"""Preenche os espaços vazios com caracteres aleatórios"""
for index, c in enumerate(self.chars):
if c == ' ':
self.chars[index] = random.choice(string.ascii_uppercase)
def _put_word_at(self, word: str, x: int, y: int, horizontal: bool):
"""Insere uma palavra na posição informada"""
for index, c in enumerate(list(word)):
if horizontal:
self._set_char(x+index, y, c)
else:
self._set_char(x, y+index, c)
def _set_char(self, x: int, y: int, c: str):
"""Define um caractere na tabela"""
self.chars[y*self.width+x] = c[0] if c else ' '
def _get_char(self, x: int, y: int) -> str:
"""Obtém um caractere da tabela"""
return self.chars[y*self.width+x]
def _get_row(self, y: int) -> str:
"""Obtém uma linha da tabela"""
return ''.join([self._get_char(x, y) for x in range(self.width)])
def __str__(self) -> str:
return '\n'.join([self._get_row(y) for y in range(self.height)])
Uso
Python
from caca_palavra.tabuleiro import Tabuleiro
tabuleiro = Tabuleiro([
'nome', 'endereço', 'bairro', 'cidade',
'estado', 'país', 'casa', 'camelo',
'amarelo', 'bacana', 'guionardo'
], 20, 20)
print(tabuleiro)
Saída
Text Only
JUWYHAYNCYAEHERGDQDQ
OVMKRJWGJBLAMARELOKT
WJRPNXOFWLWTZCIDADEY
ESTADOLMZGGVDBWESWQT
ALORBACANATXOKBNLGMC
JJWRDRPCWRPQLKJOOYNT
DKFWCEFAMHOTAVXMOIYL
PNNPFMEMDELWXABEYVYA
MNPAÍSTEPFAJGKYNHPRH
TLRKMZNLKTGUIONARDOJ
TXGYTWOOPFACAPYKYVJU
YEKQCOHIDGERGCBVDLCZ
LRKTTUUBYKNKAFTJGQSS
EIAXTHRHBXDQNLJMXSGQ
VXSPORCWACESHJVGEUTM
WIAWYMKTIARWRSEQXONS
RLGJVFITRSETDUWBSACL
VVBTETWGRAÇXEKHLQHIA
ISVCQYZWOQOXXZUOHAIM
UYIZVVXGKSISTUGAULON
Last update:
September 18, 2024
Created: September 18, 2024
Created: September 18, 2024