C語言遞歸應(yīng)用實現(xiàn)掃雷游戲
更新時間:2022年06月07日 15:27:09 作者:橘澤
這篇文章主要為大家詳細(xì)介紹了C語言遞歸應(yīng)用實現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了C語言遞歸應(yīng)用實現(xiàn)掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
游戲設(shè)計規(guī)則:
- 菜單
- 兩個棋盤,Mine一個布置雷,Show一個給玩家看,玩家選擇show里的坐標(biāo)翻開雷陣,在mine里的相同坐標(biāo)如果是雷則玩家失敗游戲結(jié)束,若不是雷則判斷此坐標(biāo)周圍8個坐標(biāo)是否有雷,有雷則顯示周圍總雷數(shù),沒有就顯示為空格。為了避免判斷雷陣最外邊一圈坐標(biāo)時出現(xiàn)溢出,因此設(shè)置雷陣數(shù)組時行(列)比打印出的要多兩行(列),布置雷時也不在最外面一圈布雷。
- 第一步如果踩雷則將mine中所選坐標(biāo)位置換為安全,并重新布置雷位,確保玩家第一次不會踩雷。
- 雷區(qū)沒有雷時的展開操作:當(dāng)所以選位置周圍8個坐標(biāo)均無雷時,則分別判斷坐標(biāo)周圍8個坐標(biāo)的周圍8個坐標(biāo)是否有雷(沒寫錯,請仔細(xì)思考理解。。),有雷則在該座標(biāo)處顯示雷數(shù),并不再進行下一坐標(biāo)的判斷,若沒有則顯示空格,并繼續(xù)進行下一次判斷。
函數(shù)模塊及講解
test.c文件主要內(nèi)容及功能講解
#include"game.h" int main() { ? ? ? srand((unsigned int)time(NULL)); ?? ? ? ? int x = 0; ?? ? ?? ? ? ? while (1) ? ? ? ? ? ? { ?? ? ?menu();//菜單 ?? ? ?printf("請選擇:>"); ?? ? ?scanf("%d", &x); ?? ? ?if (x == 1) ?? ? ?{ ?? ? ? ? ?char mine[ROWS][COLS] = { 0 };//布置雷的棋盤 ?? ? ? ? ?char show[ROWS][COLS] = { 0 };//查找雷的棋盤 ?? ? ? ? ?//初始化 ?? ? ? ? ?setboard(mine, ROWS, COLS, '0');//設(shè)置雷的棋盤初始化 ?? ? ? ? ?setboard(show, ROWS, COLS, '*');//設(shè)置排查的棋盤初始化 ?? ? ? ? ?//打印 ?? ? ? ? ?displayboard(show, ROW, COL);//打印排查的棋盤9 ? ?? ? ? ? ?//布雷 ?? ? ? ? ?putmine(mine, ROW, COL);// ? ? ??? ? ? ? ?//displayboard(mine, ROW, COL);//打印用來方便測試 ??? ? ? ? ?//排雷 ?? ? ? ? ?findmine(mine,show, ROW, COL); ?? ? ?} ?? ? ?else if (x == 0) ?? ? ?{ ?? ??? ? ? printf("退出游戲!\n"); ?? ??? ? ? break; ?? ? ?} ?? ? ?else ?? ? ?{ ?? ??? ? ? printf("輸入錯誤,請重新輸入!\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)//打印棋盤 { ?int x = 0; ?int y = 0; ?for (x = 0; x <= cols; x++) ?{ ? printf("%d ", x);//打印列的序號 ?} ?printf("\n"); ?for (x = 1; x <= rows; x++) ?{ ? printf("%d ", x);//打印行的序號 ? for (y = 1; y <= cols; y++) ? { ? ?printf("%c ", board[x][y]); ? } ? printf("\n"); ?} ?printf("\n"); } //布雷,使用rand產(chǎn)生隨機值,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--; ? } ?} } //計算盤中還有多少個*, //后面用來和雷數(shù)比較判斷, //當(dāng)*等于雷數(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("請輸入查找坐標(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)//第一步踩雷時要替換雷位保證玩家不會first blood ? ? { ? ? ?firstsafe(mine, x, y); ? ? ?//displayboard(mine, ROW, COL);//用來打印方便測試?yán)孜挥袥]有被替換 ? ? ?goto first;//替換之后繼續(xù)判斷該坐標(biāo),轉(zhuǎn)到first ? ? } ? ? printf("YOU LOSE!GAME OVER!\n");//當(dāng)玩家不是第一步踩雷時就輸了 ? ? printf("\n"); ? ? displayboard(mine, ROW, COL);//打印雷盤讓玩家看到自己踩得是不是雷 ? ? break; ? ?} ? ?else ? ?{ ? ? first: ? ? recfindmine(mine, show, x, y);//展開程序 ? ? displayboard(show, ROW, COL); ? ? //displayboard(mine, ROW, COL);//方便測試 ? ?} ? } ? else ? { ? ?printf("坐標(biāo)錯誤,請重新輸入!\n"); ? } ?} ?if (number(show) == low)//當(dāng)*等于雷數(shù)時排雷成功 ?{ ? printf("YOU WIN!\n"); ? displayboard(mine, ROW, COL); ?} } //算一個坐標(biāo)周圍8個有沒有雷 //mine盤里放的是字符'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'; } //本來寫的時候?qū)懙牟檎抑車?個坐標(biāo),結(jié)果后來發(fā)現(xiàn)找周圍4個也是一樣的 //用遞歸來進行判斷 //目前這個函數(shù)還有bug,展開有時候遇到周圍有雷的時候不會停,會繼續(xù)判斷 //導(dǎo)致展開不是連續(xù)的,就像掃雷開掛了。。但是基本的展開功能還是能夠?qū)崿F(xià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,再隨機生成一個不是雷的坐標(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);
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++實現(xiàn)LeetCode(68.文本左右對齊)
這篇文章主要介紹了C++實現(xiàn)LeetCode(68.文本左右對齊),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++編程中__if_exists與__if_not_exists語句的用法
這篇文章主要介紹了C++編程中__if_exists與__if_not_exists語句的用法,是C++中用于判斷指定的標(biāo)識符是否存在的基礎(chǔ)的條件判斷語句,需要的朋友可以參考下2016-01-01C語言中system()執(zhí)行cmd命令打開關(guān)閉程序的方法
今天小編就為大家分享一篇C語言中system()執(zhí)行cmd命令打開關(guān)閉程序的方法。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05C++設(shè)計模式之簡單工廠模式的實現(xiàn)示例
這篇文章主要給大家介紹了關(guān)于C++設(shè)計模式之簡單工廠模式的相關(guān)資料,簡單工廠模式,主要用于創(chuàng)建對象,添加類時,不會影響以前的系統(tǒng)代碼,需要的朋友可以參考下2021-06-06