C語(yǔ)言遞歸應(yīng)用實(shí)現(xiàn)掃雷游戲
更新時(shí)間:2022年06月07日 15:27:09 作者:橘澤
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言遞歸應(yīng)用實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文實(shí)例為大家分享了C語(yǔ)言遞歸應(yīng)用實(shí)現(xiàn)掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
游戲設(shè)計(jì)規(guī)則:
- 菜單
- 兩個(gè)棋盤(pán),Mine一個(gè)布置雷,Show一個(gè)給玩家看,玩家選擇show里的坐標(biāo)翻開(kāi)雷陣,在mine里的相同坐標(biāo)如果是雷則玩家失敗游戲結(jié)束,若不是雷則判斷此坐標(biāo)周?chē)?個(gè)坐標(biāo)是否有雷,有雷則顯示周?chē)偫讛?shù),沒(méi)有就顯示為空格。為了避免判斷雷陣最外邊一圈坐標(biāo)時(shí)出現(xiàn)溢出,因此設(shè)置雷陣數(shù)組時(shí)行(列)比打印出的要多兩行(列),布置雷時(shí)也不在最外面一圈布雷。
- 第一步如果踩雷則將mine中所選坐標(biāo)位置換為安全,并重新布置雷位,確保玩家第一次不會(huì)踩雷。
- 雷區(qū)沒(méi)有雷時(shí)的展開(kāi)操作:當(dāng)所以選位置周?chē)?個(gè)坐標(biāo)均無(wú)雷時(shí),則分別判斷坐標(biāo)周?chē)?個(gè)坐標(biāo)的周?chē)?個(gè)坐標(biāo)是否有雷(沒(méi)寫(xiě)錯(cuò),請(qǐng)仔細(xì)思考理解。。),有雷則在該座標(biāo)處顯示雷數(shù),并不再進(jìn)行下一坐標(biāo)的判斷,若沒(méi)有則顯示空格,并繼續(xù)進(jìn)行下一次判斷。
函數(shù)模塊及講解
test.c文件主要內(nèi)容及功能講解
#include"game.h"
int main()
{
? ? ? srand((unsigned int)time(NULL)); ??
? ? ? int x = 0;
?? ? ??
? ? ? while (1) ? ? ?
? ? ? {
?? ? ?menu();//菜單
?? ? ?printf("請(qǐng)選擇:>");
?? ? ?scanf("%d", &x);
?? ? ?if (x == 1)
?? ? ?{
?? ? ? ? ?char mine[ROWS][COLS] = { 0 };//布置雷的棋盤(pán)
?? ? ? ? ?char show[ROWS][COLS] = { 0 };//查找雷的棋盤(pán)
?? ? ? ? ?//初始化
?? ? ? ? ?setboard(mine, ROWS, COLS, '0');//設(shè)置雷的棋盤(pán)初始化
?? ? ? ? ?setboard(show, ROWS, COLS, '*');//設(shè)置排查的棋盤(pán)初始化
?? ? ? ? ?//打印
?? ? ? ? ?displayboard(show, ROW, COL);//打印排查的棋盤(pán)9 ?
?? ? ? ? ?//布雷
?? ? ? ? ?putmine(mine, ROW, COL);// ?
? ??? ? ? ? ?//displayboard(mine, ROW, COL);//打印用來(lái)方便測(cè)試
??? ? ? ? ?//排雷
?? ? ? ? ?findmine(mine,show, ROW, COL);
?? ? ?}
?? ? ?else if (x == 0)
?? ? ?{
?? ??? ? ? printf("退出游戲!\n");
?? ??? ? ? break;
?? ? ?}
?? ? ?else
?? ? ?{
?? ??? ? ? printf("輸入錯(cuò)誤,請(qǐng)重新輸入!\n");//處理非法輸入
?? ? ?}
? ? ? }
?system("pause");
?return 0;
}game.c文件主要內(nèi)容及功能講解
#include"game.h"
void menu()//菜單
{
?printf("*****************************\n");
?printf("**** ? 1.play ? 0.exit ? ****\n");
?printf("*****************************\n");
}
void setboard(char board[ROWS][COLS], int rows, int cols, char n)//初始化,mine初始化為0,show初始化為*
{
?int x = 0;
?int y = 0;
?int a = 0;
?for (x = 0; x < rows; x++)
?{
? for (y = 0; y < cols; y++)
? {
? ?board[x][y] = n;
? }
?}
}
void displayboard(char board[ROWS][COLS], int rows, int cols)//打印棋盤(pán)
{
?int x = 0;
?int y = 0;
?for (x = 0; x <= cols; x++)
?{
? printf("%d ", x);//打印列的序號(hào)
?}
?printf("\n");
?for (x = 1; x <= rows; x++)
?{
? printf("%d ", x);//打印行的序號(hào)
? for (y = 1; y <= cols; y++)
? {
? ?printf("%c ", board[x][y]);
? }
? printf("\n");
?}
?printf("\n");
}
//布雷,使用rand產(chǎn)生隨機(jī)值,srand調(diào)用在主函數(shù)里
void putmine(char mine[ROWS][COLS], int rows, int cols)
{
?int x = 0;
?int y = 0;
?int count = low;
?while (count)
?{
? x = rand() % ROW + 1;
? y = rand() % COL + 1;
? if (mine[x][y] == '0')
? {
? ?mine[x][y] = '1';
? ?count--;
? }
?}
}
//計(jì)算盤(pán)中還有多少個(gè)*,
//后面用來(lái)和雷數(shù)比較判斷,
//當(dāng)*等于雷數(shù)時(shí)排雷成功
int number(char show[ROWS][COLS])
{
?int count = 0;
?int x = 0;
?int y = 0;
?for (x = 1; x <= ROW; x++)
?{
? for (y = 1; y <= COL; y++)
? {
? ?if (show[x][y] == '*')
? ? count++;
? }
?}
?return count;
}
void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols)
{
?int x = 0;
?int y = 0;
?while (number(show) != low)
?{
? printf("請(qǐng)輸入查找坐標(biāo):>");
? scanf("%d%d", &x, &y);
? if (x > 0 && x <= rows && y > 0 && y <= cols && show[x][y] != ' ')//注意判斷坐標(biāo)合法性
? {
? ?if (mine[x][y] == '1')
? ?{
? ? if (number(show) == ROW * COL)//第一步踩雷時(shí)要替換雷位保證玩家不會(huì)first blood
? ? {
? ? ?firstsafe(mine, x, y);
? ? ?//displayboard(mine, ROW, COL);//用來(lái)打印方便測(cè)試?yán)孜挥袥](méi)有被替換
? ? ?goto first;//替換之后繼續(xù)判斷該坐標(biāo),轉(zhuǎn)到first
? ? }
? ? printf("YOU LOSE!GAME OVER!\n");//當(dāng)玩家不是第一步踩雷時(shí)就輸了
? ? printf("\n");
? ? displayboard(mine, ROW, COL);//打印雷盤(pán)讓玩家看到自己踩得是不是雷
? ? break;
? ?}
? ?else
? ?{
? ? first:
? ? recfindmine(mine, show, x, y);//展開(kāi)程序
? ? displayboard(show, ROW, COL);
? ? //displayboard(mine, ROW, COL);//方便測(cè)試
? ?}
? }
? else
? {
? ?printf("坐標(biāo)錯(cuò)誤,請(qǐng)重新輸入!\n");
? }
?}
?if (number(show) == low)//當(dāng)*等于雷數(shù)時(shí)排雷成功
?{
? printf("YOU WIN!\n");
? displayboard(mine, ROW, COL);
?}
}
//算一個(gè)坐標(biāo)周?chē)?個(gè)有沒(méi)有雷
//mine盤(pán)里放的是字符'0'和'1',
//函數(shù)返回是整型值,
//'1'-'0'=1;
int minenum(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';
}
//本來(lái)寫(xiě)的時(shí)候?qū)懙牟檎抑車(chē)?個(gè)坐標(biāo),結(jié)果后來(lái)發(fā)現(xiàn)找周?chē)?個(gè)也是一樣的
//用遞歸來(lái)進(jìn)行判斷
//目前這個(gè)函數(shù)還有bug,展開(kāi)有時(shí)候遇到周?chē)欣椎臅r(shí)候不會(huì)停,會(huì)繼續(xù)判斷
//導(dǎo)致展開(kāi)不是連續(xù)的,就像掃雷開(kāi)掛了。。但是基本的展開(kāi)功能還是能夠?qū)崿F(xiàn)的
//希望看出來(lái)的大佬給指點(diǎn)一下,謝謝;
void recfindmine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
?int i = minenum(mine, x, y);
?if (show[x][y] == '*' && i == 0)
?{
? show[x][y] = ' ';
? if (show[x - 1][y] == '*' && (x - 1) > 0 && y > 0)//上
? {
? ?recfindmine(mine, show, x-1, y);
? }
? //if ((x - 1) > 0 && (y - 1) > 0 && show[x - 1][y - 1] == '*')//左上
? //{
? // recfindmine(mine, show, x-1, y-1);
? //}
? //if ((x - 1) > 0 && (y + 1) > 0 && show[x - 1][y + 1] == '*')//右上
? //{
? // recfindmine(mine, show, x-1, y+1);
? //}
? if (show[x + 1][y] == '*' && (x + 1) > 0 && y > 0)//下
? {
? ?recfindmine(mine, show, x+1, y);
? }
? //if ((x + 1) > 0 && (y - 1) > 0 && show[x + 1][y - 1] == '*')//左下
? //{
? // recfindmine(mine, show, x+1, y-1);
? //}
? //if ((x + 1) > 0 && (y + 1) > 0 && show[x + 1][y + 1] == '*')//右下
? //{
? // recfindmine(mine, show, x+1, y+1);
? //}
? if (show[x][y + 1] == '*' && x > 0 && (y + 1) > 0)//右
? {
? ?recfindmine(mine, show, x, y+1);
? }
? if (show[x][y - 1] == '*' && x > 0 && (y - 1) > 0)//左
? {
? ?recfindmine(mine, show, x, y-1);
? }
?}
?else?
?{
? show[x][y] = i + '0';
?}
}
//保證第一步不死,把第一步的雷替換成0,再隨機(jī)生成一個(gè)不是雷的坐標(biāo)改成雷
void firstsafe(char mine[ROWS][COLS], int x, int y)
{
?mine[x][y] = '0';
?while (1)
?{
? int a = 0;
? int b = 0;
? a = rand() % ROW + 1;
? b = rand() % COL + 1;
? if (mine[a][b] == '0')
? {
? ?mine[a][b] = '1';
? ?break;
? }
?}
}game.h文件主要內(nèi)容及功能講解
#include<stdlib.h> #include<stdio.h> #include<time.h> #define ROWS 11 #define COLS 11 #define ROW 9 #define COL 9 #define low 10 void menu(); void setboard(char board[ROWS][COLS], int rows, int cols,char n); void displayboard(char board[ROWS][COLS], int rows, int cols); void putmine(char mine[ROWS][COLS], int rows, int cols); void findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols); void recfindmine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y); int minenum(char mine[ROWS][COLS], int x,int y); int number(char show[ROWS][COLS]); void firstsafe(char mine[ROWS][COLS], int x, int y);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- C語(yǔ)言實(shí)現(xiàn)掃雷小游戲完整算法詳解(附完整代碼)
- C語(yǔ)言實(shí)現(xiàn)掃雷游戲的方法
- C語(yǔ)言二維數(shù)組應(yīng)用實(shí)現(xiàn)掃雷游戲
- C語(yǔ)言制作掃雷游戲(圖形庫(kù))
- C語(yǔ)言實(shí)現(xiàn)掃雷代碼
- 基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易的掃雷游戲
- C語(yǔ)言詳細(xì)講解通過(guò)遞歸實(shí)現(xiàn)掃雷的展開(kāi)
- C語(yǔ)言實(shí)現(xiàn)經(jīng)典掃雷小游戲完整代碼(遞歸展開(kāi)?+?選擇標(biāo)記)
- C語(yǔ)言實(shí)現(xiàn)爆炸展開(kāi)的掃雷詳解
相關(guān)文章
舉例剖析C++中引用的本質(zhì)及引用作函數(shù)參數(shù)的使用
這篇文章主要介紹了C++中引用的本質(zhì)及引用作函數(shù)參數(shù)的使用,講解了函數(shù)返回值是引用的情況等一些難點(diǎn),需要的朋友可以參考下2016-03-03

