C++代碼實現(xiàn)掃雷游戲
前言
提示:本文是基于easyX圖形庫實現(xiàn)的,還有部分功能可以添加,僅適合新手參考。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、掃雷游戲模式
在確定大小的矩形雷區(qū)中隨機布置一定數(shù)量的地雷,玩家需要盡快找出雷區(qū)中的所有不是地雷的方塊,而不許踩到地雷。
游戲的基本操作包括左鍵單擊和右鍵單擊。其中左鍵用于打開安全的格子,推進游戲進度;右鍵用于標記地雷,以輔助判斷。
左鍵單擊:在判斷出不是雷的方塊上按下左鍵,可以打開該方塊。如果方塊上出現(xiàn)數(shù)字,則該數(shù)字表示其周圍3×3區(qū)域中的地雷數(shù)(一般為8個格子,對于邊塊為5個格子,對于角塊為3個格子。所以掃雷中最大的數(shù)字為8);如果方塊上為空(相當于0),則可以遞歸地打開與空相鄰的方塊;如果不幸觸雷,則游戲結(jié)束。
右鍵單擊:在判斷為地雷的方塊上按下右鍵,可以標記地雷(顯示為小紅旗)。重復一次或兩次操作可取消標記。
二、代碼實現(xiàn)
1.繪制地圖場景
根據(jù)每一塊地區(qū)的數(shù)據(jù)進行圖形輸出。
代碼如下(示例):
void drawmap(int map[][12],IMAGE *img) { int i, j; for (i = 1; i <= 10; i++) { for (j = 0; j <= 10; j++) { int x = 50 * (i - 1);//得到位置 int y = 50 * (j - 1); if (map[i][j]>25) { putimage(x, y, &img[9]);//標記flag } else { switch (map[i][j]) { case 9: putimage(x, y, &img[11]);//輸出圖片雷 break; case 10: putimage(x, y, &img[0]);//0 break; case 11: putimage(x, y, &img[1]);//1 break; case 12: putimage(x, y, &img[2]);//2 break; case 13: putimage(x, y, &img[3]);//3 break; case 14: putimage(x, y, &img[4]);//4 break; case 15: putimage(x, y, &img[5]);//5 break; case 16: putimage(x, y, &img[6]);//6 break; case 17: putimage(x, y, &img[7]);//7 break; case 18: putimage(x, y, &img[8]);//8 break; default: putimage(x, y, &img[10]);//地圖 break; } } } } }
2.鼠標點擊
鼠標左鍵點擊翻開格子,右鍵點擊標記flag,再次點擊可以進行取消。
sum記錄翻開格子的數(shù)量,點擊后對每個位置的數(shù)據(jù)進行加減操作。
代碼如下(示例):
int mousedown(int map[][12]) { MOUSEMSG m; //定義鼠標消息變量 while (1) { //獲取鼠標消息 m = GetMouseMsg(); int mi = m.x / 50 + 1; int mj = m.y / 50 + 1; //判斷鼠標消息 switch (m.uMsg) { case WM_LBUTTONDOWN: if (map[mi][mj] > 9) //已翻開的情況 { continue; } if (map[mi][mj] == 0) //如果點擊為0,則翻開一片。 { //使用遞歸函數(shù) swap(map, mi, mj); } else { map[mi][mj] += 10; sum += 1; } return map[mi][mj]; break; case WM_RBUTTONDOWN: if (map[mi][mj] > 9&& map[mi][mj] < 25) //已翻開的情況 { continue; } if (map[mi][mj] > 25) //再次點擊取消flag { map[mi][mj] -= 30; } else { map[mi][mj] += 30; } return map[mi][mj]; break; } } }
3.遞歸
當我們點到為0的地區(qū)時,將會打開周圍的部分地區(qū),外圍為非0數(shù)或到達邊界,內(nèi)部為0.
如圖:
代碼如下(示例):
void swap(int map[][12],int mi,int mj) { map[mi][mj] = 10; sum += 1; for (int i = mi - 1; i <= mi + 1; i++) { for (int j = mj - 1; j <= mj + 1; j++) { //數(shù)組下標不能越界 if (i >= 1 && i <= 10 && j >= 1 && j <= 10) { //翻開的只能是數(shù)字 if (map[i][j] < 9) { //如果為0,則進行遞歸。 if (map[i][j] == 0) { swap(map, i, j); } else { map[i][j] += 10; sum += 1; } } } } } }
4.初始化游戲
代碼如下(示例):
void startgame() { initgraph(500, 500); //初始化地圖500x500 int map[12][12] = { 0 }; int i,j,m,n; //隨機函數(shù)種子 srand((unsigned int)time(NULL)); //隨機生成10個雷 for (n = 0; n < 10;) { i = rand() % 10 + 1; //[1,10] j = rand() % 10 + 1; if (map[i][j] == 0) //排除本來就有雷的情況 { map[i][j] = -1; //-1表示有雷 n++; } } //產(chǎn)生數(shù)字 for (i = 1; i <= 10; i++) { for (j = 1; j <= 10; j++) { //排除是雷的情況 if (map[i][j] != -1) { for (m = i - 1; m <= i + 1; m++) //判斷周圍是否有雷 { for (n = j - 1; n <= j + 1; n++) { if (map[m][n] == -1) { map[i][j]++; } } } } } } IMAGE img[12]; //定義圖片變量 loadimage(&img[0], "E:\\C++ project\\minesweeping\\0.jpg", 50, 50); loadimage(&img[1], "E:\\C++ project\\minesweeping\\1.gif", 50, 50);//加載圖片 loadimage(&img[2], "E:\\C++ project\\minesweeping\\2.gif", 50, 50); loadimage(&img[3], "E:\\C++ project\\minesweeping\\3.gif", 50, 50); loadimage(&img[4], "E:\\C++ project\\minesweeping\\4.gif", 50, 50); loadimage(&img[5], "E:\\C++ project\\minesweeping\\5.gif", 50, 50); loadimage(&img[6], "E:\\C++ project\\minesweeping\\6.gif", 50, 50); loadimage(&img[7], "E:\\C++ project\\minesweeping\\7.gif", 50, 50); loadimage(&img[8], "E:\\C++ project\\minesweeping\\8.gif", 50, 50); loadimage(&img[9], "E:\\C++ project\\minesweeping\\flag.gif", 50, 50); loadimage(&img[10], "E:\\C++ project\\minesweeping\\地圖.gif", 50, 50); loadimage(&img[11], "E:\\C++ project\\minesweeping\\雷.gif", 50, 50); while (1) { drawmap(map, img); //點到地雷 if (mousedown(map)==9) { sum = 0; //重置判斷變量 drawmap(map, img); MessageBox(hwnd,"你踩到雷了!","Game Over",MB_OK); return; } //成功完成游戲 if (sum == 90) { sum = 0; //重置判斷變量 drawmap(map, img); MessageBox(hwnd, "你成功完成了游戲!", "Game Over", MB_OK); return; } } }
5.main
代碼如下(示例):
#include<iostream> #include<time.h> #include<graphics.h> //圖形庫頭文件 easyx #include <conio.h> //調(diào)用_getch函數(shù) using namespace std; HWND hwnd; int sum = 0;//用于表示目前已經(jīng)點開的格子數(shù) //聲明函數(shù) void drawmap(int map[][12], IMAGE* img); int mousedown(int map[][12]); void swap(int map[][12], int mi, int mj); //初始化游戲 //繪制地圖 //鼠標點擊 //遞歸函數(shù) int main() { while (1) { startgame(); if (MessageBox(hwnd, "再來一次", "結(jié)束游戲", MB_YESNO)==IDNO) break; } //_getch(); //防止閃屏 closegraph(); return 0; }
總結(jié)及運行
提示:本代碼僅供參考,編譯器為visual studio
圖片資源可以在網(wǎng)上找找,將其放到對應的目錄即可。
運行結(jié)果如圖:
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++調(diào)用Python基礎(chǔ)功能實例詳解
c++調(diào)用Python首先安裝Python,本文以win7為例,給大家詳細介紹C++調(diào)用Python基礎(chǔ)功能,需要的朋友參考下吧2017-04-04VSCode搭建STM32開發(fā)環(huán)境的方法步驟
當我們的工程文件比較大的時候,編譯一次代碼需要很久可能會花費到四五分鐘,但是我們用vscode編寫和編譯的話時間就會大大縮減,本文就介紹一下VSCode搭建STM32開發(fā)環(huán)境,感興趣的可以了解一下2021-07-07c++下使用windows api遍歷指定文件夾及其子文件夾中的文件
這篇文章主要介紹了c++下使用windows api遍歷指定文件夾及其子文件夾中的文件實現(xiàn)代碼,一般都是通過c++自帶的函數(shù)實現(xiàn)2021-07-07