C語言實(shí)現(xiàn)簡(jiǎn)單掃雷源碼
掃雷是一款大家都熟知的小游戲,今天我們將使用c語言實(shí)現(xiàn)一個(gè)簡(jiǎn)易版本的掃雷
需要的功能
1.保證第一次下子時(shí),不被炸死
2.輸入的坐標(biāo)周圍沒雷,可以直接展開周圍的坐標(biāo)
3.輸入的坐標(biāo)周圍有雷時(shí),應(yīng)該顯示周圍有多少個(gè)雷
注意事項(xiàng)
1.應(yīng)該定義兩個(gè)數(shù)組,一個(gè)用來向玩家展示排雷的情況,一個(gè)來存放雷
2.定義的數(shù)組的大小,應(yīng)該大于掃雷游戲的棋盤的真實(shí)大小,防止數(shù)組越界
(如:在掃雷的棋盤為99時(shí),我們應(yīng)該定義1111的數(shù)組,防止數(shù)組越界)
3.可以將代碼分文件實(shí)現(xiàn)
代碼的實(shí)現(xiàn)
分文件
將代碼分別寫入game.c,game.h,test.c文件里,可以讓代碼更加有條理
test.c主要寫游戲主要框架
game.c實(shí)現(xiàn)需要的函數(shù)
game.h定義需要的函數(shù)
對(duì)兩個(gè)數(shù)組初始化
//board-需要初始化的數(shù)組 //set-初始化的元素(這里我將'1'設(shè)置為雷,'0'代表沒有雷;將玩家看到的棋盤初始化為'*') void InitBoard(char board[ROWS][COLS], int rows, int cols,char set) { int i; int j; 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) { int i; int j=1; printf("-----------------------------\n");//分割每次打印的棋盤,防止混淆 for (i = 0; i <= row; i++) {//打印列號(hào) printf("%d ", i); } 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"); } printf("-----------------------------\n"); }
布置雷
//布置雷 //count-布置的雷的數(shù)量 void SetMineBoard(char board[ROWS][COLS], int row, int col, int count) { while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } }
排查雷
//排查雷 //num-雷的數(shù)量 void FineMine(int row, int col, int num) { int flag = 1; int a = 1; while (flag) { printf("請(qǐng)輸入一個(gè)坐標(biāo):"); int x; int y; scanf("%d%d", &x, &y); if (a == 1)//第一次輸入坐標(biāo)需要進(jìn)行判斷,防止第一次就踩到了雷 { a--; safe(x, y,ROW,COL);//安全函數(shù),保證第一次不會(huì)踩到雷 } if (x >= 1 && x <= row&&y >= 1 && y <= col)//坐標(biāo)合法 { if (mine[x][y] != '1')//如果該位置不是雷,應(yīng)該搜索周圍有多少雷 { int count = GetMineCount(x, y);//查找周圍雷的數(shù)量 show[x][y] = count + '0'; if (show[x][y] == '0') {//該位置沒有雷時(shí),應(yīng)該繼續(xù)展開搜索周圍的坐標(biāo) open_mine(x, y);//展開周圍坐標(biāo)功能 int z = count_show_mine(row, col); if (z == num) { printf("你已經(jīng)找出全部的雷,游戲勝利\n"); DisplayBoard(show, ROW, COL);//打印 break; } } DisplayBoard(show, ROW, COL);//打印 } else { printf("你踩到雷,游戲結(jié)束\n"); DisplayBoard(mine, ROW, COL);//打印 flag = 0; } } else { printf("坐標(biāo)有誤,請(qǐng)重新輸入"); } } }
保證第一次下子時(shí),不被炸死
//保證不會(huì)在第一次時(shí)踩到雷 void safe(int x, int y, int row, int col) { int q = 1; if (mine[x][y] == '1') {//如果此處是雷,將雷換到其他地方 mine[x][y] = '0'; while (q) { int a = rand() % row + 1; int b = rand() % col + 1; if (mine[a][b] == '0'&&a!=x&&b!=y) { q--; mine[a][b] = '1'; } } } }
統(tǒng)計(jì)周圍有幾個(gè)雷;
//統(tǒng)計(jì)坐標(biāo)(x,y)周圍有幾個(gè)雷; int GetMineCount(int x, int y) { return (mine[x - 1][y - 1]) + (mine[x - 1][y]) + (mine[x - 1][y + 1]) + (mine[x][y - 1]) + (mine[x][y + 1]) + (mine[x + 1][y - 1]) + (mine[x + 1][y]) + (mine[x + 1][y + 1]) - 8 * '0'; }
展開周圍坐標(biāo)
//展開排查周圍坐標(biāo)的情況 void open_mine(int x, int y)//坐標(biāo)周圍展開函數(shù) { if (mine[x - 1][y - 1] == '0') { show[x - 1][y - 1] = GetMineCount(x - 1, y - 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x - 1][y] == '0') { show[x - 1][y] = GetMineCount(x - 1, y) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x - 1][y + 1] == '0') { show[x - 1][y + 1] = GetMineCount(x - 1, y + 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x][y - 1] == '0') { show[x][y - 1] = GetMineCount(x, y - 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x][y + 1] == '0') { show[x][y + 1] = GetMineCount(x, y + 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x + 1][y - 1] == '0') { show[x + 1][y - 1] = GetMineCount(x + 1, y - 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x + 1][y] == '0') { show[x + 1][y] = GetMineCount(x + 1, y) + '0';//顯示該坐標(biāo)周圍雷數(shù) } if (mine[x + 1][y + 1] == '0') { show[x + 1][y + 1] = GetMineCount(x + 1, y + 1) + '0';//顯示該坐標(biāo)周圍雷數(shù) } }
判斷勝利
//判斷剩余未知區(qū)域的個(gè)數(shù),個(gè)數(shù)為雷數(shù)時(shí)玩家贏 int count_show_mine(int row,int col) { int count = 0; int i = 0; int j = 0; for (i = 1; i <= row - 2; i++) { for (j = 1; j <= col - 2; j++) { if (show[i][j] == '*') { count++; } } } return count; }
效果展示
1.打印和布置
第一個(gè)數(shù)組是玩家在游戲看到的數(shù)組,第二個(gè)數(shù)組是存放雷的數(shù)組,在游戲中第二個(gè)數(shù)組不會(huì)被打印
2.safe函數(shù)的檢查
第一個(gè)數(shù)組為本來存放雷的數(shù)組,可以看到此時(shí)(1,7)位置是有雷的,但是,我們?cè)谳斎耄?,7)坐標(biāo)時(shí),因?yàn)閟afe函數(shù)的功能,使得(1,7)位置的雷轉(zhuǎn)移到其他地方
3.由上圖可知(2,8)存放的有雷,這時(shí)我們輸入(2,8)(不是第一次輸入),游戲結(jié)束
4.展開功能
第一個(gè)數(shù)組仍然為布置雷后打印出的數(shù)組,我們可以看到(3,3)位置及周圍都沒有雷,所以我們輸入(3,3)看到其周圍8個(gè)位置也被搜索
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++跳轉(zhuǎn)語句之Goto對(duì)變量定義的影響詳解
goto語句也被稱為無條件轉(zhuǎn)移語句,這篇文章主要介紹了C++跳轉(zhuǎn)語句之Goto對(duì)變量定義的影響,文中通過示例代碼解文字介紹的很詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2016-11-11MFC Frame-Splitter模型實(shí)例原理解析
這篇文章主要介紹了MFC Frame-Splitter模型實(shí)例原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07重學(xué)c/c++之?dāng)?shù)據(jù)存儲(chǔ)詳解(整數(shù)、浮點(diǎn)數(shù))
C語言給定了一些基本的數(shù)據(jù)類型,下面這篇文章主要給大家介紹了關(guān)于重學(xué)c/c++之?dāng)?shù)據(jù)存儲(chǔ)(整數(shù)、浮點(diǎn)數(shù))的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11C語言數(shù)組和指針,內(nèi)存之間的關(guān)系
這篇文章主要介紹了C語言數(shù)組和指針,內(nèi)存之間的關(guān)系,首先論證一維數(shù)組和一級(jí)指針之前的關(guān)系,我們常常使用一級(jí)指針指針的方式訪問一維數(shù)組,只有對(duì)內(nèi)存的理解到位才能理解它們直接的關(guān)系。需要的小伙伴可以參考一下2022-02-02C語言實(shí)現(xiàn)電話簿管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)電話簿管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11