You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
elifadjandnotfoundAdj: # Some shapes may not touch another when placed in their spot. It's useless to place those
142
+
ifbx>0andboard[by][bx-1] >0:
143
+
foundAdj=True
144
+
elifbx+1<widthandboard[by][bx+1] >0:
145
+
foundAdj=True
146
+
elifby>0andboard[by-1][bx] >0:
147
+
foundAdj=True
148
+
elifby+1<heightandboard[by+1][bx] >0:
149
+
foundAdj=True
150
+
else:
151
+
foundAdj=False
152
+
153
+
ifadjandnotfoundAdj:
154
+
returnFalse
155
+
156
+
forj, rinenumerate(shape):
157
+
by=y+j
158
+
fori, cinenumerate(r):
159
+
bx=x+i
160
+
161
+
ifc==1:
162
+
board[by][bx] =id
163
+
164
+
# Check for impossible areas. Done in one scan by combining areas it sees above with area's it's created by traveling from left to right
165
+
areas= {}
166
+
combines= {}
167
+
ai=-1
168
+
169
+
forj, rinenumerate(board):
170
+
fori, cinenumerate(r):
171
+
ifc==0:
172
+
left=1
173
+
up=1
174
+
175
+
ifi>0:
176
+
left=board[j][i-1]
177
+
ifj>0:
178
+
up=board[j-1][i]
179
+
elifi==0andj==0:
180
+
areas[ai] =1
181
+
board[j][i] =ai
182
+
ai-=1
183
+
continue
184
+
185
+
ifleft<0andup<0:
186
+
ifleft==up:
187
+
areas[left] +=1
188
+
else:
189
+
areas[left] +=1
190
+
combines[left] =up
191
+
192
+
board[j][i] =left
193
+
elifleft<0:
194
+
areas[left] +=1
195
+
board[j][i] =left
196
+
elifup<0:
197
+
areas[up] +=1
198
+
board[j][i] =up
199
+
else:
200
+
ai-=1
201
+
areas[ai] =1
202
+
board[j][i] =ai
203
+
204
+
# Reset our math
205
+
forj, rinenumerate(board):
206
+
fori, cinenumerate(r):
207
+
ifc<0:
208
+
board[j][i] =0
209
+
210
+
# Combine all areas
211
+
forkey, valueincombines.items():
212
+
v=value# Sometimes chains of areas may exist
213
+
whilevincombines:
214
+
v=combines[v]
215
+
216
+
areas[v] +=areas[key]
217
+
delareas[key]
218
+
219
+
# Check if any areas are "cutoff". This is a slight optimization that sometimes prevents the contuation of a search that has an obvious "hole" that can only be filled by
220
+
# an already used piece
221
+
iflen(areas) >1:
222
+
remove_shape(shape, x, y)
223
+
returnFalse
224
+
225
+
# If the area left is not a multiple of 5, then it is unsolvable.
226
+
forkey, valueinareas.items():
227
+
ifvalue<5orvalue%5!=0:
228
+
remove_shape(shape, x, y)
229
+
returnFalse
230
+
231
+
returnTrue
232
+
233
+
defremove_shape(shape, x, y):
234
+
forj, rinenumerate(shape):
235
+
fori, cinenumerate(r):
236
+
ifc==1:
237
+
board[y+j][x+i] =0
238
+
239
+
solution_stack= []
240
+
241
+
# It's safe to use a recursive search because the max depth we can go is 12.
242
+
defrecursive_search():
243
+
globalnum_steps
244
+
245
+
fori, shapeinenumerate(shapes):
246
+
ifshape["used"]:
247
+
continue
248
+
249
+
forj, variationinenumerate(shape["variations"]):
250
+
forxinrange(0, width):
251
+
foryinrange(0, height):
252
+
iftry_place_shape(variation, x, y, i+1, len(solution_stack) !=0):
Pentominos is a simple puzzle game where the goal is to fit several varying shapes of area 5 units into another shape. There are 12 unique "pentominos" that can be placed. The largest version of the game can fit 12 pentominos into a 6x10 box with a total of 2339 solutions.
0 commit comments