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...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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
