欢乐跳瓶python辅助程序(在夜神模拟器上实际运行)

本人写的一个关于欢乐跳瓶的作弊程序,在夜神模拟器上运行的,主要拿canny写的。

如果是跳一跳其实就更容易了,因为欢乐跳瓶的界面较跳一跳来说噪声相对要多不少。

完整可运行代码下载请移步 https://download.csdn.net/download/kuroyukineko/10494650

下面贴一下大致PPT的内容和代码。



下面是纯代码,如果需要上机运行的话还需要几个匹配的模版,在下载里都打了包,这里就不贴了。

# bottle_flip_cheat
# by Kuroyukineko 2018.03.09
# Noxplayer(1280*720)_BottleFlip

import sys
import time
import math
import win32gui
import win32ui
import win32api
import win32con
import numpy as np
import cv2
import matplotlib.pyplot as plt

def beginDetect(hwnd, window_hw_para):
	
	filename = "begindetect.jpg"
	
	pic_capture(hwnd, filename)
	#read image
	img_origin = cv2.imread(filename)
	img_cut_gray = cv2.cvtColor(img_origin, cv2.COLOR_BGR2GRAY)
	#template
	template = cv2.imread("beginTemplate.jpg", 0)
	template1 = cv2.imread("beginTemplate.jpg", 0)
	#w, h = template.shape[::-1]
	res = cv2.matchTemplate(img_cut_gray,template,cv2.TM_CCOEFF_NORMED) 
	res1 = cv2.matchTemplate(img_cut_gray,template1,cv2.TM_CCOEFF_NORMED)
	threshold = 0.6 
	loc = np.where( res >= threshold)	
	loc1 = np.where( res1 >= threshold)	
	
	if len(loc[0]) != 0 or len(loc1[0]) != 0:
		mouse_move(window_hw_para['left'] + 280, 
		window_hw_para['top'] + 500)
		mouse_click(0.5) #jump
		time.sleep(1)
	cv2.destroyAllWindows() 
	
def ready_game():
	#player locate the game window
	print ("Please move the cursor on game window and press 'Y'.")
	#decide to start or not
	ready_confirm = input(">> ")
	if ready_confirm == 'Y':
		start_game()
	else:
		end_gmae()

def start_game():
	print ("Enjoy the game!")

def end_game():
	print ("ByeBye!")
	sys.exit()
	
def restart_detect(hwnd, window_hw_para, timeRecord):	
	filename = "restartdetect.jpg"
	
	pic_capture(hwnd, filename)
	#read image
	img_origin = cv2.imread(filename)
	img_cut_gray = cv2.cvtColor(img_origin, cv2.COLOR_BGR2GRAY)
	#template
	template = cv2.imread("restartTemplate.jpg", 0)
	template1 = cv2.imread("skipTemplate.jpg", 0)
	#w, h = template.shape[::-1]
	res = cv2.matchTemplate(img_cut_gray,template,cv2.TM_CCOEFF_NORMED) 
	res1 = cv2.matchTemplate(img_cut_gray,template1,cv2.TM_CCOEFF_NORMED)
	threshold = 0.6 
	loc = np.where( res >= threshold)	
	loc1 = np.where( res1 >= threshold)	
	cv2.destroyAllWindows()  
	
	if len(loc[0]) != 0 or len(loc1[0]) != 0:
		end_game()
 
def mouse_move(position_x, position_y):
	win32api.SetCursorPos([position_x, position_y])
	
#click the mouse (position_x, position_y, click_time/s)
def mouse_click(click_time): 
	win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
	time.sleep(click_time)
	win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)	
	
	
def distance_calculate(hwnd, window_hw_para):
	filename = "tmp.jpg"
	error_set = 15
	pic_capture(hwnd, filename)
	start_position, close_flag = jump_from_position(window_hw_para,error_set)
	final_position = jump_to_position(window_hw_para, error_set, start_position)
	print ("from", start_position)
	print ("to", final_position)
	if close_flag == True:
		distance = 25
	else:
		distance = (((start_position[0] - final_position[0]) ** 2 + 
		(start_position[1] - final_position[1]) ** 2) ** 0.5)
	print ('distance = ', distance)
	#if distance < 70:
		#distance = distance * 0.85
	return distance

	
def pic_capture(hwnd, filename):
	hwndDC = win32gui.GetWindowDC(hwnd)
	mfcDC = win32ui.CreateDCFromHandle(hwndDC)
	saveDC = mfcDC.CreateCompatibleDC()
	saveBitMap = win32ui.CreateBitmap()
	MoniterDev = win32api.EnumDisplayMonitors(None, None)
	w = MoniterDev[0][2][2]
	h = MoniterDev[0][2][3]
	saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
	saveDC.SelectObject(saveBitMap)
	saveDC.BitBlt((0, 0), (w, h), mfcDC, (0, 0), win32con.SRCCOPY)
	saveBitMap.SaveBitmapFile(saveDC, filename)
	
def jump_from_position(window_hw_para,error):
	#read image
	img_origin = cv2.imread('tmp.jpg')
	#cv2.imshow('tmp.jpg', img_origin)
	window_h = int((window_hw_para['bottom'] - window_hw_para['top']) / 2)
	window_w = window_hw_para['right'] - window_hw_para['left']
	
	img_gray = cv2.cvtColor(img_origin, cv2.COLOR_BGR2GRAY)
	template = cv2.imread('Template.jpg',0)
	w, h = template.shape[::-1]
	res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) 
	threshold = 0.6
	loc = np.where(res >= threshold) #matrix (j, i)
	if len(loc[0]) == 0:
		print ("zero array occurs.")
		
	#Template color: [255 151 122]
	blue = img_origin[loc[0] + 54, loc[1] + 19, 0].astype(np.int64) - 255 #40,10
	green = img_origin[loc[0] + 54, loc[1] + 19, 1].astype(np.int64) - 151
	red = img_origin[loc[0] + 54, loc[1] + 19, 2].astype(np.int64) - 122
	#print(blue, green, red)
	error_blue_square = blue.astype(np.int64) ** 2
	error_green_square = green.astype(np.int64) ** 2
	error_red_square = red.astype(np.int64) ** 2
	#print (error_blue_square, error_green_square, error_red_square)
	error_cal = np.sqrt(error_blue_square + error_green_square + error_red_square)
	#print (error_cal)
	result_loc = np.where(error_cal < error)
	mid = int(len(result_loc[0])/2)
	result = result_loc[0][0]
	final_loc = [loc[0][result] + 80, loc[1][result] + 19] #62,10
	flag = False
	cv2.destroyAllWindows() 
	return final_loc, flag

#incase that bootle is too close to the middle line
def left_or_right(corner_position_x, window_w):
	flag = np.zeros(2)
	t1 = corner_position_x <= window_w / 2 + 25
	t2 = corner_position_x >= window_w / 2 - 25
	if t1 and t2:
		#too close to middle line 
		flag[0] = True 
	else:
		flag[0] = False
		
	if corner_position_x < window_w / 2:
		flag[1] = True
	else:
		flag[1] = False
	
	return flag
	
def jump_to_position(window_hw_para, error_set, from_loc):

	finalposition = np.zeros(2)
	#now = time.time()
	img_origin = cv2.imread('tmp.jpg')
	#cv2.imshow('tmp.jpg', img_origin)
	window_h = int((window_hw_para['bottom'] - window_hw_para['top']) / 3)
	window_w = window_hw_para['right'] - window_hw_para['left']
	#print("The size of window is [%d, %d]" % (window_h, window_w))
	flag_bottle = left_or_right(from_loc[1], window_w)
	flag, crystalposition = crystal_detect(hwnd, error_set)

	#estimate
	middle_x = 276.5
	middle_y = 491.5
	
	absy = abs(from_loc[0] - middle_y)
	absx = abs(from_loc[1] - middle_x)
	
	if middle_y > from_loc[0]:
		final_loc_est_y = middle_y + absy
	else:
		final_loc_est_y = middle_y - absy
		
	if middle_x > from_loc[1]:
		final_loc_est_x = middle_x + absx
	else:
		final_loc_est_x = middle_x - absx
	loc_estimate = [int(final_loc_est_y), int(final_loc_est_x)]
	
	blue = img_origin[int(final_loc_est_y), int(final_loc_est_x), 0].astype(np.int64) - 162
	green = img_origin[int(final_loc_est_y), int(final_loc_est_x), 1].astype(np.int64) - 162
	red = img_origin[int(final_loc_est_y), int(final_loc_est_x), 2].astype(np.int64) - 162
	
	error_blue_square = blue.astype(np.int64) ** 2
	error_green_square = green.astype(np.int64) ** 2
	error_red_square = red.astype(np.int64) ** 2
	#print (error_blue_square, error_green_square, error_red_square)
	error_cal = np.sqrt(error_blue_square + error_green_square + error_red_square)
	#print (error_cal)
	#detect gray
	if error_cal <= 15:
		print("Use estimate location!!!")
		return loc_estimate

	if flag == False:
		# calculate estimated zone
		j_min = int(final_loc_est_y - 45) if (final_loc_est_y - 45) > window_h else window_h
		j_max = int(final_loc_est_y + 45) if (final_loc_est_y + 45) < 2*window_h else 2*window_h
		i_min = int(final_loc_est_x - 45) if (final_loc_est_x - 45) > 0 else 0
		i_max = int(final_loc_est_x + 45) if (final_loc_est_x + 45) < window_w else 2*window_w

		#too close to bottle(line)
		if flag_bottle[1] == True:
			#bottle left
			if from_loc[1]+30 >= i_min:
				i_min = from_loc[1]+30
		else:
			if from_loc[1]-30 <= i_max:
				i_max = from_loc[1]-30
				
		img_cut = img_origin[j_min:j_max, i_min:i_max]
	
		#canny
		img_canny = cv2.Canny(img_cut, 120, 165)
		#cv2.imshow('Canny', img_canny)
		#pick corner which decides x
		corner_position_y, corner_position_x = get_top_corner(window_h, 
		window_w, img_canny, img_cut, flag_bottle, from_loc[1])	
		flag_lor = left_or_right(corner_position_x+i_min, window_w)
		corner2 = get_conrner2(window_h, window_w, img_canny, 
		img_cut, corner_position_y, corner_position_x, error_set, flag_lor[1]) #get the color
		finalposition = [corner2[0]+j_min, corner_position_x+i_min] #img_origin
	else:
		finalposition = crystalposition
		return finalposition

	cv2.destroyAllWindows() 
	return finalposition
		
		
def get_top_corner(window_h, window_w, img_canny, img_cut, flag, from_loc_x):	

	result = np.where(img_canny == 255)
	ans = np.where(result[0] == result[0][0])
	mid = int(len(ans[0]) / 2)	
	#sort by line
	j = result[0][mid]
	i = result[1][mid]
	
	return j, i  #img_cut[j,i]
	
def get_conrner2(h, w, img_canny, 
img_cut, y, x, error, flag):
	corner2 = np.zeros(2)
	result_asort = np.where(img_canny == 255)
	
	if flag == True: 
		corner2 = leftsort(result_asort)			
	else:
		corner2 = rightsort(result_asort)
	return corner2


def leftsort(input):
	#input matrix is [2, n] [j, i]
	#print(input)
	#np.savetxt('i.txt',input[1])
	min_i = np.min(input, axis = 1)
	#print (input[1])
	min_loc_i = np.where(input[1] == min_i[1]) #location of min 
	i_sorted = [input[0][min_loc_i], input[1][min_loc_i]] #sorted by i
	#print (i_sorted)
	min_j = np.min(i_sorted, axis = 1)
	#print (i_sorted[0])
	min_loc_j = np.where(i_sorted[0] == min_j[0]) #location of min 
	#min_loc_j = np.where(i_sorted[1] == min_j[1]) #location of min 
	j_sorted = [i_sorted[0][min_loc_j], i_sorted[1][min_loc_j]] #sorted by j
	#print (j_sorted)
	output = [j_sorted[0][0], j_sorted[1][0]]
	#print (output)
	return output #matrix (j, i)	
	
def rightsort(input):
	#input matrix is [2, n] [j, i]
	max_i = np.max(input, axis = 1)
	#print (input[1])
	max_loc_i = np.where(input[1] == max_i[1]) #location of min 
	i_sorted = [input[0][max_loc_i], input[1][max_loc_i]] #sorted by i
	#print (i_sorted)
	min_j = np.min(i_sorted, axis = 1)
	#print (i_sorted[0])
	min_loc_j = np.where(i_sorted[0] == min_j[0]) #location of min 
	#min_loc_j = np.where(i_sorted[1] == min_j[1]) #location of min 
	j_sorted = [i_sorted[0][min_loc_j], i_sorted[1][min_loc_j]] #sorted by j
	#print (j_sorted)
	output = [j_sorted[0][0], j_sorted[1][0]]
	#print (output)
	return output #matrix (j, i)	
	

def crystal_detect(hwnd,error):	
	filename = "crystaldetect.jpg"
	flag = False
	pic_capture(hwnd, filename)
	#read image
	img_origin = cv2.imread(filename)
	img_gray = cv2.cvtColor(img_origin, cv2.COLOR_BGR2GRAY)
	#template
	error = 10
	template = cv2.imread("crystalTemplate.jpg", 0)
	res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED) 
	threshold = 0.7 
	loc = np.where( res >= threshold)	
	
	blue = img_origin[loc[0] + 6, loc[1] + 4, 0].astype(np.int64) - 255
	green = img_origin[loc[0] + 6, loc[1] + 4, 1].astype(np.int64) - 194
	red = img_origin[loc[0] + 6, loc[1] + 4, 2].astype(np.int64) - 4
	error_blue_square = blue.astype(np.int64) ** 2
	error_green_square = green.astype(np.int64) ** 2
	error_red_square = red.astype(np.int64) ** 2
	error_cal = np.sqrt(error_blue_square + error_green_square + error_red_square)
	result_loc = np.where(error_cal < error)
	
	if len(result_loc[0]) != 0:
		###########print ("crystal detected")
		flag = True
		result = result_loc[0][0]
		final_loc = [loc[0][result] + 43, loc[1][result] + 8] # in coordinates [img_origin]
	else:
		final_loc = np.array([0, 0])
	final_position = [final_loc[0], final_loc[1]]
	cv2.destroyAllWindows() 
	return flag, final_position
	
def distance2click_time(distance):
	click_time = distance / 355 #355
	return click_time

def if_game_over():
	return game_over
	
#def game_restart():	
	
game_over = False
ready_game()

#MAIN
autoFlag = True
timeRecord = [] 
#initial the window
pos = win32api.GetCursorPos()
hwnd = win32gui.WindowFromPoint(pos)
win32gui.EnableWindow(hwnd, True)
win32gui.SetForegroundWindow(hwnd)
win32gui.ShowWindow(hwnd, win32con.SW_SHOWNORMAL)

#get coordinates of window
left, top, right, bottom = win32gui.GetWindowRect(hwnd)

#print (left, top, right, bottom)
window_hw_para = {"left": left, "top":top, 
"right":right, "bottom":bottom}

if autoFlag == True:
	beginDetect(hwnd,  window_hw_para)

mouse_move(right - 50, bottom - 50)
while True:
	#now = time.time()
	distance = distance_calculate(hwnd, window_hw_para)	
	##########print (distance)
	T = distance2click_time(distance)
	#now = time.time() - now
	#print("Algorithm takes " + str(now*1000)+"ms")
	mouse_click(T) #jump
	#timeRecord.append(now*1000)
	time.sleep(1.5)
	restart_detect(hwnd,  window_hw_para, timeRecord)

print ("Game over.")

猜你喜欢

转载自blog.csdn.net/Kuroyukineko/article/details/80782517
今日推荐