C語言小游戲之掃雷
- 一.游戲介紹
- 二.游戲步驟及實作的功能
- 1.初始化雷盤
- 2.列印雷盤
- 3.隨機布置雷
- 4.玩家排雷
- 5.防止玩家第一次被炸死
- 6.統計所選位置周圍八個位置中雷的個數
- 7.拓展已選位置周圍的區域
- 8.標記雷及取消標記
一.游戲介紹

看到這張圖片,相信很多小伙伴都非常熟悉,很多小伙伴都玩過掃雷這個小游戲,掃雷是一款益智類游戲,在放松娛樂的同時可以鍛煉各位小伙伴的智商,
游戲規則:如上圖,玩家需要在不被炸死的前提下找出圖中雷的位置,若能找出所有雷,則游戲勝利,若不幸踩到雷則被炸死,
注:先介紹程式實作的主要功能,后文會有完整代碼
二.游戲步驟及實作的功能
(一) 游戲步驟
- 程式開始執行時玩家需要選擇是否開始游戲,輸入1則游戲開始,輸入0則退出游戲

- show地圖出現后玩家開始選擇進行選擇,輸入1則開始選擇區域,輸入2則可以標記自己認為是雷的區域,輸入3則可以取消原先被標記的區域

- 當所有非雷區域全部被排出來后則游戲勝利
//遍歷show地圖,以便判斷最后的勝利
int Travel(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int win = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*' || show[i][j] == '!')
{
win++;
}
}
}
return win;
}
以下為效果圖:

(二)實作的功能
- 初始化雷盤
- 列印雷盤
- 隨機布置雷
- 玩家開始排雷
- 防止玩家第一次被雷炸死.
- 統計所選位置周圍八個位置中雷的個數
- 拓展已選位置周圍的區域
- 標記雷及取消標記
1.初始化雷盤
初始化雷盤時需要構造兩個二維陣列,一個陣列(mine陣列)里面是存放雷的,用于實作各種功能,另一個陣列(show陣列)是給玩家操作時看的,看不到雷的具體位置,
由于需要統計每個位置周圍八個區域中雷的個數,在統計最邊緣的位置時為了利于功能的實作,在初始化雷盤時構建的二維陣列mine陣列的行和列比show陣列多兩行兩列,
//初始化雷盤
//主函式中函式的呼叫
//Initboard(mine, ROWS, COLS,'0');
//Initboard(show, ROWS, COLS, '*');
void Initboard(char board[ROWS][COLS], int rows, int cols,char set)
{
int i = 0, j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
初始化雷盤時,mine陣列全部初始化為字符‘0’,show陣列全部初始化為字符‘*’,
2.列印雷盤
玩家需要通過列印出的show陣列雷盤進行游戲,列印雷盤時將行號和列號全部列印出來有利于玩家進行操作
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0, j = 0;
//列印列號
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
雷盤列印如下:

3.隨機布置雷
在show陣列中,用字符‘0’表示無雷區域,用字符‘1’表示有雷區域,由于第一個步驟中已經將show陣列全部初始化為字符‘0’了,故只需使用srand和rand函式生成亂數,使得雷的分布為隨機位置,
//隨機布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
int count = EASY_COUNT;
while (count)
{
x = rand() % row+1;
y = rand() % col+1;
if (board[x][y] != '1')
{
board[x][y] = '1';
count--;
}
}
}
4.玩家排雷
玩家根據show陣列展示出的地圖開始排雷,選擇自己認為不是雷的區域
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int ch = 0;
int flag_count = 0;
int win = 0;
int fch = 1;//用來標記玩家是否為第一次排雷
while (1)
{
menu1();
scanf("%d", &ch);
if (ch == 1)
{
int x = 0, y = 0;
printf("請開始排雷:>");
scanf("%d%d", &x, &y);
//判斷坐標合法
if (x <= row && x > 0 && y > 0 && y <= col)
{
//判斷玩家是否是第一次排雷
if (fch == 1 && mine[x][y] == '1')
{
//是第一次排雷
ChangePlace(mine, row, col, x, y);
fch++;
}
else
{
//判斷是否踩雷
if (mine[x][y] == '1')
{
printf("游戲結束\n");
printf("恭喜你,踩到雷了\n");
DisplayBoard(mine, row, col);
break;
}
else
{
broad(mine, show, x, y);
DisplayBoard(show, row, col);
}
fch++;
}
}
else
{
printf("輸入坐標不合法,請重新輸入\n");
}
}
else if (ch == 2)
{
printf("請開始標記雷:>\n");
Flagmine(show, row, col, flag_count);
DisplayBoard(show, row, col);
}
else if (ch == 3)
{
printf("請選擇要取消標記的位置:>\n");
Cancelflag(show, row, col, flag_count);
DisplayBoard(show, row, col);
}
//遍歷show地圖(改進)
win=Travel(show, row, col);
if (win == EASY_COUNT)
break;
}
if (win == EASY_COUNT)
{
printf("恭喜你,游戲勝利\n");
}
}
5.防止玩家第一次被炸死
如果玩家第一次就踩雷,則提示玩家重新選擇,并將該位置的雷重新隨機布置,
//防止玩家第一次排雷被炸死
void ChangePlace(char mine[ROWS][COLS], int row, int col, int x, int y)
{
x = rand() % row;
y = rand() % col;
mine[x][y] = '1';
printf("第一次就踩雷了,重新選擇\n");
}

6.統計所選位置周圍八個位置中雷的個數
統計已選位置周圍八個位置中含有雷的個數,并在該位置上數字的形式列印出來,
//計算坐標周圍雷的個數
int get_mine(char mine[ROWS][COLS], int x, int y)
{
return mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x][y - 1] +
mine[x + 1][y - 1] +
mine[x + 1][y] +
mine[x + 1][y + 1] +
mine[x][y + 1] +
mine[x - 1][y + 1]-8*'0';
}
此處由于陣列mine中存放的是字符’0’,而不是數字0,故當統計完八個位置后需要減去字符’0’之后回傳為數字,
7.拓展已選位置周圍的區域
以遞回的方式拓展式排雷,
//拓展周圍不是雷的區域
void broad(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
//判斷坐標是否越界
if (x == 0 || y == 0 || x == ROWS - 1 || y == COLS - 1)
return;
//判斷是否已經被排除
if (show[x][y] != '*')
{
return;
}
int count = get_mine(mine, x, y);
if (count > 0)
{
show[x][y] = count + '0';
return;
}
//遞回拓展地圖
else if (count == 0)
{
show[x][y] = '0';
broad(mine, show, x - 1, y);
broad(mine, show, x - 1, y - 1);
broad(mine, show, x, y - 1);
broad(mine, show, x + 1, y - 1);
broad(mine, show, x + 1, y);
broad(mine, show, x + 1, y + 1);
broad(mine, show, x, y + 1);
broad(mine, show, x - 1, y + 1);
}
}
效果如下:

8.標記雷及取消標記
玩家可以通過輸入坐標對自己覺得是雷的位置進行標記,標記后為‘!’,如果覺得不是也可以取消標記,
//標記雷
void Flagmine(char show[ROWS][COLS], int row, int col,int flag_count)
{
int x = 0, y = 0;
//判斷標記數與雷數是否相等
if (flag_count == EASY_COUNT)
{
printf("標記的雷數和實際存在的雷數相等,無法再標記\n");
return;
}
printf("請輸入你要標記位置的坐標:>\n");
scanf("%d%d", &x, &y);
//判斷坐標是否合法
if (x > 0 && x <= row && y > 0 && y <= col)
{
//判斷該坐標是否仍未被排除
if (show[x][y]=='*')
{
show[x][y] = '!';
flag_count++;
}
else
{
printf("該位置不可能是雷,請重新輸入\n");
}
}
else
{
printf("該坐標不合法,請重新輸入:>\n");
}
}
//取消標記
void Cancelflag(char show[ROWS][COLS], int row, int col, int flag_count)
{
int x = 0;
int y = 0;
scanf("%d%d", &x, &y);
//判斷坐標是否合法
if (x > 0 && x <= row && y > 0 && y <= col)
{
//判斷該位置是否被標記過
if (show[x][y] == '!')
{
show[x][y] = '*';
flag_count--;
}
else
printf("該位置未被標記過,無需取消標記\n");
}
else
{
printf("該坐標不合法,請重新輸入:>\n");
}
}
圖中‘!’即為標記區域

綜上,此程式基本實作了掃雷小游戲的功能,有一定的娛樂性,各位小伙伴感興趣的話可以玩一把,
源代碼鏈接:掃雷完整版源代碼
各位大佬有建議可以多多交流,歡迎評論區討論,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/351131.html
標籤:其他
