forked from mast3rsoft/WordSearch
-
Notifications
You must be signed in to change notification settings - Fork 1
/
WordSearch.py
213 lines (212 loc) · 6.99 KB
/
WordSearch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
import random
class WordSearch():
HORIZONTAL = 0
VERTICAL = 1
DIAGONAL = 2
REVHORIZONTAL = 3
REVVERTICAL = 4
REVDIAGONAL = 5
REVFLIPDIAGONAL = 6
FLIPDIAGONAL = 7
DONTCARE = -100
wordPosition = {}
def __init__(self, search_words, max_x = 20, max_y = 20):
self.max_x = max_x
self.max_y = max_y
self.grid = [] # grid is a list of list of strings (characters)
testWords = ['superhero', 'gugu','gaga','blah','vodka']
search_words = search_words.split(",")
if search_words == ['']:
search_words = testWords
search_words = [string.upper() for string in search_words]
self.search_words = search_words
for row in range(0, self.max_y):
self.grid.append([])
for column in range(0, self.max_x):
self.grid[row].append('*')
for word in search_words:
word_direction = random.randint(0, 7)
while not self.engrave(word, self.DONTCARE , self.DONTCARE , word_direction):
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.max_y - 1)
x = random.randint(0, self.max_x - 1)
if self.grid[y][x] == '*':
break
# check if x & y are valid
if x == self.max_x or x < 0:
return False
if y == self.max_y 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.REVFLIPDIAGONAL:
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 didn’t 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):
words = [string.upper() for string in words]
for word in words:
firstLetter = word[0]
positions = None
y = 0; found = False
while y < self.max_y and not found:
x = 0
while x < self.max_x 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):
max_x = self.max_x
max_y = self.max_y
# horizontal
found = True; x = firstX; y = firstY; positions = []
for letter in word:
if x == max_x 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 == max_y 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 == max_y or x == max_x 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 == max_x 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 == max_y 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 Program for WordSearch Generator
if __name__ == '__main__':
HIDDEN_WORDS = ("Impact,Gaga")
w = WordSearch(HIDDEN_WORDS, 10, 10)
def print_grid(grid):
for row in grid:
for column in row:
print("%s" % column, end='')
print()
print_grid(w.grid)
w.findWords(HIDDEN_WORDS.split(','))
print(w.wordPosition)