C++代碼實現(xiàn)掃雷游戲
前言
提示:本文是基于easyX圖形庫實現(xiàn)的,還有部分功能可以添加,僅適合新手參考。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、掃雷游戲模式
在確定大小的矩形雷區(qū)中隨機(jī)布置一定數(shù)量的地雷,玩家需要盡快找出雷區(qū)中的所有不是地雷的方塊,而不許踩到地雷。
游戲的基本操作包括左鍵單擊和右鍵單擊。其中左鍵用于打開安全的格子,推進(jìn)游戲進(jìn)度;右鍵用于標(biāo)記地雷,以輔助判斷。
左鍵單擊:在判斷出不是雷的方塊上按下左鍵,可以打開該方塊。如果方塊上出現(xiàn)數(shù)字,則該數(shù)字表示其周圍3×3區(qū)域中的地雷數(shù)(一般為8個格子,對于邊塊為5個格子,對于角塊為3個格子。所以掃雷中最大的數(shù)字為8);如果方塊上為空(相當(dāng)于0),則可以遞歸地打開與空相鄰的方塊;如果不幸觸雷,則游戲結(jié)束。
右鍵單擊:在判斷為地雷的方塊上按下右鍵,可以標(biāo)記地雷(顯示為小紅旗)。重復(fù)一次或兩次操作可取消標(biāo)記。
二、代碼實現(xiàn)
1.繪制地圖場景
根據(jù)每一塊地區(qū)的數(shù)據(jù)進(jìn)行圖形輸出。
代碼如下(示例):
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]);//標(biāo)記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.鼠標(biāo)點(diǎn)擊
鼠標(biāo)左鍵點(diǎn)擊翻開格子,右鍵點(diǎn)擊標(biāo)記flag,再次點(diǎn)擊可以進(jìn)行取消。
sum記錄翻開格子的數(shù)量,點(diǎn)擊后對每個位置的數(shù)據(jù)進(jìn)行加減操作。
代碼如下(示例):
int mousedown(int map[][12])
{
MOUSEMSG m; //定義鼠標(biāo)消息變量
while (1)
{
//獲取鼠標(biāo)消息
m = GetMouseMsg();
int mi = m.x / 50 + 1;
int mj = m.y / 50 + 1;
//判斷鼠標(biāo)消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:
if (map[mi][mj] > 9) //已翻開的情況
{
continue;
}
if (map[mi][mj] == 0) //如果點(diǎn)擊為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) //再次點(diǎn)擊取消flag
{
map[mi][mj] -= 30;
}
else
{
map[mi][mj] += 30;
}
return map[mi][mj];
break;
}
}
}
3.遞歸
當(dāng)我們點(diǎn)到為0的地區(qū)時,將會打開周圍的部分地區(qū),外圍為非0數(shù)或到達(dá)邊界,內(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ù)組下標(biāo)不能越界
if (i >= 1 && i <= 10 && j >= 1 && j <= 10)
{
//翻開的只能是數(shù)字
if (map[i][j] < 9)
{
//如果為0,則進(jìn)行遞歸。
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;
//隨機(jī)函數(shù)種子
srand((unsigned int)time(NULL));
//隨機(jī)生成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);
//點(diǎn)到地雷
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)點(diǎn)開的格子數(shù)
//聲明函數(shù)
void drawmap(int map[][12], IMAGE* img);
int mousedown(int map[][12]);
void swap(int map[][12], int mi, int mj);
//初始化游戲
//繪制地圖
//鼠標(biāo)點(diǎn)擊
//遞歸函數(shù)
int main()
{
while (1)
{
startgame();
if (MessageBox(hwnd, "再來一次", "結(jié)束游戲", MB_YESNO)==IDNO)
break;
}
//_getch(); //防止閃屏
closegraph();
return 0;
}
總結(jié)及運(yùn)行
提示:本代碼僅供參考,編譯器為visual studio
圖片資源可以在網(wǎng)上找找,將其放到對應(yīng)的目錄即可。
運(yùn)行結(jié)果如圖:


以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++調(diào)用Python基礎(chǔ)功能實例詳解
c++調(diào)用Python首先安裝Python,本文以win7為例,給大家詳細(xì)介紹C++調(diào)用Python基礎(chǔ)功能,需要的朋友參考下吧2017-04-04
VSCode搭建STM32開發(fā)環(huán)境的方法步驟
當(dāng)我們的工程文件比較大的時候,編譯一次代碼需要很久可能會花費(fèi)到四五分鐘,但是我們用vscode編寫和編譯的話時間就會大大縮減,本文就介紹一下VSCode搭建STM32開發(fā)環(huán)境,感興趣的可以了解一下2021-07-07
c++下使用windows api遍歷指定文件夾及其子文件夾中的文件
這篇文章主要介紹了c++下使用windows api遍歷指定文件夾及其子文件夾中的文件實現(xiàn)代碼,一般都是通過c++自帶的函數(shù)實現(xiàn)2021-07-07

