前言
????????結(jié)合前邊我們所學(xué)的C語言知識,本期我們將使用C語言實現(xiàn)一個簡單的小游戲——掃雷
目錄
前言
總體框架設(shè)計
多文件分裝程序
各功能模塊化實現(xiàn)
初始化棋盤
?棋盤打印
埋雷
?判贏與排雷
游戲邏輯安排
總結(jié)
1. 總體框架設(shè)計
????????和三子棋相同,游戲開始時不需要任何判斷與操作直接進(jìn)入游戲(符合我們所學(xué)的do…while結(jié)構(gòu)),然后再根據(jù)菜單選擇,開始游戲和退出游戲,這部分的操作與三子棋較為類似,這里不再詳細(xì)講解(詳請看三子棋那期博客)。
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("請選擇>:\n");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戲!\n");
break;
default:
printf("輸入錯誤請重新輸入>:\n");
break;
}
} while (input);
return 0;
}
?菜單打印部分也是相同
void menu()
{
printf("******************************\n");
printf("********* 1.play *********\n");
printf("********* 0.exit *********\n");
printf("******************************\n");
}
2. 多文件分裝程序
當(dāng)然根據(jù)之前的方法,我將程序分裝到多文件,.h文件用于聲明函數(shù),test.c文件用于程序設(shè)計,game.c文件用于函數(shù)定義。
注意:函數(shù)的定義和聲明是不同的(詳細(xì)請看函數(shù)那期內(nèi)容)
函數(shù)聲明(在.h文件中)
//初始化棋盤
void InitBoard(char board[ROWS][COLS], char set);
?函數(shù)定義(在函數(shù)實現(xiàn).c文件中)
void InitBoard(char board[ROWS][COLS], char set)
{
}
3. 各功能模塊化實現(xiàn)
????????接下來是最重要的部分,game()游戲部分的實現(xiàn)。游戲開始首先我們需要布置棋盤,設(shè)置雷的個數(shù),和三子棋有所不同,這里我們最好是創(chuàng)建兩個二維數(shù)組來存放我們的棋盤信息,一個棋盤用于玩家下棋棋盤,另外一個用于存放雷的信息。
3.1 初始化棋盤
InitBoard(mine,'0');//埋雷棋盤
InitBoard(show,'*');//玩家棋盤
?棋盤初始化和二維數(shù)組初始化相同
void InitBoard(char board[ROWS][COLS], char set)//字符型變量用于接收傳入的字符
{
for (int i = 0; i < ROWS; i++) {//為了便于更改棋盤大小這里需要定義字符型常量
for (int j = 0; j < COLS; j++) {
board[i][j] = set;
}
}
}
?3.2 棋盤打印
????????棋盤的打印沒有三子棋那么難,如果想要美化棋盤也是可以使用與三子棋結(jié)合的棋盤。
效果圖如下:
?這里我們采用上圖的效果進(jìn)行講解
void DisPlaybroad(char board[ROWS][COLS])
{
printf("------------------掃雷游戲------------------\n");//棋盤分割線
printf(" "); //與行打印對齊
for (int i = 1; i <=COL; i++) { //打印列數(shù)序號1~9
printf(" %d ", i);
}
printf("\n"); //打印完一行及時換行
printf(" -----------------------------------");//列與棋盤分割線
printf("\n");
for (int i = 1; i <= ROW; i++) { //打印行數(shù)序號
printf("%d ",i);
for (int j = 1; j <= COL; j++) { //與三子棋打印一樣" %c |"為一次循環(huán)進(jìn)行打印
printf(" %c ", board[i][j]);
if (j < COL) {
printf("|");
}
}
printf("\n");
if (i < ROW) {
for (int i = 1; i <=ROW; i++) {
if (i ==1) {
printf(" "); //空出第一列用于打印序列號
}
printf("---");
if (i < ROW) { //---|---|---為一個整體(一次循環(huán))循環(huán)打印
printf("|");
}
}
printf("\n");
}
}
}
3.3 埋雷
????????首先我們需要了解掃雷的規(guī)則,玩家選擇一個坐標(biāo),然后檢測該坐標(biāo)附近8個坐標(biāo)是否有雷,然后在玩家棋盤中顯示附近雷的個數(shù),簡單的9*9的棋盤在邊緣檢測時比較復(fù)雜,那么我們就可以采用11*11的棋盤去初始化,埋雷的位置限制在9*9的棋盤中,這樣就可以避免許多沒必要的判斷。
void SetMine(char board[ROWS][COLS]) {
int count = N;//雷的個數(shù)
while (count) {
int x = rand() % ROW + 1;//使用隨機數(shù)來進(jìn)行埋雷,與srand配合使用來實現(xiàn)真正的隨機。
int y = rand() % COL + 1;//COL,ROW等于9,隨機數(shù)與9求余范圍是0~8,加一范圍就變成了1~9
if (board[x][y] == '0') {//確保雷的位置不重復(fù)布置
board[x][y] = '1';//用1來表示雷
count--;//布置之后雷的數(shù)量減一
}
}
}
?字符型常量定于如下:
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define N 10
?3.4 判贏與排雷
????????這部分特別需要注意的是兩個棋盤之間的聯(lián)系。判斷雷的數(shù)量在埋雷的棋盤中進(jìn)行,打印輸出雷的信息在show這個數(shù)組展現(xiàn)。
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]) {
int x = 0;
int y = 0;
int win = 0;
while (win<COL*ROW-N) //判贏
{
printf("請輸入要排查的位置>:\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
if (mine[x][y] == '1') {
printf("很遺憾,你踩到了雷,游戲結(jié)束!\n");
DisPlaybroad(mine); //游戲結(jié)束打印埋雷棋盤
break;
}
else {
show[x][y] = Get_Mine(mine, x, y) + '0';//掃雷部分函數(shù)返回值是一個數(shù)字,而打印時是以字符的形式打印數(shù)字,所以加上‘0’轉(zhuǎn)變?yōu)閷?yīng)的ascll值,注意這里將埋雷棋盤的排雷信息通過函數(shù)返回給show棋盤。
DisPlaybroad(show);//沒有踩到雷繼續(xù)打印棋盤
win++;//計數(shù)
}
}
else {
printf("坐標(biāo)非法,請重新輸入!\n");
}
}
if (win == ROW * COL - N) {//9*9的棋盤埋10個雷,那需要走71步才能將雷掃完。
printf("恭喜你排雷成功!\n");
DisPlaybroad(mine);
}
}
int Get_Mine(char mine[ROWS][COLS], int x, int y)//排雷
{//在ascll表中數(shù)字都有對應(yīng)的ascll值,且是10個連續(xù)的,對應(yīng)0~9,數(shù)字字符
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');
}//判斷附近8個位置中雷的個數(shù),1是字符不是數(shù)字有對應(yīng)的ascll值,-8*‘0’減去8個字符0的ascll值
?以上便是游戲各模塊的實現(xiàn)。
3.5 游戲邏輯安排
????????游戲的各個模塊我們已經(jīng)基本實現(xiàn),接下來我們需要將各個模塊進(jìn)行組裝,使游戲順利運行。
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盤
InitBoard(mine,'0');
InitBoard(show,'*');
//埋雷
SetMine(mine);
//打印棋盤
DisPlaybroad(show);
//排雷+判贏
FindMine(mine,show);
}
?????????首先我們創(chuàng)建了兩個二維數(shù)組,游戲開始需要先初始化棋盤,游戲開始前我們需要先進(jìn)行埋雷操作,然后才是打印棋盤,最后就是判贏。這就是游戲大概整體邏輯。
4. 代碼
以下便是整體代碼的呈現(xiàn):
用于聲明的頭文件(.h文件)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define N 10
//初始化棋盤
void InitBoard(char board[ROWS][COLS], char set);
//打印棋盤
void DisPlaybroad(char board[ROWS][COLS]);
//埋雷
void SetMine(char board[ROWS][COLS]);
//排雷
void FindMine(char mine[ROWS][COLS],char show[ROWS][COLS]);
?函數(shù)定義文件(.c文件)
#include"game1.h"
void InitBoard(char board[ROWS][COLS], char set)
{
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = set;
}
}
}
void DisPlaybroad(char board[ROWS][COLS])
{
printf("------------------掃雷游戲------------------\n");
printf(" ");
for (int i = 1; i <=COL; i++) {
printf(" %d ", i);
}
printf("\n");
printf(" -----------------------------------");
printf("\n");
for (int i = 1; i <= ROW; i++) {
printf("%d ",i);
for (int j = 1; j <= COL; j++) {
printf(" %c ", board[i][j]);
if (j < COL) {
printf("|");
}
}
printf("\n");
if (i < ROW) {
for (int i = 1; i <=ROW; i++) {
if (i ==1) {
printf(" ");
}
printf("---");
if (i < ROW) {
printf("|");
}
}
printf("\n");
}
}
}
void SetMine(char board[ROWS][COLS]) {
int count = N;
while (count) {
int x = rand() % ROW + 1;
int y = rand() % COL + 1;
if (board[x][y] == '0') {
board[x][y] = '1';
count--;
}
}
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS]) {
int x = 0;
int y = 0;
int win = 0;
while (win<COL*ROW-N) //判贏
{
printf("請輸入要排查的位置>:\n");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= 9 && y >= 1 && y <= 9) {
if (mine[x][y] == '1') {
printf("很遺憾,你踩到了雷,游戲結(jié)束!\n");
DisPlaybroad(mine);
break;
}
else {
show[x][y] = Get_Mine(mine, x, y) + '0';
DisPlaybroad(show);
win++;
}
}
else {
printf("坐標(biāo)非法,請重新輸入!\n");
}
}
if (win == ROW * COL - N) {
printf("恭喜你排雷成功!\n");
DisPlaybroad(mine);
}
}
int Get_Mine(char mine[ROWS][COLS], 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');
}
?游戲主體(.c文件)文章來源:http://www.zghlxwxcb.cn/news/detail-455711.html
#include"game1.h"
void menu()
{
printf("******************************\n");
printf("********* 1.play *********\n");
printf("********* 0.exit *********\n");
printf("******************************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盤
InitBoard(mine,'0');
InitBoard(show,'*');
//埋雷
SetMine(mine);
//打印棋盤
DisPlaybroad(show);
//排雷+判贏
FindMine(mine,show);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("請選擇>:\n");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("退出游戲!\n");
break;
default:
printf("輸入錯誤請重新輸入>:\n");
break;
}
} while (input);
return 0;
}
總結(jié)
? ? ? 以上就是今天要講的內(nèi)容,本文僅僅使用簡單的C語言基礎(chǔ)語法來實現(xiàn)的掃雷小游戲,希望可以對你有所幫助,感謝閱讀!文章來源地址http://www.zghlxwxcb.cn/news/detail-455711.html
到了這里,關(guān)于C語言小游戲——掃雷的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!