目錄
前言
一,游戲構思
二,游戲實現(xiàn)
2.1 游戲框架
2.2 game.h頭文件
2.3 game()的實現(xiàn)
2.4 每個函數(shù)的實現(xiàn)
2.5 周圍雷的數(shù)目(around_num)
三,游戲總代碼
這次我們練習一個掃雷小游戲,這次涉及的知識主要是二維數(shù)組(當然如果對數(shù)組不熟悉的話可以看我之前寫的有關數(shù)組的文章)掃雷游戲相信我們大家都很熟悉吧,多練習這樣的小游戲,小項目都有助于提高我們的代碼能力。話不多說,先來張美圖,直接開始!
? 我們需要兩個棋盤,一個用來存放雷,一個向我們展示雷的數(shù)量。每個棋盤我們可以用二數(shù)維組實現(xiàn),也就是需要兩個二維數(shù)組。這個游戲我們還分為三個文件,test.c里放游戲框架,game.c里放函數(shù)的實現(xiàn)過程,game.h里放頭文件和函數(shù)聲明。游戲效果如下:
游戲框架我們還是采用之前的do while 結構,再加上switch分支語句。菜單我們用printf打印實現(xiàn),代碼如下
//test.c文件里
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h" //把#include放在game.h中
void menu()
{
printf("************************************************\n");
printf("********************** 1.play ******************\n");
printf("********************** 0.exit ******************\n");
printf("************************************************\n");
}
int main()
{
int input = 0;
do
{
menu(); //菜單
printf("請選擇:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //游戲實現(xiàn)放在這這函數(shù)里
break;
case 0:
break;
default:
printf("選擇錯誤,重新選擇\n");
}
} while (input);
return 0;
}
2.2 game.h頭文件我們創(chuàng)建一個頭文件,將所用到的庫函數(shù)和全局變量放在里面,這個掃雷的棋盤的大小我們用9*9,但是創(chuàng)建的時候我們得用11*11。因為我們掃雷游戲時輸入坐標后,如果那個坐標不是雷,它會進行一個周圍坐標的計算,如果輸入的坐標是棋盤最外面的一圈,它會越界訪問。所以我們創(chuàng)建11*11,但打印的時候我們可以打印成9*9(最外圈不打?。?。創(chuàng)建一個全局變量row用來表示行,col用來表示列,用#define將row,col定義為9,ROW,COL定義為11。用mine_num表示雷的數(shù)量,暫且為10個雷。用頭文件創(chuàng)建全局變量還有一個實用的好處,就是想改變行和列和累的數(shù)量時可以直接在game.h頭文件中改。代碼如下:
//game.h
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#define row 9 //row = 9
#define col 9 //col = 9
#define ROW row+2 //ROW = row + 2 = 11
#define COL col+2 //COL = 11
#define mine_num 10 //雷的數(shù)量
2.3 game()的實現(xiàn)? 將游戲的主要實現(xiàn)過程放在game()中,這里面我們首先創(chuàng)建兩個二維數(shù)組,一個用來防雷(mine),一個用來展示(show)。然后我們再初始化(init_board)這兩個數(shù)組,數(shù)組mine我們把它全部初始化為0,在mine中放置雷的時候,我們用字符 '1' 表示雷,這樣到時候利用加法方便計算雷的數(shù)量,數(shù)組show我們全部初始化為 ‘ * ’,到時候輸入坐標的位置用mine計算出的數(shù)字代替 ‘ * ’。接下來我們在mine中放置雷(set_mine),做完這一切后我們就開始排雷,(函數(shù)的具體實現(xiàn)在下面講)最將排雷的實現(xiàn)放在clear_mine中,代碼如下:
//test.c
void game()
{
char show[ROW][COL] = { 0 }; //show 展示的棋盤
char mine[ROW][COL] = { 0 }; //mine 放雷的棋盤
init_board(show, ROW, COL, '*'); //初始化棋盤show
init_board(mine, ROW, COL, '0'); //初始化棋盤mine
set_mine(mine,ROW,COL,mine_num); //放置雷
clear_mine(show,mine,ROW,COL); //排雷
}
2.4 每個函數(shù)的實現(xiàn)我們把每個游戲過程的函數(shù)放在game.c中講,我們先把函數(shù)一一在game.h頭文件中進行聲明,然后在game.c中也包含game.c中,這樣就能將game.c和test.c里建立聯(lián)系。
//game.h
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#define row 9
#define col 9
#define ROW row+2
#define COL col+2
#define mine_num 10
void init_board(char board[ROW][COL], int rows, int cols, char ret); //初始化函數(shù)
void prin_board(char board[ROW][COL], int rows, int cols); //打印函數(shù)
void set_mine(char board[ROW][COL], int rows, int cols, int num); //隨機放置雷的函數(shù)
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols);//掃雷的函數(shù)
我們先實現(xiàn)初始化函數(shù)init_board。用兩個for循環(huán)將數(shù)組一一賦值。代碼如下:
//game.c
void init_board(char board[ROW][COL], int rows, int cols, char ret) //初始化棋盤
{
int i = 0;
for (i = 0; i< rows; i++)
{
int j = 0;
for (j = 0; j< cols; j++)
{
board[i][j] = ret;
}
}
}
?????接著實現(xiàn)打印函數(shù)prin_board。這里先將列數(shù)打印出來,然后用兩個for打印棋盤,在第一個for中先打印行的數(shù)字,然后打印這一行的棋盤。代碼如下:
//game.c
void prin_board(char board[ROW][COL], int rows, int cols) //打印棋盤
{
int i = 0;
printf("----------掃雷———————\n");
for (i = 0; i< cols + 1; i++) //打印列數(shù)0,1,2,3...
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i<= rows; i++) //只把11*11棋盤中間的9*9打印出來,因為要把雷隨機放在這中間9*9中
{
int j = 0;
printf("%d ", i); //打印行數(shù)1,2,3...
for (j = 1; j<= cols; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("----------掃雷———————-\n");
}
效果如下:
接著我們實現(xiàn)放雷的函數(shù)set_mine,這里因為需要隨機放置雷的數(shù)量,所以需要隨機函數(shù)rand(),隨機的起點我們用上時間戳放在test.c中的main中,時間戳所需要的庫函數(shù)
代碼如下:
//game.c
void set_mine(char board[ROW][COL], int rows, int cols, int num) //放雷
{
while (num)
{
int x = rand() % 9 + 1; //隨機坐標1 - 9,最外層不放雷,這樣計算周圍一圈雷不會數(shù)組越界
int y = rand() % 9 + 1; //rand()得到的值余9+1可以得到1—9的數(shù)
if (board[x][y] == '0')
{
board[x][y] = '1'; //在mine棋盤中 雷 用 ‘1’表示,方便計算周圍雷的數(shù)量
num--;
}
}
}
最后是排雷函數(shù)clear_mine,我們用while循環(huán),如果沒踩到雷,需要循環(huán)展現(xiàn)的棋盤數(shù)量減去雷的數(shù)量(9*9 - 10),然后打印棋盤,輸入排雷的坐標,然后用兩個if語句進行坐標篩選,是否合法?是否沒被排過?如果坐標都滿足,進入最后一個if進行判斷坐標是否為雷,如果為雷,游戲結束,跳出循環(huán),如果非雷,將坐標周圍雷的數(shù)量(around_num)替換掉那個坐標的 ‘ * ’(賦值在show[i][j])代碼如下:
//game.h
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols) //掃雷
{
int input = row*col - mine_num; //如果每次都沒踩到雷,需要排9*9-10個坐標。
while (input)
{
int i = 0;
int j = 0;
prin_board(show, row, col); //打印棋盤
printf("請輸入坐標:\n"); //輸入排雷的坐標
scanf("%d %d", &i, &j);
if (i >0 && i<= 9 && j >0 && j<= 9) //坐標的范圍必須在1到9(包含9和1)之間
{
if (show[i][j] == '*')
{
if (mine[i][j] == '0')
{
show[i][j] = around_num(mine, i, j) + '0'; //周圍雷的數(shù)量賦值到所選的坐標中
prin_board(show, row, col);
input--;
}
else
{
prin_board(mine, row, col);
printf("很遺憾,你被炸死了\n");
break;
}
}
else
{
printf("該坐標已排過雷,請重新輸入\n");
}
}
else
{
printf("坐標非法,請重新輸入\n");
int i = 0;
while ((i = getchar()) != '\n') //清楚緩存區(qū)
{
;
}
}
}
}
這里面的
show[i][j] = around_num(mine, i, j) + '0';?? ??? ?//周圍雷的數(shù)量賦值到所選的坐標中?
around_num返回值是 int 型,所以加上字符 ‘ 0 ’,在賦值給char型棋盤show中,它也隨之轉化為char型。
2.5 周圍雷的數(shù)目(around_num)實現(xiàn)過程如下:
//game.c
static int around_num(char board[ROW][COL], int i, int j) //周圍雷的數(shù)目
{
return (board[i - 1][j - 1] + board[i - 1][j] + board[i - 1][j + 1] + board[i][j - 1] + board[i][j + 1] + board[i + 1][j - 1] + board[i + 1][j] + board[i + 1][j + 1] - 8 * '0');
}
該函數(shù)實現(xiàn)過程是將輸入坐標周圍一圈的字符 ‘ 1 ’相加(正如前面所講的mine棋盤初始化為字符 ‘?0 ’,雷用 字符‘ 1 ’表示,這也是用 ‘1’表示雷的好處,方便計算),然后作為函數(shù)的返回值。
這里static作用是將around_num變?yōu)殪o態(tài)函數(shù),靜態(tài)函數(shù)只能在聲明它的文件可見,其他文件不能引用該函數(shù)。意思是該函數(shù)只有在game.c可用,其他文件不可用。
around_num返回值是 int 型,因為數(shù)組board為char型,所以要減去字符‘ 0 ’(由ASCII表可以看出字符任意數(shù)字減去字符0的值為十進制的該任意字符的值),總共有8個char值,最后要減去8個字符‘0’。
三,游戲總代碼//test.c代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("************************************************\n");
printf("********************** 1.play ******************\n");
printf("********************** 0.exit ******************\n");
printf("************************************************\n");
}
void game()
{
char show[ROW][COL] = { 0 }; //show 展示的棋盤
char mine[ROW][COL] = { 0 }; //mine 放雷的棋盤
init_board(show, ROW, COL, '*'); //初始化棋盤
init_board(mine, ROW, COL, '0');
set_mine(mine,ROW,COL,mine_num); //放雷
clear_mine(show,mine,ROW,COL); //掃雷
}
int main()
{
int input = 0;
srand((unsigned)time(NULL)); //隨機值的起點
do
{
menu(); //游戲菜單
printf("請選擇:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
break;
default:
printf("選擇錯誤,重新選擇\n");
}
} while (input);
return 0;
}
//game.h代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
//row 行
//col 列
#include#include#define row 9
#define col 9
#define ROW row+2
#define COL col+2
#define mine_num 10
void init_board(char board[ROW][COL], int rows, int cols, char ret);
void prin_board(char board[ROW][COL], int rows, int cols);
void set_mine(char board[ROW][COL], int rows, int cols, int num);
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols);
//game.c代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
static int around_num(char board[ROW][COL], int i, int j) //周圍雷的數(shù)目
{
return (board[i - 1][j - 1] + board[i - 1][j] + board[i - 1][j + 1] + board[i][j - 1] + board[i][j + 1] + board[i + 1][j - 1] +
board[i + 1][j] + board[i + 1][j + 1] - 8 * '0');
}
void init_board(char board[ROW][COL], int rows, int cols, char ret) //初始化棋盤
{
int i = 0;
for (i = 0; i< rows; i++)
{
int j = 0;
for (j = 0; j< cols; j++)
{
board[i][j] = ret;
}
}
}
void prin_board(char board[ROW][COL], int rows, int cols) //打印棋盤
{
int i = 0;
printf("----------掃雷———————\n");
for (i = 0; i< cols + 1; i++) //打印列數(shù)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i<= rows; i++) //只把11*11棋盤中間的9*9打印出來,因為要把雷隨機放在這中間9*9中
{
int j = 0;
printf("%d ", i); //打印行數(shù)
for (j = 1; j<= cols; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("----------掃雷———————-\n");
}
void set_mine(char board[ROW][COL], int rows, int cols, int num) //放雷
{
while (num)
{
int x = rand() % 9 + 1; //隨機坐標1 - 9,最外層不放雷,這樣計算周圍一圈雷不會數(shù)組越界
int y = rand() % 9 + 1;
if (board[x][y] == '0')
{
board[x][y] = '1'; //在mine棋盤中 雷 用 ‘1’表示,方便計算周圍雷的數(shù)量
num--;
}
}
}
void clear_mine(char show[ROW][COL], char mine[ROW][COL], int rows, int cols) //掃雷
{
int input = row*col - mine_num;
while (input)
{
int i = 0;
int j = 0;
prin_board(show, row, col); //打印棋盤
printf("請輸入坐標:\n");
scanf("%d %d", &i, &j);
if (i >0 && i<= 9 && j >0 && j<= 9)
{
if (show[i][j] == '*')
{
if (mine[i][j] == '0')
{
show[i][j] = around_num(mine, i, j) + '0'; //周圍雷的數(shù)量賦值到所選的坐標中
prin_board(show, row, col);
input--;
}
else
{
prin_board(mine, row, col);
printf("很遺憾,你被炸死了\n");
break;
}
}
else
{
printf("該坐標已排過雷,請重新輸入\n");
}
}
else
{
printf("坐標非法,請重新輸入\n");
int i = 0;
while ((i = getchar()) != '\n') //清楚緩存區(qū)
{
;
}
}
}
}
如果不方便的話,源碼還可以在gitee中獲取:csdn-game3 · 雨天code/1 - 碼云 - 開源中國 (gitee.com)
好了,到這里就結束了,如果對你有幫助,不如留個足跡再走。
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
標題名稱:C語言掃雷小游戲(超詳解)-創(chuàng)新互聯(lián)
本文路徑:http://sd-ha.com/article42/deigec.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供網站排名、小程序開發(fā)、微信小程序、網站設計、網站內鏈、App設計
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)