ThermalTodos/application/wordsearch_generator.py
2023-08-23 13:14:27 -04:00

232 lines
7.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#https://github.com/mast3rsoft/WordSearch/blob/master/WordSearch.py
import random
class WordSearch():
HORIZONTAL = 0
VERTICAL = 1
DIAGONAL = 2
REVHORIZONTAL = 3
REVVERTICAL = 4
REVDIAGONAL = 5
REVFLIPDIAGONA = 6
FLIPDIAGONAL = 7
DONTCARE = -100
wordPosition = {}
def __init__(self, searchWords, maxX = 20, maxY = 20):
self.maxX = maxX
self.maxY = maxY
self.grid = [] # grid is a list of list of strings (characters)
testWords = ['superhero', 'gugu','gaga','blah','vodka']
searchWords = searchWords.split(",")
if searchWords == ['']:
searchWords = testWords
self.searchWords = searchWords
for row in range(0, self.maxY):
self.grid.append([])
for column in range(0, self.maxX):
self.grid[row].append('*')
for word in searchWords:
DIR = random.randint(0, 7)
while not self.engrave(word, self.DONTCARE , self.DONTCARE , DIR):
pass
self.obfusticate()
def engrave(self, word, x, y, direction):
if len(word) == 0:
return True
# word has length > 0
# check if we need to choose random pos
if x == self.DONTCARE or y == self.DONTCARE: # cannot have one random, one fixed
while True:
y = random.randint(0, self.maxY - 1)
x = random.randint(0, self.maxX - 1)
if self.grid[y][x] == '*':
break
# check if x & y are valid
if x == self.maxX or x < 0:
return False
if y == self.maxY or y < 0:
return False
if not (self.grid[y][x] == "*" or self.grid[y][x] == word[0]):
return False
undovalue = self.grid[y][x]
undox = x
undoy = y
self.grid[y][x] = word[0]
# now need to write rest of the word
if direction == self.HORIZONTAL:
x += 1
elif direction == self.VERTICAL:
y += 1
elif direction == self.DIAGONAL:
y += 1
x += 1
elif direction == self.REVHORIZONTAL:
x -= 1
elif direction == self.REVVERTICAL:
y -= 1
elif direction == self.REVDIAGONAL:
y -= 1
x -= 1
elif direction == self.FLIPDIAGONAL:
x += 1
y -= 1
elif direction == self.REVFLIPDIAGONA:
x -= 1
y += 1
else:
print("This direction not implemented yet")
if self.engrave(word[1:], x, y, direction):
# we could do the rest, we are happy and done
return True
else:
# grrh: something didnt work, we need to undo now
y = undoy
x = undox
self.grid[y][x] = undovalue
return False
def obfusticate(self):
for row in self.grid:
for i in range(len(row)):
if row[i] == '*':
row[i] = 'abcdefghijklmnopqrstuvwxyz0123456789'[random.randint(0,25)]
def letter(self,x,y):
return self.grid[x][y]
def findWords(self, words):
for word in words:
firstLetter = word[0]
positions = None
y = 0; found = False
while y < self.maxY and not found:
x = 0
while x < self.maxX and not found:
if firstLetter == self.grid[y][x]:
positions = self.wordIsHere(word, x, y)
if positions:
found = True
break
x += 1
if not found:
y += 1
if found:
self.wordPosition[word] = positions
def wordIsHere(self,word, firstX, firstY):
maxX = self.maxX
maxY = self.maxY
# horizontal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if x == maxX or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x += 1
if found:
return positions
# vertical
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == maxY or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
y += 1
if found:
return positions
# reverse horizontal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if x == -1 or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x -= 1
if found:
return positions
# reverse vertical
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == -1 or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
y -= 1
if found:
return positions
# diagonal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == maxY or x == maxX or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x += 1
y += 1
if found:
return positions
# reverse diagonal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == -1 or x == -1 or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x -= 1
y -= 1
if found:
return positions
# flip diagonal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == -1 or x == maxX or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x += 1
y -= 1
if found:
return positions
# reverse flip diagonal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if y == maxY or x == -1 or letter != self.grid[y][x]:
found = False
break
positions.append((y, x))
x -= 1
y += 1
if found:
return positions
#
return None
# Test Progamm for WordSearch Genertator
if __name__ == '__main__':
# words = ("gugu,gaga")
# w = WordSearch(words, 10, 5)
# def printGrid(grid):
# for row in grid:
# for column in row:
# print("%s" % column, end='')
# print()
# printGrid(w.grid)
# w.findWords(words.split(','))
# print(w.wordPosition)
from wonderwords import RandomWord
r = RandomWord()
words = r.random_words(5, include_parts_of_speech=["nouns", "verbs", "adjectives"], word_max_length=16)
print(words)
w = WordSearch(','.join(words), 16, 16)
def printGrid(grid):
for row in grid:
for column in row:
print("%s " % column, end='')
print()
printGrid(w.grid)
# print(w.grid)
# w.findWords(words.split(','))
print(w.wordPosition)