Windows扫雷的设计思路与实现
????? 最近花了個(gè)把星期左右把Windows xp的掃雷實(shí)現(xiàn)了一下,在這里寫(xiě)下設(shè)計(jì)思路與大概實(shí)現(xiàn)。這個(gè)是下載地址,
歡迎大家下載試玩,http://kuai.xunlei.com/d/LTACJFIRFVKB。其實(shí)其中還有有個(gè)隱藏的bug。看看你能不能發(fā)現(xiàn),哈哈。源代碼我以后會(huì)補(bǔ)上,暫時(shí)不能上傳,請(qǐng)各位諒解!
???? 既然是游戲的話,只有會(huì)玩了才有可能知道是怎么實(shí)現(xiàn)的!數(shù)字n代表以它為中心3*3的方格范圍內(nèi)
有n個(gè)雷。主要就是根據(jù)這個(gè)來(lái)判斷是否有雷。然后是空格子的話就代表它周?chē)鷽](méi)有雷。然后就是鼠標(biāo)的各種事件了。下面這個(gè)是一個(gè)列表。
之后主要是按照這個(gè)寫(xiě)的,也有些改動(dòng),但是不大。
1.左鍵按下
?1.1.右鍵按下
??3*3方格變形
?1.2.右鍵未被按下
??當(dāng)前方格變形
LBtnDown = TRUE;
2.右鍵按下
?2.1.左鍵按下
??3*3方格變形
?2.1.左鍵未被按下
??當(dāng)前方格變形
RBtnDown = TRUE;
3.左鍵彈起
?3.1.之前左右鍵按下
??3.1.1.該數(shù)字的雷被找到
???調(diào)用展開(kāi)算法 右鍵彈起失效
???RBtnDown = FALSE;
??3.1.2.沒(méi)找到
???3*3方格復(fù)原 右鍵彈起失效
???標(biāo)記標(biāo)多了也會(huì)調(diào)用展開(kāi)算法
???RBtnDown = FALSE;??
?3.2.之前左鍵按下
??當(dāng)前位置方格調(diào)用展開(kāi)算法
LBtnDown = FALSE;
4.右鍵彈起
?4.1.之前左右鍵按下
??4.1.1.該數(shù)字的雷被找到
???調(diào)用展開(kāi)算法 左鍵彈起失效
???LBtnDown = FALSE;
??4.1.2.沒(méi)找到
???3*3方格復(fù)原 左鍵彈起失效
?標(biāo)記標(biāo)多了也會(huì)調(diào)用展開(kāi)算法
???LBtnDown = FALSE;
RBtnDown = FALSE;
5.鼠標(biāo)滾動(dòng)
?5.1.左鍵按下
??5.1.1.右鍵按下
???3*3方格移動(dòng)
??5.1.2.右鍵彈起
???一個(gè)方格移動(dòng)
這個(gè)是雷區(qū)初始化的代碼。主要就是先寫(xiě)邊界,然后把前面n個(gè)元素改成雷,最后隨機(jī)分布。
?
void CMineView::SetMine() {int i, j, currenti, currentj, i1, i2, j1, j2;currenti = m_mine.minenumber % m_mine.width;if (currenti == 0) {//剛好除盡currenti = m_mine.minenumber/m_mine.width;currentj = m_mine.width;for (i = 1; i <= currenti; i++) {for (j = 1; j <= m_mine.width; j++) {m_mineMax[i][j] = -1;//初始化雷區(qū)}}currenti++;currentj = 1;} else {//除不盡currenti = (m_mine.minenumber/m_mine.width)+1;currentj = m_mine.minenumber%m_mine.width;for (i = 1; i < currenti; i++) {for (j = 1; j <= m_mine.width; j++) {m_mineMax[i][j] = -1;//初始化雷區(qū)}}for (j = 1; j <= currentj; j++) {m_mineMax[currenti][j] = -1;//初始化雷區(qū)}currentj++;}//初始化不是雷區(qū)的區(qū)域for (j = currentj; j <= m_mine.width; j++) {m_mineMax[currenti][j] = 0;}++currenti;for (i = currenti; i <= m_mine.height; i++) {for (j = 1; j <= m_mine.width; j++) {m_mineMax[i][j] = 0;}}srand(time(NULL));for (i = m_mine.height * m_mine.width - 1; i >= 2; --i) {//布雷currenti = rand() % i;//產(chǎn)生的隨機(jī)位置if (i%m_mine.width == 0) {//除的盡i1 = i / m_mine.width;j1 = m_mine.width;} else {//除不盡i1 = (i / m_mine.width) + 1;j1 = i % m_mine.width;}if (currenti == 0) {//就是第一個(gè)i2 = 1;j2 = 1;} else {if (currenti%m_mine.width == 0) {//除的盡i2 = currenti / m_mine.width;j2 = m_mine.width;} else {//除不盡i2 = (currenti / m_mine.width) + 1;j2 = currenti % m_mine.width;}}Swap(&m_mineMax[i1][j1], &m_mineMax[i2][j2]);} }
?? 展開(kāi)算法的主要思路就是用一個(gè)大的數(shù)組(包括虛擬邊界)保存該算法對(duì)每一個(gè)方格的訪問(wèn)次數(shù)的計(jì)數(shù)。
==1就不在訪問(wèn),分8個(gè)方向遞歸探測(cè)。碰到雷或者邊界就返回。具體代碼如下:
?
//8個(gè)方向探測(cè) void CMineView::StretchMine(int i, int j) {if (m_mineVisit[i][j] == 1) {//走過(guò)的路不再走return ;}if (m_mineMax[i][j] == -2) {//碰壁了return ;}if (m_mineMax[i][j] == -1) {//撞雷了return ;} else {//上右下左遞歸探測(cè)if (m_minePic[i][j] != 1) {m_minePic[i][j] = 15 - m_mineMax[i][j];//根據(jù)位圖中數(shù)字的關(guān)系得到的公式} else {m_minePic[i][j] = 4;}if (m_mineMax[i][j] > 0) {//碰到了數(shù)字 就停止m_mineVisit[i][j] = 1;//已訪問(wèn)return ;}m_mineVisit[i][j] = 1;//只有走得通的路才會(huì)被訪問(wèn),訪問(wèn)次數(shù)+1StretchMine(i-1, j-1);StretchMine(i-1, j);//上邊StretchMine(i-1, j+1);StretchMine(i, j+1);//右邊StretchMine(i+1, j);//下邊StretchMine(i+1, j-1);StretchMine(i+1, j+1);之前碰到困難就是各個(gè)類直接自定義消息所用的句柄的獲取,最難的那個(gè)就是模態(tài)對(duì)話框和CMainFrame類的通信,最后發(fā)現(xiàn),模態(tài)對(duì)話框在DoModal
之前會(huì)調(diào)用oninitdialog,在oninitdialog里面可以把句柄傳出來(lái),這才實(shí)現(xiàn)了不同級(jí)別的繪制。然后就是繪圖了,主要還是用到了雙緩沖,之前雙緩沖
用的很不正宗,后來(lái)改了改,用了3個(gè)cdc對(duì)象,一個(gè)選擇位圖,一個(gè)裝圖像,然后把這個(gè)最后bitblt到pDC當(dāng)中。這樣就避免了屏幕閃爍。
?繪圖代碼很固定。鼠標(biāo)的各種消息會(huì)改變繪圖的數(shù)據(jù),實(shí)現(xiàn)了動(dòng)態(tài)繪制。我感覺(jué)難點(diǎn)還是在于理解鼠標(biāo)各個(gè)事件。我花了1天多時(shí)間,結(jié)果沒(méi)
寫(xiě)好,之后冷靜了想了下,然后把各種消息記錄下來(lái)。用的多的代碼寫(xiě)成函數(shù)方便調(diào)用。
? 本身掃雷沒(méi)啥難的,只要你會(huì)玩了,你就基本上知道怎么寫(xiě)了。就說(shuō)這多把。大學(xué)已經(jīng)結(jié)束了,已經(jīng)要開(kāi)始找工作了,這里預(yù)祝和我一樣的這些畢業(yè)生
早點(diǎn)找到一個(gè)合適的工作!90后 up!You can make it!
總結(jié)
以上是生活随笔為你收集整理的Windows扫雷的设计思路与实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 5G蝴蝶效应:孕育万亿级产业
- 下一篇: 精灵混合加密系统_为什么要加密数据?