摘要:上一期咱們用語言實現(xiàn)了三子棋的小游戲語言實現(xiàn)三子棋今天我們再來寫個掃雷的游戲,說起掃雷,相信大家都不陌生,可能許多朋友還是玩掃雷的高手。
? ? ?上一期咱們用C語言實現(xiàn)了三子棋的小游戲? C語言實現(xiàn)三子棋?
? ? ?今天我們再來寫個掃雷的游戲,說起掃雷,相信大家都不陌生,可能許多朋友還是玩掃雷的高手。
?
其實掃雷和三子棋有許多相似之處,都需要用到數(shù)組的知識。
? 今天的掃雷也是相當(dāng)有趣的
由于博主是一個編程學(xué)習(xí)的小白,所以這只是掃雷的初級版,此版本有一些功能還無法實現(xiàn),在后續(xù)的學(xué)習(xí)中,我會持續(xù)更新,不斷對這個小游戲進(jìn)行優(yōu)化,期待大家的關(guān)注,還有,這篇文章中若有錯誤或不當(dāng)?shù)牡胤剑瑲g迎大家指正!??
關(guān)于這個掃雷項目的代碼,歡迎訪問我的gitee代碼倉庫:
https://gitee.com/living-amethyst/code2021/tree/master/test_11_09_mine%20clearance?
? 讓我們開始吧!
目錄
?
為了讓代碼的可讀性更高,思維性更強(qiáng),我們需要創(chuàng)建三個文件來完成這個項目
?然后我們需要建立兩個棋盤,為什么呢?
?
?我們先想一下掃雷的游戲規(guī)則,如圖,如果我選中的方塊不是雷,那么它上面就會顯示一個數(shù)字,這個數(shù)字代表它以它為中心的這個3*3區(qū)域內(nèi)(紅色方框)地雷的個數(shù),它的范圍是0~8,我們初步的設(shè)想是:無雷的放數(shù)字0,有雷的放數(shù)字1
? ? ?但是如果我這個方塊不是雷,顯示它周圍的雷的格式時,如果它的周圍有一個雷,需要顯示
數(shù)字1時?,我們就會分不清這個1 是雷?還是排查出的周圍雷的個數(shù)?所以我們需要建立兩個棋盤
?一個棋盤用來存放布置好的雷的信息(這是游戲結(jié)束前不讓玩家看到的)
?另一個棋盤存放排查好的雷的信息(這是游戲過程中玩家看到的)
還有一個問題
如果我們布置的棋盤是9*9的?
? ? 當(dāng)我們選擇了排查這個位置的周圍的雷的個數(shù)時,它的旁邊就沒有了,所以我們要將棋盤擴(kuò)展為11*11
(但是打印時只打印9*9的棋盤 )
如圖,這樣我們就能排查這格周圍的地雷的個數(shù)了
我們具體這樣操作
?
與之前的三子棋游戲一樣,我們首先需要設(shè)置一個游戲菜單
? ?由于一進(jìn)入游戲,我們首先就要看到菜單,所以這里我們采用do...while循環(huán)
我們的菜單需要實現(xiàn)的功能有:
void menu(){ printf("************************/n"); printf("***** 1.play *******/n"); printf("***** 0.exit *******/n"); printf("************************/n"); }void test(){ int input = 0; do { menu(); printf("請選擇"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戲/n"); break; default: printf("選擇錯誤/n"); break; } } while (input);}int main(){ test(); return 0;}
?
?這里我們創(chuàng)建了test函數(shù)和menu函數(shù),為的是讓邏輯更清晰,現(xiàn)在我們的菜單部分就完成了
對于這個游戲菜單,我們能實現(xiàn)的游戲功能有:?
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?這是菜單的運行效果
//創(chuàng)建數(shù)組 char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息 char show[ROWS][COLS] = { 0 };//存放排查好的雷的信息
我們把mine數(shù)組作為存放布置好的雷的信息的棋盤
? ? ? ?把show數(shù)組作為存放排查好的雷的信息棋盤?
我們用一個InitBoard函數(shù)來初始化這兩個棋盤?
?看代碼:
//函數(shù)的聲明void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);//函數(shù)的定義void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){ int i = 0; int j = 0; for(i = 0;i < rows;i++) { for (j = 0;j < cols;j++) { board[i][j] = set; } }}//函數(shù)的調(diào)用//初始化mine數(shù)組為全字符"0" InitBoard(mine,ROWS,COLS,"0"); //初始化show數(shù)組為全"*" InitBoard(show,ROWS,COLS,"*");
我們把mine數(shù)組全部初始化為字符 " 0 "
? ? ? ?把show數(shù)組全部初識化為字符 " * "?
我們與兩個棋盤
其中?mine數(shù)組代表的棋盤時游戲結(jié)束后或者游戲測試人員才能看到的
另一個show數(shù)組代表的棋盤是玩家玩游戲時能看到的
我們上代碼
//函數(shù)的定義void DisplayBoard(char board[ROWS][COLS], int row, int col);//函數(shù)的定義void DisplayBoard(char board[ROWS][COLS], int row, int col){ //1-9 int i = 0; int j = 0; printf("/n"); printf("---掃雷游戲---/n"); //打印列號 for (i = 0;i <= col;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"); } }//函數(shù)的調(diào)用DisplayBoard(show, ROW, COL);//只打印9*9的內(nèi)容
下面我們就可以來布置雷啦,由于雷是隨機(jī)布置的,于是我們就要用到rand函數(shù)?
srand((unsigned int)time(NULL));? ? ?//進(jìn)行初始化
x = rand() % row+1;? ? ? ? ??//x的范圍是1~9
y = rand() % ?col+1;? ? ? ? ??//y的范圍是1~9
下面看代碼:
//函數(shù)的聲明void SetMine(char mine[ROWS][COLS],int row,int col);//函數(shù)的定義void SetMine(char mine[ROWS][COLS], int row, int col){ //布置10個雷 int count = EASY_COUNT; while (count) { //生產(chǎn)隨機(jī)的下標(biāo) int x = rand() % row + 1;//范圍1到9 int y = rand() % col + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }}//函數(shù)的調(diào)用SetMine(mine, ROW, COL);
?
?我們加上mine棋盤的打印,并將它注釋掉,這是為了方便我們測試游戲或這檢查游戲出現(xiàn)的問題的
這里的EASY_COUNT是雷的個數(shù),我們用define定義它
關(guān)于排查雷,我們是這樣實現(xiàn)的:
- 輸入排查雷的坐標(biāo)
- 檢查該坐標(biāo)是不是雷
- ??? (1)是雷 ? ?--> 很遺憾炸死了
- ? ? (0)不是雷 ?--> 統(tǒng)計坐標(biāo)周圍有幾個雷-->存儲排查雷的信息到show數(shù)組,游戲繼續(xù)?
這里我們用了?get_mine_count? 和? FindMine??兩個函數(shù)
get_mine_count函數(shù)用來統(tǒng)計坐標(biāo)周圍有幾個雷
看代碼
//聲明void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);//從mine中排查放到show中//排查雷int get_mine_count(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+1] + mine[x + 1][y] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * "0";}void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ //1.輸入排查雷的坐標(biāo) //2.檢查該坐標(biāo)是不是雷 //(1)是雷 --> 很遺憾炸死了 //(0)不是雷 --> 統(tǒng)計坐標(biāo)周圍有幾個雷-->存儲排查雷的信息到show數(shù)組,游戲繼續(xù) int x = 0; int y = 0; int win = 0; while (win= 1 && x <= col && y >= 1 && y <= row) { if (mine[x][y] == "1") { printf("很遺憾,你被炸死了/n"); DisplayBoard(mine, row, col);//把怎么被炸死的顯現(xiàn)出來 break; } else { //不是雷的話統(tǒng)計(x,y)坐標(biāo)周圍有幾個雷 int count = get_mine_count(mine, x, y); show[x][y] = count+"0"; //顯示排查出的信息 DisplayBoard(show, row, col); win++; } } else { printf("坐標(biāo)不合法,請重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!"); DisplayBoard(mine, row, col); } }//調(diào)用FindMine(mine,show,ROW,COL);
?這里有幾個需要說明的點:
1.
?這里函數(shù)有兩個形參,是為了從mine中排查然后放到show中
2.
?
這些代表查找的坐標(biāo)的周圍其他格子的坐標(biāo)
3.由于我們在棋盤中存放的是字符 "0 "和字符 "1"?
我們先看一下?ASCII碼 表
?
?我們可以發(fā)現(xiàn)"0" "1" "2"這些字符的ASCII碼值都是連續(xù)的,我們想顯示出排查格子周圍雷的個數(shù),需要先將字符"0","1","2"...轉(zhuǎn)化為數(shù)字 0,1 ,2,3...
我們只需要把每個字符減去一個"0",它的ASCII碼值是48就可以了,看看我們是如何操作的吧:
?之后再轉(zhuǎn)化成字符的形式存到數(shù)組中
4.我們還要判斷玩家輸入坐標(biāo)的合法性:
?
game.h—— 游戲函數(shù)的聲明
#pragma once#include#include#include#define ROW 9#define COL 9#define EASY_COUNT 10#define ROWS ROW+2#define COLS COL+2//初始化棋盤void InitBoard(char board[ROWS][COLS], int rows,int cols,char set);//打印棋盤void DisplayBoard(char board[ROWS][COLS], int row, int col);//布置雷void SetMine(char mine[ROWS][COLS],int row,int col);//排查雷void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
?
?game.c—— 游戲函數(shù)的實現(xiàn)
#define _CRT_SECURE_NO_WARNINGS#include"game.h"http://初始化void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){ int i = 0; int j = 0; 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){ //1-9 int i = 0; int j = 0; printf("/n"); printf("---掃雷游戲---/n"); //打印列號 for (i = 0;i <= col;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"); } }//布置雷void SetMine(char mine[ROWS][COLS], int row, int col){ //布置10個雷 int count = EASY_COUNT; while (count) { //生產(chǎn)隨機(jī)的下標(biāo) int x = rand() % row + 1;//范圍1到9 int y = rand() % col + 1; if (mine[x][y] == "0") { mine[x][y] = "1"; count--; } }}int get_mine_count(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+1] + mine[x + 1][y] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * "0";}//排查雷void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col){ //1.輸入排查雷的坐標(biāo) //2.檢查該坐標(biāo)是不是雷 //(1)是雷 --> 很遺憾炸死了 //(0)不是雷 --> 統(tǒng)計坐標(biāo)周圍有幾個雷-->存儲排查雷的信息到show數(shù)組,游戲繼續(xù) int x = 0; int y = 0; int win = 0; while (win= 1 && x <= col && y >= 1 && y <= row) { if (mine[x][y] == "1") { printf("很遺憾,你被炸死了/n"); DisplayBoard(mine, row, col);//把怎么被炸死的顯現(xiàn)出來 break; } else { //不是雷的話統(tǒng)計(x,y)坐標(biāo)周圍有幾個雷 int count = get_mine_count(mine, x, y); show[x][y] = count+"0"; //顯示排查出的信息 DisplayBoard(show, row, col); win++; } } else { printf("坐標(biāo)不合法,請重新輸入/n"); } } if (win == row * col - EASY_COUNT) { printf("恭喜你,排雷成功!"); DisplayBoard(mine, row, col); } }
?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(){ //創(chuàng)建數(shù)組 char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息 char show[ROWS][COLS] = { 0 };//存放排查好的雷的信息 //初始化mine數(shù)組為全字符"0" InitBoard(mine,ROWS,COLS,"0"); //初始化show數(shù)組為全"*" InitBoard(show,ROWS,COLS,"*"); //打印棋盤 DisplayBoard(show, ROW, COL);//只打印9*9的內(nèi)容 //布置雷 SetMine(mine, ROW, COL); /*DisplayBoard(mine, ROW, COL);*/ //這是不給玩家看到的 //排查雷 FindMine(mine,show,ROW,COL);//從mine中排查放到show中}void test(){ int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請選擇:/n"); scanf("%d", &input); switch (input) { case 1: //掃雷 game(); break; case 0: break; default: printf("選擇錯誤"); break; } } while (input);}int main(){ test(); return 0;}
好了,這樣我們就把掃雷游戲編寫完成了
?如果你玩過正宗的掃雷游戲,那你肯定知道,掃雷游戲還有兩個功能:
這就是我們以后給這個游戲的優(yōu)化方案
其中第一個功能我們需要使用遞歸實現(xiàn)
這些都會再以后更新,歡迎持續(xù)關(guān)注 !
??
?
?
?
?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/123065.html
摘要:條消息語言入門三子棋語言實現(xiàn)詳細(xì)版的博客博客條消息語言入門三子棋語言實現(xiàn)詳細(xì)版的博客博客我們將雷盤初始化為統(tǒng)一的符號。 目錄 1.原理簡介 2.分布目標(biāo)及代碼實現(xiàn) 3.總結(jié) 1.原理簡介 ?首先我們需要一個空的雷盤,在其中隨機(jī)埋入十枚雷,當(dāng)我們排這顆雷時,若此位置為雷,則游戲失敗,若不...
摘要:有雷則返回雷數(shù)難度設(shè)置其實實現(xiàn)思路比較簡單,可以再設(shè)置和。 知識提要(自主編寫游戲所需要的知識): 1.函數(shù)的基本實現(xiàn); 2.二維數(shù)組; 目錄 掃雷 1.基本界面的實現(xiàn) 2.初始化棋盤(二維數(shù)組) 3.棋盤的打印 4.布置雷 5.安全保護(hù) 6.雷數(shù)顯示 7.排查雷 8.標(biāo)記雷 9.展開 10...
摘要:函數(shù)游戲菜單請選擇掃雷游戲退出游戲選擇錯誤解析函數(shù)內(nèi)部利用時間戳,形成隨機(jī)數(shù),主要目的是實現(xiàn)游戲中地雷的隨機(jī)埋放。 前言 本篇文章使用C語言實現(xiàn)簡單小游戲---掃雷。(文章最后有完整代碼鏈接) 想必大多數(shù)人都玩過或者了解過掃雷的游戲規(guī)則,但是在這里,我們在一起重溫一下掃雷的游戲規(guī)則,也更好...
摘要:玩家選擇開始游戲后,出現(xiàn)雷盤,并且隨機(jī)布置雷。雷盤的數(shù)組大小為,方便計算掃雷時周圍雷的數(shù)量,并防止數(shù)組越界。放置布置的雷的信息放置排查出雷的信息初始化雷盤初始化展示界面打印展示界面效果如下布置雷隨機(jī)在數(shù)組中讓十個變成作為雷。 目錄 前言 一、游戲思路 二、游戲框架 1.菜單界面 1.菜單:...
摘要:寫在前面我們已經(jīng)寫過了三子棋小游戲肯定沒玩過癮,我們再寫個掃雷小游戲吧目錄寫在前面認(rèn)識游戲游戲規(guī)則游戲框架游戲?qū)崿F(xiàn)效果展示全部代碼文件文件文件認(rèn)識游戲相信大家對掃雷都不陌生每臺電腦必備的小游戲游戲規(guī)則就是在規(guī)定的時間將 ...
閱讀 3564·2023-04-26 00:05
閱讀 954·2021-11-11 16:55
閱讀 3522·2021-09-26 09:46
閱讀 3517·2019-08-30 15:56
閱讀 909·2019-08-30 15:55
閱讀 2933·2019-08-30 15:53
閱讀 1939·2019-08-29 17:11
閱讀 814·2019-08-29 16:52