# How to use find_better_solution method in avocado

Best Python code snippet using avocado_python

SolitaireSolver.py

Source:SolitaireSolver.py

`1from PIL import ImageGrab, ImageFilter, Image, ImageDraw2import win32api, win32con3import cv24import numpy as np5import glob6from matplotlib import pyplot as plt7import time8import sys9import gc10sys.setrecursionlimit(1000)11# Rewrite from recursion to increment12## map?13## [[0,0,0],1,[2,3,4],[[5],[6],[7],[8],[9],[10],[11],[12]))14## move15## [from there, from_deep, to pos n, auto? = true\false]16## pos17## spec-button move? (0, 0, 0, False)18## 19## possible cards: 3*(1..9) + 3*4 + 120## how to store this?21## like this: (rgb = 123) (red green black :D )22## 1,1 2,1 3,123## 1,2 2,2 3,224## 1,3 2,3 3,325## ...26## 1,9 2,9 3,927## 4,-1 5,-1 6,-1 (spec cards x4)28## 7,-1 (special middle card)29## 8,-1 (card back)30class screen_positions:31 def __init__(self):32 self.spec_buttons = [(), (), ()] # x, y, w, h33 self.cells = [(), (), ()] # x, y, w, h34 self.middle = () # x, y, w, h35 self.topright = [(), (), ()] # x, y, w, h36 self.main_field = () # x, y, w, h37 self.main = [] # x1, x2, x3, x4, x5, x6, x7, x838cards_pos = screen_positions()39cards_pos.spec_buttons = [ 40(575, 25, 53, 54),41(575, 108, 53, 54),42(575, 191, 53, 54)43]44cards_pos.cells = [45(116, 19, 120, 232),46(268, 19, 120, 232),47(420, 19, 120, 232)48]49cards_pos.middle = (684, 19, 120, 232)50cards_pos.topright = [51(876, 19, 120, 232),52(1028, 16, 120, 233),53(1180, 18, 120, 232)54]55cards_pos.main_field = (116, 283, 1180+121, 283+418)56cards_pos.main = [1180, 1028, 876, 724, 572, 420, 268, 116]57cards_pos.main.sort()58data = {}59move_weights = [50, 40, 10, 4, 1, 0]60 # auto_move = 50, special_move = 40, full_chain = 10, 61 # full_chain_to_free = 4, to_free_cell = 1, break_chain = 1 ...62class Move:63 # map_pos ((0,1,2),3,(4,5,6),((7),(9),(9),(10),(11),(12),(13),(14)))64 def __init__(self, from_pos, deep, to, weight):65 self.from_pos = from_pos66 self.deep = deep #deep calculated from bottom to top, so last card at 0 deep67 self.to = to68 self.weight = weight 69 70 def __repr__(self):71 return "M f:%s d:%s to:%s w:%s" % (self.from_pos, self.deep, self.to, self.weight)72 73 def __str__(self):74 str_ = "Move from position %s with deep of %s to position %s, weight=%s"75 return str_ % (self.from_pos, self.deep, self.to, self.weight)76 77 def __eq__(self, other):78 return isinstance(other, self.__class__) and (self.__dict__ == other.__dict__) 79 80 def __le__(self, other):81 return self.weight <= other.weight82 83 def __lt__(self, other):84 return self.weight < other.weight85 86 def __gt__(self, other):87 return self.weight > other.weight88 89 def __ge__(self, other):90 return self.weight >= other.weight91def card_str(card):92 return "(%s, %2s)"%card if card != () else "( )" 93class Map_:94 # Solitiare map95 def __init__(self):96 self.cells = [ (), (), () ]97 self.middle = False98 self.topright = [ (), (), () ]99 self.main = [ [], [], [], [], [], [], [], [] ]100 101 def __str__(self): #map representation102 t1 = " ".join(card_str(k) for k in self.cells)103 t2 = "(7, -1)" if self.middle else "( )"104 t3 = " ".join(card_str(k) for k in self.topright)105 top = t1 + " " + t2 + " " + t3106 b_n = max([len(k) for k in self.main] + [1])107 b = [k + [()]*(b_n-len(k)) for k in self.main]108 main = "\n".join(" ".join(card_str(k[i]) for k in b) for i in range(len(b[0])))109 return top + "\n\n" + main110 111 def __eq__(self, other):112 #return( self.__dict__ == other.__dict__ )113 return isinstance(other, self.__class__) and (hash(self) == hash(other)) 114 115 def __ne__(self, other):116 return not self.__eq__(other) 117 118 def __hash__(self):119 #return(hash(str(self)))120 return hash((tuple(sorted(self.cells)), self.middle, tuple(sorted(self.topright)), tuple(tuple(c) for c in sorted(self.main))))121 122 def copy_map(self, map):123 self.cells = list(map.cells)124 self.middle = map.middle125 self.topright = list(map.topright)126 self.main = [list(a) for a in map.main]127 128 def n(self):129 return sum(k != () and k != (8, -1) for k in self.cells) + sum(sum(k != () for k in a) for a in self.main)130 131 def read_map(self):132 #read screen and evaluate map from it133 134 # 1. find basic contour135 # 2. adjust coorinates, make coordinate map136 # 2.5 make database from chips137 # 3. compare imgs with base to read value138 global cards_pos139 global data140 141 data_map = {}142 printProgressBar('Reading screen:', 30, 0)143 screenshot = ImageGrab.grab() # Make screenshot144 printProgressBar('Reading screen:', 30, 0.3)145 img_rgb = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2RGB)146 printProgressBar('Reading screen:', 30, 0.6)147 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)148 printProgressBar('Reading screen:', 30, 1)149 print()150 151 y_delta = 31152 x_delta = 0153 y_diff = 8154 x_diff = 8155 x_size = 20156 y_size = 23157 158 bar_max, bar_i = len(data), 0 #progress bar159 for key, value in data.items(): #find all mathces with database160 a = []161 #print(key)162 template = value163 w, h = template.shape[::-1]164 res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)165 threshold = 0.99166 loc = np.where(res >= threshold)167 for pt in zip(*loc[::-1]):168 x, y = pt169 for n, coord in enumerate(cards_pos.cells): #check cells pos170 x_c, y_c, _, _ = coord171 if abs(x_c + x_diff - x) < 20 and abs(y_c + y_diff - y ) < 20:172 self.cells[n] = key173 if key == (7, -1) and abs(cards_pos.middle[0] - x) < 20 and abs(cards_pos.middle[1] - y) < 20 :174 self.middle = True #check middle175 for n, coord in enumerate(cards_pos.topright): #check topright pos176 x_c, y_c, _, _ = coord177 if abs(x_c + x_diff - x) < 20 and abs(y_c + y_diff - y ) < 20:178 self.topright[n] = key179 y_c = cards_pos.main_field[1]180 if y >= y_c - 20:181 for n, x_c in enumerate(cards_pos.main): #check main field182 if abs(x_c + x_diff - x) < 20:183 i = int((y - y_diff - y_c)/y_delta)184 if len(self.main[n]) < i + 1:185 self.main[n] += [()]*(i - len(self.main[n]) + 1)186 self.main[n][i] = key187 a.append(pt)188 #cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)189 data_map[key] = a #create coordinates matches database190 bar_i += 1191 printProgressBar('Building map:', 30, bar_i/bar_max)192 print()193 #func end194 195 def possible_moves(self):196 #list of all possible moves from given map197 move_list = []198 199 if () in self.cells: #any top-left cell is empty200 j = self.cells.index(()) # index of free cell201 move_list += [Move(i+7, 0, j, 1) for i, k in enumerate(self.main) if k != []]202 # do not check moves from topright to freecells, becouse it's stupid move !!!203 204 for i, x in enumerate(self.cells): #any top-left cells is ocupy, check if we can drop it down to main field205 if x != () and x != (8, -1): #valid card on that spot206 #check topright cells207 # ... "or to topright" move that part to automove208 #move_list += [Move(i, 0, j+4, False) for j,y in enumerate(self.topright) if y and check_valid_junction(x, y)]209 #check main field210 move_list += [Move(i, 0, j+7, 1 if y == [] else 10) for j, y in enumerate(self.main) if y == [] or check_valid_junction(x, y[-1])]211 212 #comment this section to check this kind of moves is needed at all213 """214 if any(self.topright): #check if we can move from topright to mainfield (sometimes it usefull, yes?)215 for i,x in enumerate(self.topright):216 if x:217 move_list += [Move(i+4, 0, j+7, False) for j,y in enumerate(self.main) if (y and check_valid_junction(x, y[-1])) or not y]218 """219 #...220 for i, x in enumerate(self.main): #check main field column by column221 if x != []: # x = column222 n = find_max_valid_chain_len(x)223 for d, c in enumerate(x): # c = card, d = card num in column224 if len(x)-d == n: # max chain225 w = 10226 else:227 w = 1228 #if d + 1 == len(x): # only last card229 # move_list += [Move(i+7, 0, j+7, w) for j,y in enumerate(self.main) if j!=i and (y == [] or check_valid_junction(x[d], y[-1]))]230 #elif chek_valid_chain(x[d:]): # valid chain of cards231 if d >= len(x)-n:232 for j, y in enumerate(self.main):233 if j!=i and (y == [] or check_valid_junction(x[d], y[-1])):234 if y == []:235 w = w % 6236 move_list.append(Move(i+7, len(x)-d-1, j+7, w))237 238 #check for special buttons move (if all 4 of same type special card available and we have a free cell)239 # special cards is (4,-1) (5,-1) (6,-1) (spec cards x4)240 for sp in [(4,-1), (5,-1), (6,-1)]:241 if self.cells.count(sp) + [x[-1] for x in self.main if x != []].count(sp) == 4: #all 4 of 1 type available to move242 if sp in self.cells or () in self.cells:243 move_list.append(Move(15, sp[0], 15, 40))244 245 return move_list246 247 # map_pos ((0,1,2),3,(4,5,6),((7),(9),(9),(10),(11),(12),(13),(14)))248 def auto_move(self):249 #check for automatic move, that game do for me 250 #return auto move or Null if nothing to do251 252 for i, k in enumerate(self.main):253 if (7, -1) in k:254 if k[-1] == (7,-1):255 return Move(i+7, 0, 3, 50)256 257 min_n = min([a[1] if a != () else 0 for a in self.topright])258 259 for i, k in enumerate(self.cells):260 for x in [1, 2, 3]:261 if k == (x, min_n+1):262 if min_n == 0:263 j = self.topright.index(())264 else:265 j = self.topright.index((x, min_n))266 return Move(i, 0, j+4, 50)267 268 for i, k in enumerate(self.main): # because of this automove can stuck it all in loop269 if k != []: # if not empty column in self.main270 for x in [1, 2, 3]:271 if k[-1] == (x, min_n+1):272 if min_n == 0:273 j = self.topright.index(())274 else:275 j = self.topright.index((x, min_n))276 return Move(i+7, 0, j+4, 50)277 return False278 279 def move_execute(self, m):280 # execute move on current map281 #new_map = Map_()282 #new_map.copy(self)283 # map_pos ((0,1,2),3,(4,5,6),((7),(9),(9),(10),(11),(12),(13),(14)))284 if m.from_pos < 3:285 a = self.cells[m.from_pos]286 self.cells[m.from_pos] = ()287 elif m.from_pos < 4:288 pass289 elif m.from_pos < 7:290 a = self.topright[m.from_pos-4]291 if a[1] > 1:292 self.topright[m.from_pos-4][1] = a[1] - 1293 else: #don't know is it possible to remove card N 1294 self.topright[m.from_pos-4] = ()295 elif m.from_pos < 15:296 a = self.main[m.from_pos-7][-1-m.deep:]297 self.main[m.from_pos-7] = self.main[m.from_pos-7][:-1-m.deep]298 else: #special button moves299 a = (m.deep, -1)300 for k in self.main:301 if a in k:302 k.pop()303 for i, k in enumerate(self.cells):304 if a == k:305 self.cells[i] = ()306 self.cells[self.cells.index(())] = (8, -1)307 308 if m.to < 3:309 if type(a) == list:310 a = a[0]311 self.cells[m.to] = a312 elif m.to < 4:313 self.middle = True314 elif m.to < 7:315 if type(a) == list:316 if a == []:317 raise WtfError318 a = a[0]319 self.topright[m.to-4] = a320 elif m.to < 15:321 if type(a) is list:322 self.main[m.to-7] += a323 else:324 self.main[m.to-7].append(a)325 #return(new_map)326 #func end327win_map = Map_()328win_map.cells = [(8, -1), (8, -1), (8, -1)]329win_map.middle = True330win_map.topright = [(1, 9), (2, 9), (3, 9)]331win_map.main = [ [], [], [], [], [], [], [], [] ]332test_map = Map_()333test_map.main = [334 [ (2, 8), (3, 6), (5,-1), (7,-1), (3, 8) ],335 [ (4,-1), (3, 3), (5,-1), (2, 7), (2, 2) ],336 [ (3, 4), (1, 3), (2, 4), (2, 9), (4,-1) ],337 [ (6,-1), (3, 1), (6,-1), (1, 6), (2, 6) ],338 [ (5,-1), (2, 3), (3, 9), (6,-1), (3, 5) ],339 [ (1, 9), (3, 7), (4,-1), (2, 5), (3, 2) ], 340 [ (1, 5), (1, 2), (5,-1), (1, 4), (6,-1) ], 341 [ (2, 1), (1, 8), (1, 1), (4,-1), (1, 7) ], 342]343test_map2 = Map_()344test_map2.main = [345 [ (2, 8), (3, 6), (5,-1), (7,-1), (3, 8) ],346 [ (4,-1), (3, 3), (5,-1), (2, 7), (2, 2) ],347 [ (3, 4), (1, 3), (2, 4), (2, 9), (4,-1) ],348 [ (6,-1), (3, 1), (6,-1), (1, 6), (2, 6) ],349 [ (5,-1), (2, 3), (3, 9), (6,-1), (3, 5) ],350 [ (1, 9), (3, 7), (4,-1), (2, 5), (3, 2) ], 351 [ (1, 5), (1, 2), (5,-1), (1, 4), (6,-1) ], 352 [ (2, 1), (1, 8), (1, 1), (4,-1), (1, 7) ], 353]354 355def printProgressBar(name, width, percent, symbol = '#'):356 print('\r{0: <30} [{1:30s}] {2:.1f}%'.format(name, symbol * int(width * percent), percent * 100), end='')357def chek_valid_chain(chain):358 return all([check_valid_junction(b,a) for a,b in zip(chain, chain[1:])])359def find_max_valid_chain_len(chain):360 res = 1361 while len(chain) > res and check_valid_junction(chain[-res], chain[-res-1]):362 res += 1363 return res364def check_valid_junction(card, card_to):365 if card[0] != card_to[0] and card[1] + 1 == card_to[1]:366 return True367 return False368def find_solution_path():369 #recursive creating solution path370 #each iteration check all possible moves and check if it lead us to victory371 #if dead end - drop that branch372 #if stuck in returning to prev position - drop373 #chech for auto-move befor each move374 global solution_found375 global map_dict # dict={map: path_to_that_map, ...}376 global map_stack # dict={move_weight: [maps...], } stuck what map to check on possible moves next377 global map_checked # set of maps that already checked (not check it again)378 global move_weights # list of possible move weights379 global win_map380 global step381 global all_steps382 min_n = 40383 while not solution_found:384 i = 0385 while map_stack[move_weights[i]] == []: i += 1386 w_ = move_weights[i]387 #w_ = max([w for w in move_weights if map_stack[w] != []] + [0])388 if w_ != 0:389 next_map = map_stack[w_].pop()390 step = step + 1391 if len(map_dict[next_map]) > MAX_PATH:392 continue393 if step > MAX_STEPS:394 print("\nReached MAX_STEPS count, skipping this board.")395 return False396 #if next_map in map_checked:397 # print("lalalalala")398 # continue # why no entry???399 #else:400 # map_checked.add(next_map)401 prev_path = map_dict[next_map]402 a = next_map.auto_move()403 if a:404 moves_to_test = [a]405 else:406 moves_to_test = next_map.possible_moves()407 #moves_to_test.sort(reverse = True)408 for test_move in moves_to_test:409 new_map = Map_()410 new_map.copy_map(next_map)411 new_map.move_execute(test_move)412 413 if map_dict.get(new_map) == None:414 map_dict[new_map] = prev_path + [test_move]415 map_stack[test_move.weight].append(new_map)416 else:417 if len(map_dict[new_map]) > len(prev_path) + 1:418 map_dict[new_map] = prev_path + [test_move]419 if new_map.n() < min_n:420 min_n = new_map.n()421 if new_map == win_map:422 solution_found = True423 break424 all_steps = all_steps + len(moves_to_test)425 percent = (40 - min_n)/40 #draw progressbar426 str_ = '\r{0: <30} [{1:30s}] {2:.1f}% {3:d} / {4:d} moves checked'427 print(str_.format('Finding solution:', '#'*int(30*percent), percent*100, step, all_steps), end='')428 else:429 break430 #print()431def solution_optimization():432 #optimize given solution433 global map_dict434 global win_map435 move_list = map_dict[win_map]436 # how optimize it?437 # - figure out which one moves are useless, but how?438 # - determine move weight depending on how usefull it439 # like this:440 # move to topright is 1441 # move to freecell is 5442 # move to another card is 10443 # spec button move is 50444 # auto-move is 25445 # ....446 # depend of this check most value moves first447 # amd all of it should be done in find_solution_path()448 # oh well...449 pass450def solve_it(sc_map, path):451 # map_pos ((0,1,2),3,(4,5,6),((7),(9),(9),(10),(11),(12),(13),(14)))452 _, _ ,card_w, card_h = cards_pos.cells[0]453 card_w = card_w // 2454 card_h = card_h // 2455 y_delta = 31456 click(100, 100)457 time.sleep(0.5)458 for m in path:459 print(m)460 if m.weight != 50:461 x, y = 0, 0462 if m.from_pos < 3:463 x, y, _, _ = cards_pos.cells[m.from_pos]464 x += card_w465 y += card_h466 elif m.from_pos < 7:467 #a = self.topright[m.from_pos-4]468 #if a[1] > 1:469 # self.topright[m.from_pos-4][1] = a[1] - 1470 #else: #don't know is it possible to remove card N 1471 # self.topright[m.from_pos-4] = ()472 print("nothing here")473 elif m.from_pos < 15:474 x = cards_pos.main[m.from_pos-7] + card_w475 y = cards_pos.main_field[1] + 10 + y_delta*(len(sc_map.main[m.from_pos-7])-1-m.deep)476 else: #special button moves477 x, y, w, h = cards_pos.spec_buttons[m.deep-4]478 x += w // 2479 y += h // 2480 x2, y2 = 0, 0481 if m.to < 3:482 x2, y2, _, _ = cards_pos.cells[m.to]483 x2 += card_w484 y2 += card_h485 elif m.to < 4:486 pass487 elif m.to < 7:488 x2, y2, _, _ = cards_pos.topright[m.to-4]489 x2 += card_w490 y2 += card_h491 elif m.to < 15:492 x2 = cards_pos.main[m.to-7] + card_w493 i = len(sc_map.main[m.to-7])494 i = i if i != 0 else 1495 y2 = cards_pos.main_field[1] + 10 + y_delta*(i-1)496 #time.sleep(0.3)497 #screenshot = ImageGrab.grab()498 #draw = ImageDraw.Draw(screenshot) 499 #draw.line((x,y, x2,y2), fill=128)500 #img_rgb = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2RGB)501 #cv2.imshow('image',img_rgb)502 #cv2.moveWindow('image', 1366, -350)503 #cv2.waitKey(0)504 #cv2.destroyAllWindows()505 #click(100, 100)506 time.sleep(0.3)507 if x2 != 0:508 move_click(x, y, x2, y2)509 else:510 click(x, y)511 else:512 time.sleep(0.4)513 sc_map.move_execute(m)514 #break515 #solve it by move mouse and so516def find_contours(im):517 gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)518 ret,thresh = cv2.threshold(gray,127,255,0)519 _,contours,_ = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)520 #areas = [cv2.contourArea(c) for c in contours]521 #max_index = np.argmax(areas)522 #cnt=contours[max_index]523 for cnt in contours:524 x,y,w,h = cv2.boundingRect(cnt)525 if w > 50 and h > 50:526 #print("x = %4s y = %4s h = %4s w = %4s"%(x, y, w, h))527 print((x, y, w, h))528 cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)529 cv2.imshow("Show",im)530 cv2.waitKey(0)531def make_database():532 _, y, _, _ = cards_pos.main_field533 _, _, w, h = cards_pos.middle534 fig = plt.figure()535 y_delta = 31536 x_delta = 0537 y_diff = 8538 x_diff = 8539 x_size = 20540 y_size = 23541 for j, x in enumerate(cards_pos.main):542 for i in range(10):543 #cv2.imshow('image',img_rgb[y+y_diff:y+y_diff+y_size, x+x_diff:x+x_diff+x_size])544 #cv2.waitKey(0)545 #cv2.destroyAllWindows()546 #cv2.imwrite("1.png", img_rgb[y+y_diff:y+y_diff+y_size, x+x_diff:x+x_diff+x_size])547 ax =fig.add_subplot(10, 8, i*8 + 1 + j)548 ax.imshow(img_rgb[y+y_diff+y_delta*i:y+y_diff+y_delta*i+y_size, x+x_diff+x_delta*i:x+x_diff+x_delta*i+x_size], 'gray')549 ax.autoscale(False)550 ax.axis('off')551 552 plt.show()553 554def read_database():555 global data556 imgs = glob.glob("data\*.png")557 bar_max, bar_i = len(imgs), 0 #progress bar558 for a in imgs:559 data[ tuple(int(x) for x in a[a.index('(')+1:a.index(')')].split(',')) ] = cv2.imread(a, 0)560 bar_i = bar_i + 1 #draw progressbar561 printProgressBar('Reading img database:', 30, bar_i/bar_max)562 print()563 564def click(x, y):565 win32api.SetCursorPos((x, y))566 time.sleep(0.1)567 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)568 time.sleep(0.1)569 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)570def move_click(x, y, x2, y2):571 win32api.SetCursorPos((x, y))572 time.sleep(0.1)573 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)574 time.sleep(0.1)575 win32api.SetCursorPos((x2, y2))576 time.sleep(0.1)577 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x2, y2, 0, 0)578MAX_PATH = 150579AUTO_SOLVE = True580MAX_STEPS = 100000581if __name__ == "__main__":582 583 print("Program start.")584 585 read_database()586 while AUTO_SOLVE == True:587 step = 0588 all_steps = 0589 solution_found = False590 map_dict = {}591 map_stack = {}592 map_checked = set()593 gc.collect()594 screen_map = Map_()595 screen_map.read_map()596 #screen_map = test_map2597 for w in move_weights:598 map_stack[w] = []599 map_stack[0].append(None)600 map_stack[50].append(screen_map)601 map_dict[screen_map] = []602 603 print("\nCurrent Map:\n")604 print(screen_map)605 print("\n")606 607 #click(50, 50)608 find_better_solution = True609 find_solution_path()610 if solution_found:611 while find_better_solution:612 all_moves, auto_moves = len(map_dict[win_map]), len([1 for m in map_dict[win_map] if m.weight == 50])613 print("\nSolution found: %s moves (%s manual, %s auto)"%(all_moves, all_moves - auto_moves, auto_moves))614 if not AUTO_SOLVE:615 print("Find better solution? (y/n): ", end='')616 ans = input()617 if ans == 'y':618 solution_found = False619 while len(map_dict[win_map]) == all_moves:620 try:621 find_solution_path()622 except KeyboardInterrupt:623 print()624 print("Keyboard Interrupt detected, stop better solution search")625 break626 #print("Another solution found: same moves number")627 solution_found = False628 if len(map_stack) == 0:629 print("No possible moves left")630 find_better_solution = False631 else:632 find_better_solution = False633 else:634 find_better_solution = False635 if solution_found:636 solve_it(screen_map, map_dict[win_map])637 time.sleep(3)638 else:639 print("Reach dead end, no solution detected.")640 click(1115, 730)641 time.sleep(6)642 643 print("Program end.")...`

solver.py

Source:solver.py

`...18 print("Couldn't Find a Solution\n")19 return l_solutionManager.get_best()20 21 if targetFloor == 1:22 self.find_better_solution(l_solutionToDev, p_firstTree, l_solutionManager, targetFloor)23 if targetFloor == 2:24 self.find_better_solution(l_solutionToDev, p_secondTree, l_solutionManager, targetFloor)25 if targetFloor == 3:26 self.find_better_solution(l_solutionToDev, p_thirdTree, l_solutionManager, targetFloor)27 l_floor = self.get_target_floor_value(l_solutionManager.get_best_value())28 print("Floor="+str(l_floor)+" Best yet:"+str(l_solutionManager.get_best_value())+", best_undeveloped="+str(l_solutionManager.get_best_undeveloped() != None)+"\n")29 l_solutionToDev = l_solutionManager.get_best_undeveloped()30 return l_solutionManager.get_best()31 def get_target_floor_perm(self,p_permutation):32 if Cube.get_value(p_permutation, 1) >= 16:33 if Cube.get_value(p_permutation, 2) < 24:34 return 235 else:36 return 337 else:38 return 139 def get_target_floor_value(self, p_value):40 if p_value >= 16:41 if p_value < 24:42 return 243 else:44 return 345 else:46 return 147 def find_better_solution(self,p_solution,p_tree,p_solutionManager, p_floor):48 l_rubik = Cube()49 l_permutation = p_solution.get_permutation().get_copy()50 l_minimumValue = Cube.get_value(l_permutation, p_floor)51 l_rubik = Cube(l_permutation)52 self.search_tree(l_minimumValue - 4, p_tree, l_rubik, p_solutionManager, p_solution, p_floor, 0)53 def search_tree(self, minimumValueToReach,searchTree,54 cubeToSolve,solutionManager,55 previousSolution, targetFloorToSortInCube, depth):56 if minimumValueToReach < 2:57 minimumValueToReach = 258 for rotationSequenceIndex in range(0,searchTree.get_size()):59 rotationSequence = searchTree.get_rotationSequence(rotationSequenceIndex)60 if rotationSequence != None:61 cubeAfterRotationSequence = self.get_cube_after_applying_sequence(Cube(cubeToSolve), rotationSequence)...`

bot.py

Source:bot.py

`...23 poss = {24 k: self.game_state_metrics(k, state)25 for (k, state) in poss.items()26 }27 best_drop = self.find_better_solution(poss)28 rot, col, n_drop, _ = best_drop29 dx = col - self.env.game.piece.x30 translate = 'left' if dx < 0 else 'right'31 actions = ['cw'] * rot + [translate] * abs(dx) + ['drop'] * n_drop32 actions = list(reversed(actions))33 return [TetrisEnv.actions.index(a) for a in actions]34 def find_all_drop_possibilities(self):35 poss = {}36 for rot in range(4):37 for col in range(params.n_cols):38 game = self.env.game.copy()39 game.nb_lines = 040 for _ in range(rot):41 game.rotate_piece(clockwise=True)42 y_dim = game.piece.shape.shape[1]43 if col + y_dim > params.n_cols:44 continue45 game.piece.x = col46 n_drop = 047 while True:48 new_y = game.piece.y + 149 if game.check_collision(game.piece, (game.piece.x, new_y)):50 break51 game.piece.y = new_y52 n_drop += 153 poss[(rot, col, n_drop + 1, game.nb_lines)] = game.state54 return poss55 def find_better_solution(self, possibilities):56 def value(nb_lines, nb_holes, heights):57 aggregate_height = heights.sum()58 bumpiness = np.abs(np.diff(heights)).sum()59 a = -0.560 b = 0.7561 c = -0.3562 d = -0.263 return a * aggregate_height + b * nb_lines + c * nb_holes + d * bumpiness64 possibilities = {65 k: value(*v)66 for k, v in possibilities.items()67 }68 key, val = max(possibilities.items(), key=operator.itemgetter(1))69 return key...`

## Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.