作者doghib (lun)
看板Python
標題[範例] MSN寶石方塊機器人
時間Sat Jan 26 22:22:45 2008
import psyco
psyco.full()
import wx, win32api, win32con, time
from PIL import Image, ImageEnhance, ImageGrab
#從像素中找出顏色
def ColorTable(pixel):
if pixel[0] == pixel[1] == pixel[2]:
return 'W'
elif pixel[0] >200:
if pixel[2] == 0:
if pixel[1] == 0:
return 'R'
elif pixel[1] == 255:
return 'Y'
elif pixel[1] > 0:
return 'O'
elif pixel[2] > 200:
return 'M'
else:
return '?'
elif pixel[1] == 255:
if pixel[0] == pixel[2] == 0:
return 'G'
elif pixel[2] == 255:
return 'C'
else:
return '?'
else:
return '?'
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="MSN",
size=(424,768), pos=(0,0),
style=wx.DEFAULT_FRAME_STYLE ^ wx.MAXIMIZE_BOX | wx.STAY_ON_TOP )
p = wx.Panel(self)
self.going = True
self.box = (618, 205, 978, 565)
self.find = False
self.pos = ''
self.last = ''
self.allow = 0
#開始鈕
start = wx.Button(p, -1, "Start", pos=(200, 700))
self.Bind(wx.EVT_BUTTON, self.OnStart, start)
def OnStart(self, evt):
#初始位置設定(畫面為1024 * 768,MSN寶石方塊往左拉到最大)
x = 640
y = 225
while 1:
#影響處理
self.ImageHandle()
self.last = self.pos
self.find = False
time.sleep(2)
def Move(self):
if self.find:
win32api.SetCursorPos([x + int(self.pos[0][0]*45), y +
int(self.pos[0][1]*45)])
time.sleep(0.4)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
time.sleep(0.1)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
win32api.SetCursorPos([x + int(self.pos[1][0]*45), y +
int(self.pos[1][1]*45)])
time.sleep(0.2)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
time.sleep(0.1)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
else:
time.sleep(1)
def ImageHandle(self):
#從畫面擷取影像,效果同等於 PrintScreen
Im = ImageGrab.grab(self.box)
#顏色加強
color = ImageEnhance.Color(Im)
im = color.enhance(25)
count = 0
double_check = {}
V_table = {}
for i in range(8):
V_table[i] = []
y = 25
i = 0
#從擷取下來的影像中,依照特定位置獲得像素,並傳回顏色
while y < im.size[1]:
x = 22
while x < im.size[0]:
V_table[i].append(ColorTable(im.getpixel((x, y))))
#如果顏色為紅色、沒有、或是未知,則要做進一步確認(橘色加強後可
能判斷為紅色)
if V_table[i][-1] == 'R' or not V_table[i][-1] or
V_table[i][-1] == '?':
double_check[count] = {}
#紀錄哪一列、第幾個、與畫面位置
double_check[count]['row'] = i
double_check[count]['index'] = len(V_table[i]) -1
double_check[count]['pos'] = ((x, y))
count += 1
x += 45
i += 1
y += 45
#加強係數降低,使顏色判別有更多條件
im = color.enhance(5)
i = 0
while i < count:
pos = double_check[i]['pos']
t = ColorTable(im.getpixel((pos[0] - 3, pos[1]-17)))
#將確認之後結果回傳
V_table[double_check[i]['row']][double_check[i]['index']] = t
i += 1
#尋找配對之結果,先尋找縱向(上下三個),再尋找橫向(左右三個)
self.Find(7, 7, V_table)
self.Find(7, 0, V_table)
self.Find(0, 7, V_table)
self.Find(0, 0, V_table)
if self.find:
self.pos = ((self.pos[0][1], self.pos[0][0]), (self.pos[1][1],
self.pos[1][0]))
return
H_table = {}
for i in range(8):
H_table[i] = []
for j in range(8):
H_table[i].append(V_table[j][i])
self.Find(7, 7, H_table)
self.Find(7, 0, H_table)
self.Find(0, 7, H_table)
self.Find(0, 0, H_table)
#尋找配對,寶石方塊為8*8,再此分割成為4個4*4,並利用類似象限分法判別
def Find(self, X, Y, table):
y = 0
if X == 0:
x_sign = 1
else:
x_sign = -1
if Y == 0:
y_sign = 1
else:
y_sign = -1
while y < 4 and not self.find:
y = abs(Y - y)
x = 0
while x < 4 and not self.find:
x = abs(X - x)
if table[x][y] == table[x+1*x_sign][y]:
#1 xxox
if table[x][y] == table[x + 3*x_sign][y]:
self.find = True
self.pos = ((x + 2*x_sign, y), (x + 3*x_sign, y))
#2 xxo
# x
elif table[x][y] == table[x+2*x_sign][y+1*y_sign]:
self.find = True
self.pos = ((x + 2*x_sign, y), (x + 2*x_sign, y +
1*y_sign))
if (x > 0 and x_sign == 1) or (x < 7 and x_sign == -1):
#3 oxx
# x
if table[x][y] == table[x -1*x_sign][y+1*y_sign]:
self.find = True
self.pos = ((x - 1*x_sign, y), (x - 1*x_sign, y +
1*y_sign))
if (x > 1 and x_sign == 1) or (x < 6 and x_sign == -1):
#4 xoxx
if table[x][y] == table[x-2*x_sign][y]:
self.find = True
self.pos = ((x-1*x_sign, y), (x-2*x_sign, y))
if (y > 0 and y_sign == 1) or (y < 7 and y_sign == -1):
#5 x
# xxo
if table[x][y] == table[x+2*x_sign][y-1*y_sign]:
self.find = True
self.pos = ((x + 2*x_sign, y), (x + 2*x_sign, y -
1*y_sign))
if (x > 0 and x_sign == 1) or (x < 7 and x_sign ==
-1):
#6 x
# o xx
if table[x][y] == table[x -1*x_sign][y -1*y_sign]:
self.find = True
self.pos = ((x -1*x_sign, y), (x -1*x_sign, y
- 1*y_sign))
elif table[x][y] == table[x + 2*x_sign][y]:
#1 xox
# x
if table[x][y] == table[x + 1*x_sign][y + 1*y_sign]:
self.find = True
self.pos = ((x + 1*x_sign, y), (x + 1*x_sign, y +
1*y_sign))
#2 x
# xox
if (y > 0 and y_sign == 1) or (y < 7 and y_sign == -1):
if table[x][y] == table[x + 1*x_sign][y - 1*y_sign]:
self.find = True
self.pos = ((x + 1*x_sign, y), (x + 1*x_sign, y -
1*y_sign))
if self.find:
if self.pos == self.last:
if self.allow < 2:
self.allow += 1
else:
self.find = False
self.allow = 0
else:
self.allow = 0
x = abs(x - X)
x += 1
y = abs(y - Y)
y += 1
app = wx.PySimpleApp()
frm = MyFrame()
frm.Show()
app.MainLoop()
程式跑一跑大概五萬多就掛了,這邊大概提到怎麼擷取螢幕還有一些影像處理動作
這邊只寫了基本的一種比對,給大家參考參考
不過程式要結束比較麻煩因為他一直在跑迴圈...
最好是用直接點兩下的方式開啟,要結束Alt + Tab & Ctrl + F4結束掉
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 122.127.53.38
※ 編輯: doghib 來自: 122.127.53.38 (01/26 22:29)
推 rs6000:雖然看不懂~不過還是支持大大:) 01/26 23:04
推 blc:如果可以對應directx的遊戲… (邪笑) 01/27 10:32