日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Windows扫雷的设计思路与实现

發布時間:2024/3/26 windows 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Windows扫雷的设计思路与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????? 最近花了個把星期左右把Windows xp的掃雷實現了一下,在這里寫下設計思路與大概實現。這個是下載地址,

歡迎大家下載試玩,http://kuai.xunlei.com/d/LTACJFIRFVKB。其實其中還有有個隱藏的bug。看看你能不能發現,哈哈。源代碼我以后會補上,暫時不能上傳,請各位諒解!

???? 既然是游戲的話,只有會玩了才有可能知道是怎么實現的!數字n代表以它為中心3*3的方格范圍內

有n個雷。主要就是根據這個來判斷是否有雷。然后是空格子的話就代表它周圍沒有雷。然后就是鼠標的各種事件了。下面這個是一個列表。

之后主要是按照這個寫的,也有些改動,但是不大。

1.左鍵按下
?1.1.右鍵按下
??3*3方格變形
?1.2.右鍵未被按下
??當前方格變形
LBtnDown = TRUE;
2.右鍵按下
?2.1.左鍵按下
??3*3方格變形
?2.1.左鍵未被按下
??當前方格變形
RBtnDown = TRUE;
3.左鍵彈起
?3.1.之前左右鍵按下
??3.1.1.該數字的雷被找到
???調用展開算法 右鍵彈起失效
???RBtnDown = FALSE;
??3.1.2.沒找到
???3*3方格復原 右鍵彈起失效

???標記標多了也會調用展開算法
???RBtnDown = FALSE;??
?3.2.之前左鍵按下
??當前位置方格調用展開算法
LBtnDown = FALSE;
4.右鍵彈起
?4.1.之前左右鍵按下
??4.1.1.該數字的雷被找到
???調用展開算法 左鍵彈起失效
???LBtnDown = FALSE;
??4.1.2.沒找到
???3*3方格復原 左鍵彈起失效

?標記標多了也會調用展開算法
???LBtnDown = FALSE;
RBtnDown = FALSE;
5.鼠標滾動
?5.1.左鍵按下
??5.1.1.右鍵按下
???3*3方格移動
??5.1.2.右鍵彈起
???一個方格移動

這個是雷區初始化的代碼。主要就是先寫邊界,然后把前面n個元素改成雷,最后隨機分布。

?

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;//初始化雷區}}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;//初始化雷區}}for (j = 1; j <= currentj; j++) {m_mineMax[currenti][j] = -1;//初始化雷區}currentj++;}//初始化不是雷區的區域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;//產生的隨機位置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) {//就是第一個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]);} }


?? 展開算法的主要思路就是用一個大的數組(包括虛擬邊界)保存該算法對每一個方格的訪問次數的計數。

==1就不在訪問,分8個方向遞歸探測。碰到雷或者邊界就返回。具體代碼如下:

?

//8個方向探測 void CMineView::StretchMine(int i, int j) {if (m_mineVisit[i][j] == 1) {//走過的路不再走return ;}if (m_mineMax[i][j] == -2) {//碰壁了return ;}if (m_mineMax[i][j] == -1) {//撞雷了return ;} else {//上右下左遞歸探測if (m_minePic[i][j] != 1) {m_minePic[i][j] = 15 - m_mineMax[i][j];//根據位圖中數字的關系得到的公式} else {m_minePic[i][j] = 4;}if (m_mineMax[i][j] > 0) {//碰到了數字 就停止m_mineVisit[i][j] = 1;//已訪問return ;}m_mineVisit[i][j] = 1;//只有走得通的路才會被訪問,訪問次數+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);

之前碰到困難就是各個類直接自定義消息所用的句柄的獲取,最難的那個就是模態對話框和CMainFrame類的通信,最后發現,模態對話框在DoModal

之前會調用oninitdialog,在oninitdialog里面可以把句柄傳出來,這才實現了不同級別的繪制。然后就是繪圖了,主要還是用到了雙緩沖,之前雙緩沖

用的很不正宗,后來改了改,用了3個cdc對象,一個選擇位圖,一個裝圖像,然后把這個最后bitblt到pDC當中。這樣就避免了屏幕閃爍。

?繪圖代碼很固定。鼠標的各種消息會改變繪圖的數據,實現了動態繪制。我感覺難點還是在于理解鼠標各個事件。我花了1天多時間,結果沒

寫好,之后冷靜了想了下,然后把各種消息記錄下來。用的多的代碼寫成函數方便調用。

? 本身掃雷沒啥難的,只要你會玩了,你就基本上知道怎么寫了。就說這多把。大學已經結束了,已經要開始找工作了,這里預祝和我一樣的這些畢業生

早點找到一個合適的工作!90后 up!You can make it!

總結

以上是生活随笔為你收集整理的Windows扫雷的设计思路与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。