C語(yǔ)言掃雷詳細(xì)代碼分步實(shí)現(xiàn)流程
還是說(shuō)一下:發(fā)的這些小游戲都是第一個(gè)版本,之后改進(jìn)的話都會(huì)在標(biāo)題中聲明。
上一個(gè)游戲三子棋:
? ? ? ? ? ? >>?C語(yǔ)言三子棋一步步實(shí)現(xiàn)詳程<<
來(lái)看這次掃雷游戲的思路:
? ? ? ? ? ? ? ? ?1.創(chuàng)建游戲界面菜單
? ? ? ? ? ? ? ? ? 2.創(chuàng)建游戲內(nèi)容:
? ? ? ? ? ? 初始化場(chǎng)景? 打印場(chǎng)景?
? ? ? ? ? ? 埋雷? ? ? ? ? +?? ? ? ? 掃雷?
依舊是:
? ? ? ? ? 創(chuàng)建 game.h 頭文件來(lái)聲明函數(shù)
? ? ? ? ? 創(chuàng)建 game.c 源文件來(lái)定義函數(shù)
? ? ? ? ? 創(chuàng)建? ?test.c? ?源文件來(lái)運(yùn)行游戲
一,創(chuàng)建菜單

先明確要做什么,選擇合適的語(yǔ)句來(lái)對(duì)想法進(jìn)行實(shí)現(xiàn):
test.c
void menu()
{
printf("*******************\n");
printf("***** 1.play ****\n");
printf("***** 0.exit ****\n");
printf("*******************\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("請(qǐng)選擇:");
scanf("%d",&input);
switch (input)
{
case 1:
//掃雷
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
二,創(chuàng)建游戲內(nèi)容
在game函數(shù)重創(chuàng)新建。在test()函數(shù)中case1: 下調(diào)用game。
case 1: //掃雷 game();
1.場(chǎng)景創(chuàng)建和初始化
? ? ? ? 這里我們要明白,我們游戲中雷是提前布置好的,呈現(xiàn)在我們眼前的場(chǎng)景是經(jīng)過(guò)遮掩的,那么我們創(chuàng)建兩個(gè)場(chǎng)景,mine 和 show,且都是二維數(shù)組。
? ? ? ? 在掃雷的時(shí)候我們要計(jì)算輸入坐標(biāo)周圍一圈有沒(méi)有雷,因此我們要考慮在邊界坐標(biāo)的越界問(wèn)題,因此若展現(xiàn)在面前的是x*y的數(shù)組,那么實(shí)際數(shù)組的大小應(yīng)該是(x+2)*(y+2)的大小。
? ? ? ? 為了改變場(chǎng)景大小方便,我們創(chuàng)建行列時(shí)采用宏定義(在game.h)中。
game.h #include <stdio.h> //為玩家展現(xiàn)的場(chǎng)景大小 #define ROW 9 #define COL 9 //場(chǎng)景真實(shí)大小 防越界 #define ROWS ROW+2 #define COLS COL+2 //函數(shù)聲明 void initboard(char board[ROWS][COLS], int rows, int cols, char set); //初始化
game.c
//函數(shù)定義
void initboard(char board[ROWS][COLS], int rows, int cols, char set) //初始化場(chǎng)景
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set; //set接收 test.h 中傳來(lái)的字符
}
}
}
test.c
void game()
{
//創(chuàng)建數(shù)組
char mine[ROWS][COLS] = { 0 }; //布置雷
char show[ROWS][COLS] = { 0 }; //排查雷
//初始化mine數(shù)組為全'0'
initboard(mine,ROWS,COLS,'0');
//初始化show數(shù)組為全'*'
initboard(show, ROWS, COLS, '*');
}
2.場(chǎng)景打印
game.h #include <stdio.h> //為玩家展現(xiàn)的場(chǎng)景大小 #define ROW 9 #define COL 9 //場(chǎng)景真實(shí)大小 防越界 #define ROWS ROW+2 #define COLS COL+2 //函數(shù)聲明 void initboard(char board[ROWS][COLS], int rows, int cols, char set); //初始化 void displayboard(char board[ROWS][COLS], int row, int col); //打印場(chǎng)景
game.c
void displayboard(char board[ROWS][COLS ], int row, int col) //打印場(chǎng)景
{
int i = 0;
int j = 0;
for (i=0;i<=col;i++)
{
printf("%d ",i); //打印列號(hào) 為了方便玩家快速輸入坐標(biāo)
}
printf("\n"); //換行打印場(chǎng)景
for (i= 1; i <= row; i++)
{
printf("%d ",i); //打印行號(hào) 為了方便玩家快速輸入坐標(biāo)
for (j = 1; j <= col; j++)
{
printf("%c ",board[i][j]);
}
printf("\n"); //每行打印完記得換行
}
}
test.c
void game()
{
//創(chuàng)建數(shù)組
char mine[ROWS][COLS] = { 0 };//布置雷
char show[ROWS][COLS] = { 0 };//排查雷
//初始化mine數(shù)組為全'0'
initboard(mine,ROWS,COLS,'0');
//初始化show數(shù)組為全'*'
initboard(show, ROWS, COLS, '*');
//打印棋盤
displayboard(show,ROW,COL);
displayboard(mine, ROW, COL);
}
打印如下:

?注:玩游戲時(shí)只打印 show 的場(chǎng)景。
3.埋雷
game.h #include <stdio.h> #include <stdlib.h> //隨機(jī)埋雷,要用到隨機(jī)數(shù) #include <time.h> //為玩家展現(xiàn)的場(chǎng)景大小 #define ROW 9 #define COL 9 //場(chǎng)景真實(shí)大小 防越界 #define ROWS ROW+2 #define COLS COL+2 //函數(shù)聲明 void initboard(char board[ROWS][COLS], int rows, int cols, char set); //初始化 void displayboard(char board[ROWS][COLS], int row, int col); //打印場(chǎng)景 void setmine(char mine[ROWS][COLS],int row, int col); //布置雷
game.c
void setmine(char mine[ROWS][COLS], int row, int col) //布置雷
{
int count = 10;
while (count) //循環(huán)10次,放10個(gè)雷
{
int x = rand() % row + 1; //0~9
int y = rand() % col + 1; //0~9
if (mine[x][y] == '0') //判斷這個(gè)位置有沒(méi)有放雷
{
mine[x][y] = '1'; //雷為'1'
count--;
}
}
}
test.c
void game()
{
//創(chuàng)建數(shù)組
char mine[ROWS][COLS] = { 0 };//布置雷
char show[ROWS][COLS] = { 0 };//排查雷
//初始化mine數(shù)組為全'0'
initboard(mine,ROWS,COLS,'0');
//初始化show數(shù)組為全'*'
initboard(show, ROWS, COLS, '*');
//打印棋盤
//displayboard(show,ROW,COL);
//displayboard(mine, ROW, COL);
//布置雷
setmine(mine,ROW,COL);
displayboard(show, ROW, COL); //埋完雷后將 show 打印出來(lái),準(zhǔn)備下一步進(jìn)行排雷
}
埋雷這里要用到隨機(jī)數(shù),不要忘了提前使用 srand()?噢

4.排雷
game.h #include <stdio.h> #include <stdlib.h> //隨機(jī)埋雷,要用到隨機(jī)數(shù) #include <time.h> //為玩家展現(xiàn)的場(chǎng)景大小 #define ROW 9 #define COL 9 //場(chǎng)景真實(shí)大小 防越界 #define ROWS ROW+2 #define COLS COL+2 //函數(shù)聲明 void initboard(char board[ROWS][COLS], int rows, int cols, char set); //初始化 void displayboard(char board[ROWS][COLS], int row, int col); //打印場(chǎng)景 void setmine(char mine[ROWS][COLS],int row, int col); //布置雷 void findmine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col); //排雷
這里注意,我們同時(shí)接收 mine 和 show 數(shù)組,用?int row, int col 來(lái)使兩個(gè)場(chǎng)景有鏈接關(guān)系
game.h
int get_mine(char mine[ROWS][COLS],int x,int y) //找雷數(shù),該函數(shù)在排雷函數(shù)里使用,直接在
// findmine 外定義即可
{
return mine[x - 1][y] +
mine[x - 1][y - 1] +
mine[x][y - 1] + //這8個(gè)坐標(biāo)為x,y周圍一圈
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'; // '數(shù)字' - '0' = 數(shù)字
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) //排雷
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-10) //判斷雷是否排完
{
printf("請(qǐng)輸入要排查的坐標(biāo):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col) //判斷坐標(biāo)是否在可視范圍
{
//判斷
if (mine[x][y] == '1') //踩雷
{
printf("很遺憾,你被炸死了!\n");
displayboard(mine, ROW, COL);
break;
}
else //不是雷
{
//計(jì)算x,y坐標(biāo)周圍的雷
int n = get_mine(mine, x, y); //求周圍一圈雷的個(gè)數(shù)
if (n != 0)
show[x][y] = n + '0'; //并將個(gè)數(shù)通過(guò) show 場(chǎng)景顯示出來(lái)
displayboard(show, ROW, COL); //打印 show
win++;
}
}
else
{
printf("輸入坐標(biāo)非法,無(wú)法排雷,請(qǐng)重新輸入:\n");
}
}
if (win == row*col - 10)
{
printf("排雷成功\n");
displayboard(mine, ROW, COL);
}
}
注:數(shù)字 + '0' = '數(shù)字'? ? ? ? 詳細(xì)參考ASCII碼表
二進(jìn)制? ? ? ? ? ? ?字符
48? ? ? ? ? ? ? ? ? ? ?'0'
49? ? ? ? ? ? ? ? ? ? ?'1'
50? ? ? ? ? ? ? ? ? ?? '2'
51? ? ? ? ? ? ? ? ? ? ?'3'
52? ? ? ? ? ? ? ? ? ? ?'4'
53? ? ? ? ? ? ? ? ? ? ?'5'
54? ? ? ? ? ? ? ? ? ? ?'6'
55? ? ? ? ? ? ? ? ? ? ?'7'
56? ? ? ? ? ? ? ? ? ? ?'8'
57? ? ? ? ? ? ? ? ? ? ?'9'
這樣簡(jiǎn)單版本的掃雷就完成了。
注:頭文件stdio.h在game.c和test.c里面都要引用,我們將stdio.h放入game.h里面,直接用雙引號(hào)引用game.h。
完整代碼
1.game.h
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 //函數(shù)聲明 void initboard(char board[ROWS][COLS], int rows, int cols, char set);//初始化 void displayboard(char board[ROWS][COLS], int row, int col); //打印場(chǎng)景 void setmine(char mine[ROWS][COLS],int row, int col); //布置雷 void findmine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col); //排雷
2.game.c
#include "game.h"
void initboard(char board[ROWS][COLS], int rows, int cols, char set) //初始化場(chǎng)景
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void displayboard(char board[ROWS][COLS ], int row, int col) //打印場(chǎng)景
{
int i = 0;
int j = 0;
for (i=0;i<=col;i++)
{
printf("%d ",i); //打印列號(hào)
}
printf("\n");
for (i= 1; i <= row; i++)
{
printf("%d ",i); //打印行號(hào)
for (j = 1; j <= col; j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
void setmine(char mine[ROWS][COLS], int row, int col) //布置雷
{
int count = 10;
while (count)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int get_mine(char mine[ROWS][COLS],int x,int y) //找雷數(shù)
{
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';
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) //排雷
{
int x = 0;
int y = 0;
int win = 0;
while (win<row*col-10)
{
printf("請(qǐng)輸入要排查的坐標(biāo):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row&&y >= 1 && y <= col)
{
//判斷
if (mine[x][y] == '1')
{
printf("很遺憾,你被炸死了!\n");
displayboard(mine, ROW, COL);
break;
}
else
{
//計(jì)算x,y坐標(biāo)周圍的雷
int n = get_mine(mine, x, y);
if (n != 0)
show[x][y] = n + '0';
displayboard(show, ROW, COL);
win++;
}
}
else
{
printf("輸入坐標(biāo)非法,無(wú)法排雷,請(qǐng)重新輸入:\n");
}
}
if (win == row*col - 10)
{
printf("排雷成功\n");
displayboard(mine, ROW, COL);
}
}
3.test.c
#include "game.h"
void game()
{
//創(chuàng)建數(shù)組
char mine[ROWS][COLS] = { 0 };//布置雷
char show[ROWS][COLS] = { 0 };//排查雷
//初始化mine數(shù)組為全'0'
initboard(mine,ROWS,COLS,'0');
//初始化show數(shù)組為全'*'
initboard(show, ROWS, COLS, '*');
//打印棋盤
//displayboard(show,ROW,COL);
//displayboard(mine, ROW, COL);
//布置雷
setmine(mine,ROW,COL);
//displayboard(mine, ROW, COL);
displayboard(show, ROW, COL);
//排雷
findmine(mine,show, ROW, COL);
}
void menu()
{
printf("*******************\n");
printf("***** 1.play ****\n");
printf("***** 0.exit ****\n");
printf("*******************\n");
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("請(qǐng)選擇:");
scanf("%d",&input);
switch (input)
{
case 1:
//掃雷
game();
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("選擇錯(cuò)誤\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
實(shí)戰(zhàn)如下:

對(duì)了,對(duì)埋雷函數(shù)我們還可以進(jìn)行優(yōu)化,將雷的個(gè)數(shù)進(jìn)行宏定義放在game.h里,方便修改雷的數(shù)量。
優(yōu)化到下個(gè)版本時(shí)會(huì)一起修改的

到此這篇關(guān)于C語(yǔ)言掃雷詳細(xì)代碼分步實(shí)現(xiàn)流程的文章就介紹到這了,更多相關(guān)C語(yǔ)言 掃雷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言實(shí)現(xiàn)經(jīng)典掃雷小游戲完整代碼(遞歸展開(kāi)?+?選擇標(biāo)記)
- 基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲
- C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(擴(kuò)展版)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的掃雷小游戲
- C語(yǔ)言實(shí)現(xiàn)掃雷游戲詳細(xì)流程
- C語(yǔ)言數(shù)組超詳細(xì)講解下篇掃雷
- C語(yǔ)言實(shí)現(xiàn)掃雷OvO(完整代碼)
- C語(yǔ)言實(shí)現(xiàn)自定義掃雷游戲(遞歸版)
- C語(yǔ)言掃雷排雷小游戲?qū)崿F(xiàn)全程
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(137.單獨(dú)的數(shù)字之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(137.單獨(dú)的數(shù)字之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
詳解C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除
值多態(tài)是一種介于傳統(tǒng)多態(tài)與類型擦除之間的多態(tài)實(shí)現(xiàn)方式,借鑒了值語(yǔ)義,保留了繼承,在單繼承的適用范圍內(nèi),程序和程序員都能從中受益。這篇文章主要介紹了C++值多態(tài)中的傳統(tǒng)多態(tài)與類型擦除,需要的朋友可以參考下2020-04-04
Qt股票組件之自選股列表拖拽、右鍵常用菜單功能的實(shí)現(xiàn)
這篇文章主要介紹了Qt股票組件之自選股列表拖拽、右鍵常用菜單功能的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例文字相結(jié)合的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07

