要實現一個自動完成windowsXP掃雷遊戲(winmine,XP下用這個命令可啟動遊戲)的程式,需要實現下面三大點:
- 擷取遊戲資料,即分析遊戲在類型(初級、中級還是進階),每個塊是否揭開,如何揭開了上面的數字是多少。
- 分析資料,即要從上面所得的資料,分析出哪些塊是雷,哪些不是雷,哪些還不能確定。
- 從第二步得到的資料中,操作滑鼠去點擊那些確定沒有雷的塊。
下面詳細介紹自己如何?第一步和第三步(分析資料,留到後面的文章中介紹):
一、擷取遊戲資料
為了簡化處理,自己只研究XP系統下內建的掃雷。後來自己的電腦被迫升級到win7後,將XP下的掃雷遊戲複製過來,繼續實現。
用FindWindow(NULL,_T("掃雷"))尋找到掃雷遊戲的表單控制代碼,用表單控制代碼找到表單所在的地區。再截取到整個螢幕的映像(詳見http://www.cnblogs.com/xiangism/archive/2012/06/21/2557901.html),這樣即可擷取遊戲情境的像素資訊,接下面的任務即是通過分析像素值完成任務。
遊戲情境,
可以發現每個數位顏色都不一樣,故可以通過顏色特徵判斷出每個塊上分別是什麼數字。下面分別是從1-8這些數位顏色RGB值
{255,0,0},
{0,128,0},
{0,0,255},
{128,0,0},
{0,0,128},
{128,128,0},
{0,0,0},
{128,128,128} RGB從右往左排列。
沒有揭開的塊,上面和左面會有白色地區,通過這個資訊即可判斷出塊是否被揭開。
而遊戲類型的判斷,則是通過表單視窗的大小實現,初級的遊戲視窗寬是170,中級為282,進階為506~~
二、操作遊戲
如果已經從擷取的資料中分析出了哪些塊不是雷,那麼即可自動點擊。這裡使用的方法是用控制項滑鼠的win32API去點擊。即
//將確定沒有雷的方塊座標i,j,轉化成滑鼠要點擊的像素座標。//m_gameRect是表單相對於案頭的座標,firstClick是第一塊相對於表單的座標,width是每一個塊的寬度int x= m_gameRect.left + firstClick.first + i*width; int y= m_gameRect.top + firstClick.second +j*width; SetCursorPos(x,y);mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0);mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);
還有一種方式,即是向遊戲表單發現滑鼠點擊的訊息,
SendMessage(m_gameHandle,WM_LBUTTONDOWN,1,r);
SendMessage(m_gameHandle,WM_LBUTTONUP,1,r);
不過這種方式,只能在xp下用,在win7下有點問題,為了統一,就都用mouse_event了。
下面是整個程式的UML靜態類圖
從上面的類圖可以看出,開始也想支援win7的內建掃雷遊戲,可發現win7掃雷太過花哨,數字都是用漸層色顯示的,不過開始為了挑戰下自己的實力,想用影像處理、模式識別的相關知識來擷取遊戲資訊,可在實現過程中一不小心把win7下的掃雷遊戲弄成這樣了(好像是在某一個操作滑鼠點擊遊戲介面時弄成這樣的)。
奇大無比 並且也沒辦法還原回去了,於是放棄了對win7掃雷的支援。只專註與實現自己想要實現的東西.對於win7系統,自己的做法是將xp中的那個掃雷程式複製過來,即可。