C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷小游戲
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)掃雷小游戲的具體代碼,供大家參考,具體內(nèi)容如下
在編寫掃雷小游戲之前,第一,我們應(yīng)該列出我們想要實(shí)現(xiàn)的掃雷小游戲的功能:
1.顯示選中的坐標(biāo)周圍的雷的個(gè)數(shù)。
2.保證第一次選中的坐標(biāo)不是雷。
3.選中的坐標(biāo)周圍8個(gè)格子中沒(méi)有雷,則展開(kāi)。
第二,我們應(yīng)該明白我們需要兩個(gè)棋盤來(lái)實(shí)現(xiàn)掃雷游戲:一個(gè)棋盤用來(lái)展示給玩家,初始界面全為“ * ” (未翻開(kāi)的格子),這個(gè)頁(yè)面就是我們常見(jiàn)的掃雷頁(yè)面。另一個(gè)棋盤用來(lái)給編寫者看,棋盤內(nèi)只有字符‘1'和字符‘0' 。‘1'代表雷,‘0'代表非雷。使用字符‘1'‘0'來(lái)代表雷和非雷有利于我們下一步計(jì)算坐標(biāo)周圍雷的個(gè)數(shù)。
1.初始化棋盤
nitboard(show_board, ROWS, COLS,'*'); //‘*'代表未翻開(kāi)的坐標(biāo) Initboard(mine_board, ROWS, COLS, '0'); //‘0'代表非雷 void Initboard(char board[ROWS][COLS], int row, int col, char set) { memset(board, set, row*col * sizeof(board[0][0])); }
2.打印棋盤
void DisPlayboard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf(" "); for (i = 1; i <= row; 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"); } printf("\n"); }
3.在棋盤中埋入雷。(因?yàn)槊恳淮沃匦麻_(kāi)始游戲雷的位置不能重復(fù),所以選擇用隨機(jī)數(shù)來(lái)埋雷)
void GetBoom(char board[ROWS][COLS], int row, int col) //埋雷 { int x = 0; int y = 0; int sum = 0; while(1) { x = rand() % row +1; //雷放在1-9的范圍里 y = rand() % col +1; if (1) { board[x][y] = '1'; sum++; if (sum == M) //埋入雷后跳出循環(huán) { break; } } }
4.確保第一次不踩到雷,如果第一次踩到雷,我們就將此位置改為非雷,然后將此處的雷移動(dòng)到別處未放置雷的位置。
(還要考慮一種特殊情況,即如果第一次落子就獲得勝利的情況時(shí)后面函數(shù)就不用再執(zhí)行了,所以此函數(shù)要改為有返回值的函數(shù),這樣在調(diào)用此函數(shù)時(shí)就可以判斷是否為一次就獲得勝利的情況)
int Judge_first(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int m; int n; printf("請(qǐng)輸入要排查的坐標(biāo):"); scanf("%d%d", &x, &y); while (1) { if (mine_board[x][y] == '1') //如果第一次踩雷,將此坐標(biāo)改為非雷 { mine_board[x][y] = '0'; show_board[x][y] = ' '; while (1) { m = rand() % 9 + 1; n = rand() % 9 + 1; if (m != x && n != y && mine_board[m][n] != '1') { mine_board[m][n] = '1'; } Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) //展開(kāi)后判斷是否一次獲得勝利 { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); return 2; //一次獲得勝利返回2 不再執(zhí)行PlayerMove函數(shù) break; } DisPlayboard(show_board, row, col); break; } break; } else if (mine_board[x][y] == '0') { show_board[x][y] = ' '; Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); return 2; break; } DisPlayboard(show_board, row, col); break; } } }
5.當(dāng)坐標(biāo)周圍雷個(gè)數(shù)為0時(shí),展示周圍格子,再以X和Y周圍八個(gè)坐標(biāo)分別為中心展開(kāi),當(dāng)坐標(biāo)周圍有雷時(shí)不再遞歸展開(kāi),并將雷的個(gè)數(shù)放在該坐標(biāo)。
void Open(char mine_board[ROWS][COLS],char show_board[ROWS][COLS], int x, int y) { int ret = 0; ret = Num(mine_board, x, y); if (ret == 0) //當(dāng)坐標(biāo)周圍雷個(gè)數(shù)為0時(shí) 打開(kāi)周圍格子 再以X和Y周圍八個(gè)坐標(biāo)為中心展開(kāi) 重復(fù)即為遞歸展開(kāi) { show_board[x][y] = ' '; if (x - 1 > 0 && y - 1 > 0 && show_board[x - 1][y - 1] == '*') { Open(mine_board, show_board, x - 1, y - 1); } if (x - 1 > 0 && y > 0 && show_board[x - 1][y] == '*') { Open(mine_board, show_board, x - 1, y); } if (x - 1 > 0 && y + 1 <= COL && show_board[x - 1][y + 1] == '*') { Open(mine_board, show_board, x - 1, y + 1); } if (x > 0 && y + 1 <= COL && show_board[x][y + 1] == '*') { Open(mine_board, show_board, x, y + 1); } if (x + 1 < ROW && y + 1 <= COL && show_board[x + 1][y + 1] == '*') { Open(mine_board, show_board, x + 1, y + 1); } if (x + 1 <= ROW && y > 0 && show_board[x + 1][y] == '*') { Open(mine_board, show_board, x + 1, y); } if (x + 1 <= ROW && y - 1 > 0 && show_board[x + 1][y - 1] == '*') { Open(mine_board, show_board, x + 1, y - 1); } if (x > 0 && y - 1 > 0 && show_board[x][y - 1] == '*') { Open(mine_board, show_board, x, y - 1); } } else if (ret != 0) show_board[x][y] = Num(mine_board, x, y) + 48; }
6.計(jì)算坐標(biāo)周圍一圈中所含雷的個(gè)數(shù)。
int Num(char board[ROWS][COLS], int x, int y) { int sum = 0; //sum為坐標(biāo)周圍雷的個(gè)數(shù) sum = board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] - (8 * '0'); return sum; }
7.判斷玩家是否排完所有雷。
int Full(char board[ROWS][COLS], int row, int col) { int i; int j; int sum = 0; //sum為棋盤未翻開(kāi)格子的個(gè)數(shù) for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (board[i][j] == '*') sum++; } } if (sum == M) //當(dāng)未翻開(kāi)的格子數(shù)為雷數(shù)時(shí) 返回1 return 1; }
8.玩家輸入坐標(biāo)掃雷。
void PlayerMove(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int ret = 0; while (1) { if (Full(show_board, ROW, COL) == 1) //棋盤未翻開(kāi)格子等于雷數(shù)時(shí)玩家勝利 { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); break; } printf("請(qǐng)輸入坐標(biāo):"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine_board[x][y] == '1') //玩家踩到雷,游戲結(jié)束 { printf("游戲結(jié)束\n"); DisPlayboard(mine_board, ROW, COL); break; } ret = Num(mine_board, x, y); if (ret == 0) //周圍沒(méi)有雷時(shí),展開(kāi)周圍格子 { Open(mine_board, show_board, x, y); DisPlayboard(show_board, ROW, COL); } else if (ret != 0) //周圍有雷時(shí)打印雷的個(gè)數(shù) { show_board[x][y] = ret + 48; DisPlayboard(show_board, ROW, COL); } } else printf("輸入錯(cuò)誤,請(qǐng)重新輸入"); } }
9.函數(shù)聲明,宏定義,函數(shù)的定義實(shí)現(xiàn),測(cè)試。
源文件:test.c //主要負(fù)責(zé)測(cè)試整個(gè)代碼
頭文件:game.h //包含函數(shù)各種聲明,宏定義
源文件:game.c //包含各種函數(shù)的定義
test.c
#include"game.h" void menu() { printf("************************************\n"); printf("************************************\n"); printf("******* 1.play *******\n"); printf("******* 0.exit *******\n"); printf("************************************\n"); } int game() { char show_board[ROWS][COLS] = { 0 }; char mine_board[ROWS][COLS] = { 0 }; // Initboard(show_board, ROWS, COLS,'*'); //初始化數(shù)組 Initboard(mine_board, ROWS, COLS, '0'); printf("游戲開(kāi)始\n"); DisPlayboard(show_board, ROW, COL); //打印玩家雷盤 // GetBoom(mine_board, ROW, COL); //埋雷 printf("\n\n\n"); DisPlayboard(mine_board, ROW, COL); //打印雷盤 // if (Judge_first(mine_board, show_board, ROW, COL) == 2) //如果一次勝利,就不再執(zhí)行PlayerMove函數(shù) return 2; // PlayerMove(mine_board, show_board, ROW, COL); } void test() { int n; menu(); do { printf("請(qǐng)輸入選項(xiàng)按鈕: "); scanf("%d", &n); switch (n) { case 1: game(); break; case 0: printf("游戲退出\n"); break; default: printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n"); break; } }while(1); } int main() { srand((unsigned int)time(NULL)); test(); }
game.c
#include"game.h" void Initboard(char board[ROWS][COLS], int row, int col, char set) { memset(board, set, row*col * sizeof(board[0][0])); } void DisPlayboard(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; printf(" "); for (i = 1; i <= row; 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"); } printf("\n"); } void GetBoom(char board[ROWS][COLS], int row, int col) //埋雷 { int x = 0; int y = 0; int sum = 0; while(1) { x = rand() % row +1; //雷放在1-9的范圍里 y = rand() % col +1; if (1) { board[x][y] = '1'; sum++; if (sum == M) //埋入所需的雷后跳出循環(huán) { break; } } } } int Judge_first(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int m; int n; printf("請(qǐng)輸入要排查的坐標(biāo):"); scanf("%d%d", &x, &y); while (1) { if (mine_board[x][y] == '1') //如果第一次踩雷,將此坐標(biāo)改為非雷 { mine_board[x][y] = '0'; show_board[x][y] = ' '; while (1) { m = rand() % 9 + 1; n = rand() % 9 + 1; if (m != x && n != y && mine_board[m][n] != '1') { mine_board[m][n] = '1'; } Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) //展開(kāi)后判斷是否一次獲得勝利 { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); return 2; //一次獲得勝利返回2 不再執(zhí)行PlayerMove函數(shù) break; } DisPlayboard(show_board, row, col); break; } break; } else if (mine_board[x][y] == '0') { show_board[x][y] = ' '; Open(mine_board, show_board, x, y); if (Full(show_board, ROW, COL) == 1) { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); return 2; break; } DisPlayboard(show_board, row, col); break; } } } void PlayerMove(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int ret = 0; while (1) { if (Full(show_board, ROW, COL) == 1) //棋盤下滿玩家勝利 { printf("游戲勝利\n"); DisPlayboard(mine_board, ROW, COL); break; } printf("請(qǐng)輸入坐標(biāo):"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine_board[x][y] == '1') { printf("游戲結(jié)束\n"); DisPlayboard(mine_board, ROW, COL); break; } ret = Num(mine_board, x, y); if (ret == 0) //周圍沒(méi)有雷時(shí),展開(kāi)周圍格子 { Open(mine_board, show_board, x, y); DisPlayboard(show_board, ROW, COL); } else if (ret != 0) //周圍有雷時(shí)打印雷的個(gè)數(shù) { show_board[x][y] = ret + 48; DisPlayboard(show_board, ROW, COL); } } else printf("輸入錯(cuò)誤,請(qǐng)重新輸入"); } } void Open(char mine_board[ROWS][COLS],char show_board[ROWS][COLS], int x, int y) { int ret = 0; ret = Num(mine_board, x, y); if (ret == 0) //當(dāng)坐標(biāo)周圍雷個(gè)數(shù)為0時(shí) 打開(kāi)周圍格子 再以X和Y周圍八個(gè)坐標(biāo)為中心展開(kāi) 重復(fù)即為遞歸展開(kāi) { show_board[x][y] = ' '; if (x - 1 > 0 && y - 1 > 0 && show_board[x - 1][y - 1] == '*') { Open(mine_board, show_board, x - 1, y - 1); } if (x - 1 > 0 && y > 0 && show_board[x - 1][y] == '*') { Open(mine_board, show_board, x - 1, y); } if (x - 1 > 0 && y + 1 <= COL && show_board[x - 1][y + 1] == '*') { Open(mine_board, show_board, x - 1, y + 1); } if (x > 0 && y + 1 <= COL && show_board[x][y + 1] == '*') { Open(mine_board, show_board, x, y + 1); } if (x + 1 < ROW && y + 1 <= COL && show_board[x + 1][y + 1] == '*') { Open(mine_board, show_board, x + 1, y + 1); } if (x + 1 <= ROW && y > 0 && show_board[x + 1][y] == '*') { Open(mine_board, show_board, x + 1, y); } if (x + 1 <= ROW && y - 1 > 0 && show_board[x + 1][y - 1] == '*') { Open(mine_board, show_board, x + 1, y - 1); } if (x > 0 && y - 1 > 0 && show_board[x][y - 1] == '*') { Open(mine_board, show_board, x, y - 1); } } else if (ret != 0) show_board[x][y] = Num(mine_board, x, y) + 48; } int Num(char board[ROWS][COLS], int x, int y) { int sum = 0; sum = board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] - (8 * '0'); return sum; } int Full(char board[ROWS][COLS], int row, int col) { int i; int j; int sum = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (board[i][j] == '*') sum++; } } if (sum == M) return 1; }
game.h
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include <stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW + 2 #define COLS COL + 2 #define M 10 //所需雷的個(gè)數(shù) void test(); int game(); void Initboard(char board[ROWS][COLS], int row, int col, int set); //初始化數(shù)組 void DisPlayboard(char board[ROWS][COLS], int row, int col); //打印雷盤 void GetBoom(char board[ROWS][COLS], int row, int col); //安放炸彈 int Judge_first(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col); //保證第一次不是雷 void PlayerMove(char mine_board[ROWS][COLS], char show_board[ROWS][COLS], int row, int col); //玩家排雷 void Open(char mine_board[ROWS][COLS],char show_board[ROWS][COLS], int x, int y); //展開(kāi)函數(shù) int Num(char mine_board[ROWS][COLS], int x, int y); //計(jì)算坐標(biāo)周圍雷的數(shù)量 int Full(char board[ROWS][COLS], int row, int col); //判斷雷是否下滿
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于C語(yǔ)言實(shí)現(xiàn)的掃雷游戲代碼
- C語(yǔ)言開(kāi)發(fā)簡(jiǎn)易版掃雷小游戲
- C語(yǔ)言 掃雷程序的實(shí)現(xiàn)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲
- C語(yǔ)言快速實(shí)現(xiàn)掃雷小游戲
- C語(yǔ)言實(shí)現(xiàn)掃雷小游戲
- C語(yǔ)言代碼實(shí)現(xiàn)掃雷游戲
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小程序
- C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(適合初學(xué)者)
- C語(yǔ)言實(shí)現(xiàn)掃雷游戲及其優(yōu)化
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng)
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06C++編程中break語(yǔ)句和continue語(yǔ)句的學(xué)習(xí)教程
這篇文章主要介紹了C++編程中break語(yǔ)句和continue語(yǔ)句的學(xué)習(xí)教程,break和continue是C++循環(huán)控制中的基礎(chǔ)語(yǔ)句,需要的朋友可以參考下2016-01-01C語(yǔ)言字符串左旋的兩種實(shí)現(xiàn)方法
匯編語(yǔ)言中有一種移位指令叫做循環(huán)左移(ROL),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言字符串左旋的兩種實(shí)現(xiàn)方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02Qt 實(shí)現(xiàn)畫線筆鋒效果詳細(xì)原理及示例代碼
這篇文章主要介紹了Qt 實(shí)現(xiàn)畫線筆鋒效果詳細(xì)原理及示例代碼。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04JS調(diào)用C++函數(shù)拋出異常及捕捉異常詳解
這篇文章主要介紹了js調(diào)用C++函數(shù)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-08-08C++ 關(guān)于MFC多線程編程的注意事項(xiàng)
這篇文章主要介紹了C++ 關(guān)于MFC多線程編程的注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2015-06-06