摘要:有雷則返回雷數(shù)難度設(shè)置其實(shí)實(shí)現(xiàn)思路比較簡單,可以再設(shè)置和。
知識提要(自主編寫游戲所需要的知識):
1.函數(shù)的基本實(shí)現(xiàn);
2.二維數(shù)組;
目錄
效果圖:
?從以上效果圖中可見,我們需要實(shí)現(xiàn)的功能有:
1.隨機(jī)埋雷
2.顯示雷數(shù)
3.展開
4.標(biāo)記
5.判定輸贏
如果將雷,數(shù)字,和*同時放在一個數(shù)組里是不現(xiàn)實(shí)的,因?yàn)槿绻粋€格子中已經(jīng)放了雷,就不可能將其變?yōu)樾翘栵@示,所以我們得到一個大體思路,要用兩個數(shù)組,一個埋雷,一個顯示。
還是老規(guī)矩,創(chuàng)建3個文件
game.h先引用和定義必要的數(shù)據(jù)
# define _CRT_SECURE_NO_WARNINGS#include #include #include #define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 10
這次我們用"*"當(dāng)作未知量,"#"為標(biāo)記,"1"為雷,"0"為非雷(此處為一個伏筆)
這一部分比較簡單,所以就只簡單提一句
void menu(){ printf("*********************************/n"); printf("********* 1. Play *********/n"); printf("********* 0. Exit *********/n"); printf("*********************************/n"); }void game(){ char mine[ROWS][COLS] = { 0 };//存放雷的信息 char show[ROWS][COLS] = { 0 };//展示給玩家的棋盤 intialize(mine,ROWS ,COLS,"0"); intialize(show,ROWS ,COLS,"*"); //展示棋盤 print(show, ROW, COL); //布置雷 setmine(mine, ROW, COL); //排查 search(mine, show, ROW, COL,0);}int main(){ int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇>:"); scanf("%d", &input); switch (input) { case 1: printf("game start/n"); game(); break; case 0: printf("已退出游戲/n"); break; default: printf("選擇錯誤,請重新選擇/n"); break; } } while (input); return 0;}
這里可能有人要問,為什么要創(chuàng)建11*11的數(shù)組呢?
如果我們要在9*9的棋盤中找尋雷的個數(shù),那么就得找尋周圍8個元素,但是如果要找邊邊角角的格子附件雷的個數(shù),就涉及到數(shù)組越界的問題,不太好辦。所以我們將數(shù)組做大一圈,保證數(shù)組訪問不會越界
現(xiàn)在我們要考慮一個問題,這次我們有兩個二維數(shù)組要初始化,而且其中內(nèi)容也不同,那該怎么辦呢?
其實(shí)也比較簡單,只需要讓初始化函數(shù)多接受一個需要初始化的量就可以了
void intialize(char board[ROWS][COLS], int row, int col, char target){ int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = target; } }}
這樣就可以完成不同的初始化了
由于掃雷需要的棋盤比較大,為了方便游玩,這次還需要打印行列號
void print(char board[ROWS][COLS], int row, int col){ int i = 0; for (i = 0; i <= row; i++)//打印列號 { printf("%d ", i); } printf("/n"); for (i = 1; i <= row; i++) { int j = 0; printf("%d ", i);//打印行號 for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("/n"); }}
效果圖:
布置雷就牽扯到隨機(jī)數(shù)的問題,要保證雷不會重復(fù)布置且只在9*9的棋盤中布置
void setmine(char board[ROWS][COLS], int row, int col){ int x = 0; int y = 0; int count = 0; while (1)//未布置滿就一直循環(huán) { x = rand() % row + 1;//使x,y在1~9間,保證數(shù)組不越界布置 y = rand() % col + 1; if (board[x][y] != "1")//保證布置的雷不重復(fù) { board[x][y] = "1"; count++; } if (count == EASY_COUNT)//布置滿所有不重復(fù)的雷后才可跳出循環(huán) break; }}
為了防止第一次排查就猝死,提高游戲體驗(yàn)所以我們需要設(shè)計(jì)一下,讓玩家如果第一次就踩雷,棋盤會重置,直到此處沒有雷
first_die++;if (first_die == 1 && mine[x][y] == "1")//first_die在test中創(chuàng)建,默認(rèn)傳遞0進(jìn)入 { while (mine[x][y] == "1") { intialize(mine, ROWS, COLS, "0");//必須先初始化棋盤,不然會導(dǎo)致原本的雷依然在 setmine(mine, ROW, COL); } }
int search_show(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");}
"0"的ASCII值為48,我們將雷設(shè)計(jì)為"1"就是為了方便相加以后減去8個"0",直接就可以得到雷的數(shù)量
下面就是本文章的重點(diǎn)之一,雷的排查,其實(shí)實(shí)現(xiàn)思路也比較簡單,如果踩到雷,游戲結(jié)束;如果沒有,繼續(xù)游戲,同時顯示附近雷的個數(shù)
int x = 0; int y = 0; while (1) { printf("請輸入需要排查的坐標(biāo),如:1 1/n"); scanf("%d%d", &x, &y); first_die++; if (x >= 1 && x <= row && y >= 1 && y <= col)//判斷輸入的行列號是否在規(guī)定范圍 { if (mine[x][y] == "1") { printf("你死了,請?jiān)俳釉賲?n"); print(mine, ROW, COL); break; } else { show[x][y] = search_show(mine, ROW, COL)+"0";//顯示周圍的雷數(shù) open(mine,show, x, y,row,col); print(show, ROW, COL); } } else { printf("輸入錯誤,請重新輸入/n"); }
我們可以在排查以后加入一個標(biāo)記功能,我們規(guī)定用"#"標(biāo)記,同時只能標(biāo)記未知量
//標(biāo)記地雷 int input1 = 0; int input2 = 0; if (x >= 1 && x <= row && y >= 1 && y <= col) { do//至少要運(yùn)行一次 { printf("請輸入標(biāo)記坐標(biāo),輸入0 0退出標(biāo)記/n"); scanf("%d%d", &input1, &input2); if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col) { if (show[input1][input2] == "*")//只標(biāo)記未知量 { show[input1][input2] = "#"; print(show, ROW, COL); } else { printf("標(biāo)記失敗,請重新標(biāo)記/n"); } } else if (input1 == 0 && input2 == 0)//輸入0 0退出標(biāo)記 break; else { printf("標(biāo)記錯誤,請重新標(biāo)記/n"); } } while (input1&&input2); printf("已退出標(biāo)記/n"); }
這應(yīng)該是最難實(shí)現(xiàn)的一部分,這里我們用到遞歸的思想
void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col){ int ret = 0; ret =search_show(mine,x,y); if (ret == 0)//如果周圍無雷,判斷展開 { show[x][y] = " ";//防止死遞歸,如果不將show[x][y]變?yōu)? ",則下一次檢測可能又會是*,再次進(jìn)入遞歸,直至卡死。 if (x - 1 > 0 && y > 0 && show[x - 1][y] == "*"|| show[x - 1][y] == "#") open(mine, show, x - 1, y, row, col); if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == "*"|| show[x - 1][y + 1] == "#") open(mine, show, x - 1, y + 1, row, col); if (x > 0 && y + 1 <= col && show[x][y + 1] == "*"|| show[x][y + 1] == "#") open(mine, show, x, y + 1, row, col); if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == "*"|| show[x + 1][y + 1] == "#") open(mine, show, x + 1, y + 1, row, col); if (x + 1 <= row && y > 0 && show[x + 1][y] == "*"|| show[x + 1][y] == "#") open(mine, show, x + 1, y, row, col); if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == "*"|| show[x + 1][y - 1] == "#") open(mine, show, x + 1, y - 1, row, col); if (x > 0 && y - 1 > 0 && show[x][y - 1] == "*"|| show[x][y - 1] == "#") open(mine, show, x, y - 1, row, col); if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == "*"|| show[x - 1][y - 1] == "#") open(mine, show, x - 1, y - 1, row, col); } else//有雷則返回雷數(shù) { return show[x][y]=search_show(mine, x, y)+"0"; }}
其實(shí)實(shí)現(xiàn)思路比較簡單,可以再設(shè)置MIDDLE_COUNT和HARD_COUNT。
傳參時,將難度數(shù)字也傳進(jìn)去即可
這里交給大家去自行實(shí)現(xiàn),不算難
game.h# define _CRT_SECURE_NO_WARNINGS#include #include #include #define ROW 9#define COL 9#define ROWS ROW+2#define COLS COL+2#define EASY_COUNT 10//初始化void intialize(char board[ROWS][COLS], int row, int col, char target);//打印棋盤void print(char board[ROWS][COLS], int row, int col);//布置雷void setmine(char board[ROWS][COLS], int row, int col);//排查雷void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,intgame.c# define _CRT_SECURE_NO_WARNINGS# include "game.h"void intialize(char board[ROWS][COLS], int row, int col, char target){ int i = 0; for (i = 0; i < row; i++) { int j = 0; for (j = 0; j < col; j++) { board[i][j] = target; } }}void print(char board[ROWS][COLS], int row, int col){ int i = 0; for (i = 0; i <= row; i++) { printf("%d ", i); } printf("/n"); for (i = 1; i <= row; i++) { int j = 0; printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("/n"); }}void setmine(char board[ROWS][COLS], int row, int col){ int x = 0; int y = 0; int count = 0; while (1) { x = rand() % row + 1; y = rand() % col + 1; if (board[x][y] != "1") { board[x][y] = "1"; count++; } if (count == EASY_COUNT) break; }}int search_show(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");}void open(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row ,int col){ int ret = 0; ret =search_show(mine,x,y); if (ret == 0)//如果周圍無雷,判斷展開 { show[x][y] = " ";//防止死遞歸,如果不將show[x][y]變?yōu)? ",則下一次檢測可能又會是*,再次進(jìn)入遞歸,直至卡死。 if (x - 1 > 0 && y > 0 && show[x - 1][y] == "*"|| show[x - 1][y] == "#") open(mine, show, x - 1, y, row, col); if (x - 1 > 0 && y + 1 <= col && show[x - 1][y + 1] == "*"|| show[x - 1][y + 1] == "#") open(mine, show, x - 1, y + 1, row, col); if (x > 0 && y + 1 <= col && show[x][y + 1] == "*"|| show[x][y + 1] == "#") open(mine, show, x, y + 1, row, col); if (x + 1 <= row && y + 1 <= col && show[x + 1][y + 1] == "*"|| show[x + 1][y + 1] == "#") open(mine, show, x + 1, y + 1, row, col); if (x + 1 <= row && y > 0 && show[x + 1][y] == "*"|| show[x + 1][y] == "#") open(mine, show, x + 1, y, row, col); if (x + 1 <= row && y - 1 > 0 && show[x + 1][y - 1] == "*"|| show[x + 1][y - 1] == "#") open(mine, show, x + 1, y - 1, row, col); if (x > 0 && y - 1 > 0 && show[x][y - 1] == "*"|| show[x][y - 1] == "#") open(mine, show, x, y - 1, row, col); if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == "*"|| show[x - 1][y - 1] == "#") open(mine, show, x - 1, y - 1, row, col); } else { return show[x][y]=search_show(mine, x, y)+"0"; }}int win(char show[ROWS][COLS], int row, int col){ int i = 0; int j = 0; int count = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (show[i][j] == "*"||show[i][j]=="#") count++; } } if (count == EASY_COUNT) return 1; else return 0;}void search(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int first_die){ int x = 0; int y = 0; while (1) { printf("請輸入需要排查的坐標(biāo),如:1 1/n"); scanf("%d%d", &x, &y); first_die++; //防止第一次暴斃 if (first_die == 1 && mine[x][y] == "1") { while (mine[x][y] == "1") { intialize(mine, ROWS, COLS, "0"); setmine(mine, ROW, COL); } } if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == "1") { printf("你死了,請?jiān)俳釉賲?n"); print(mine, ROW, COL); break; } else { show[x][y] = search_show(mine, ROW, COL)+"0";//顯示周圍的雷數(shù) open(mine,show, x, y,row,col); print(show, ROW, COL); } } else { printf("輸入錯誤,請重新輸入/n"); } //判斷輸贏 int Win = win(show, row, col); if (Win == 1) { printf("恭喜您,勝利了/n"); break; } //標(biāo)記地雷 int input1 = 0; int input2 = 0; if (x >= 1 && x <= row && y >= 1 && y <= col) { do { printf("請輸入標(biāo)記坐標(biāo),輸入0 0退出標(biāo)記/n"); scanf("%d%d", &input1, &input2); if (input1 >= 1 && input1 <= row && input2 >= 1 && input2 <= col) { if (show[input1][input2] == "*") { show[input1][input2] = "#"; print(show, ROW, COL); } else { printf("標(biāo)記失敗,請重新標(biāo)記/n"); } } else if (input1 == 0 && input2 == 0) break; else { printf("標(biāo)記錯誤,請重新標(biāo)記/n"); } } while (input1&&input2); printf("已退出標(biāo)記/n"); } }}test.c# define _CRT_SECURE_NO_WARNINGS# include "game.h"void menu(){ printf("*********************************/n"); printf("********* 1. Play *********/n"); printf("********* 0. Exit *********/n"); printf("*********************************/n"); }void game(){ char mine[ROWS][COLS] = { 0 };//存放雷的信息 char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息 intialize(mine,ROWS ,COLS,"0"); intialize(show,ROWS ,COLS,"*"); //展示棋盤 print(show, ROW, COL); //布置雷 setmine(mine, ROW, COL); //排查 search(mine, show, ROW, COL,0);}int main(){ int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇>:"); scanf("%d", &input); switch (input) { case 1: printf("game start/n"); game(); break; case 0: printf("已退出游戲/n"); break; default: printf("選擇錯誤,請重新選擇/n"); break; } } while (input); return 0;}
以上就是本次的分享內(nèi)容了,喜歡我的分享的話,別忘了點(diǎn)贊加關(guān)注喲!
如果你對我的文章有任何看法,歡迎在下方評論留言或者私信我鴨!
我是白晨,我們下次分享見!!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/121852.html
摘要:目錄前言前言前期的準(zhǔn)備前期的準(zhǔn)備游戲代碼的具體實(shí)現(xiàn)游戲代碼的具體實(shí)現(xiàn)完整版的掃雷小游戲代碼完整版的掃雷小游戲代碼總結(jié)總結(jié)前言掃雷是一款大眾類的益智小游戲,于年發(fā)行。 目錄 前言 前期的準(zhǔn)備 游戲代碼的具體實(shí)現(xiàn) 1、text.c 2、game.h 3、game.c 完整版的掃雷小游戲代碼: 1...
摘要:條消息語言入門三子棋語言實(shí)現(xiàn)詳細(xì)版的博客博客條消息語言入門三子棋語言實(shí)現(xiàn)詳細(xì)版的博客博客我們將雷盤初始化為統(tǒng)一的符號。 目錄 1.原理簡介 2.分布目標(biāo)及代碼實(shí)現(xiàn) 3.總結(jié) 1.原理簡介 ?首先我們需要一個空的雷盤,在其中隨機(jī)埋入十枚雷,當(dāng)我們排這顆雷時,若此位置為雷,則游戲失敗,若不...
摘要:作者時間網(wǎng)站地址摘要語言實(shí)現(xiàn)我們小時候玩過的掃雷游戲,最近看到了一些掃雷游戲的簡單實(shí)現(xiàn),但是總有功能上的缺失,玩起來不那么的原汁原味,因此我增加了一些新功能確保玩家首次排雷一定不會炸死。 ...
摘要:上一期咱們用語言實(shí)現(xiàn)了三子棋的小游戲語言實(shí)現(xiàn)三子棋今天我們再來寫個掃雷的游戲,說起掃雷,相信大家都不陌生,可能許多朋友還是玩掃雷的高手。 ? ? ?上一期咱們用C語言實(shí)現(xiàn)了三子棋的小游戲? C語言實(shí)現(xiàn)三子棋? ? ? ?今天我們再來寫個掃雷的游戲,說起掃雷,相信大家都不陌生,可能許多朋友還是...
閱讀 1225·2021-11-11 16:54
閱讀 1738·2021-10-13 09:40
閱讀 933·2021-10-08 10:05
閱讀 3498·2021-09-22 15:50
閱讀 3701·2021-09-22 15:41
閱讀 1782·2021-09-22 15:08
閱讀 2338·2021-09-07 10:24
閱讀 3570·2019-08-30 12:52