一.前言
人盡皆知的掃雷小游戲,原理簡單,寫法也簡單,我會通過C語言分各個部分將這個小游戲進(jìn)行剖析,一看就會!
二.資源環(huán)境的配置
我們需要新建一個頭文件game.h,兩個源文件game.c和text.c,一共三個文件
他們的關(guān)系是這樣的:
test.c是主體,是游戲的測試邏輯
game.c是游戲的實(shí)現(xiàn)邏輯
game.h是實(shí)現(xiàn)游戲函數(shù)的聲明
也就是說,main函數(shù)在test.c內(nèi),游戲所需要實(shí)現(xiàn)的各項(xiàng)功能寫在game.c內(nèi),我們需要在text.c內(nèi)使用,必須要引用他們,game.h則是各個函數(shù)的聲明。將一整個游戲分為這三個部分來寫,不僅可以很好的區(qū)分內(nèi)容,而且不會讓我們的代碼看起來雜亂無序,便于后期的修改。
三.游戲整體構(gòu)思
最基本的掃雷游戲需要以下幾個功能
1.游戲打開首先需要有菜單,它要有讓我們實(shí)現(xiàn)自由進(jìn)入游戲和退出游戲的功能
2.需要兩個二維數(shù)組存放布置雷和排查雷的信息
3.初始化棋盤
4.布置雷
5.打印棋盤
6.排查雷
1.游戲的開始與結(jié)束(菜單)
為了有利于分析,我會把各個部分的功能分解,主體在text.c內(nèi)實(shí)現(xiàn)
別忘了我們函數(shù)的聲明全部在game.h內(nèi),使用時必須包含頭文件(include “game.h”)
text.c
菜單
{ void menu()
printf("***************************\n");
printf("********* 1.play **********\n");
printf("********* 0.exit **********\n");
printf("***************************\n");
}
游戲的開始與退出
int main()
{
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);
return 0;
}
2.創(chuàng)建二維數(shù)組用來布置雷和排查雷的信息
本來我們存放棋盤數(shù)據(jù)只需要兩個9 * 9的二維數(shù)組
但是我們掃雷,需要排查一個坐標(biāo)周圍八個坐標(biāo)是否有雷,如果那個坐標(biāo)在邊界,我們定義的數(shù)組只是9 * 9的,那么這個時候數(shù)組則會越界,所以我們要將數(shù)組創(chuàng)建為11*11的,這樣數(shù)組就不會越界了
棋盤內(nèi)數(shù)據(jù)為字符,數(shù)組定義為char類型即可
為了便于區(qū)分,先在game.h內(nèi)定義ROW(行)和COL(列)為9,ROWS和COLS就是ROW和COL分別加2.
在 text.c的game()內(nèi)創(chuàng)建
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
3.初始化棋盤
未開始掃雷時,我們要讓棋盤上顯示*,因?yàn)檫€沒安放雷,所以我們排查的坐標(biāo)點(diǎn)開為‘0’
text.c內(nèi)
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
game.h內(nèi)
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
game.c內(nèi)
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;
}
}
}
4.打印棋盤
雖然我們的棋盤大小是11*11的,但是我們需要的只是9 * 9,所以只接收9 * 9的就可以了,下面的布置雷和排查雷也同理
text.c
DisplayBoard(show, ROW, COL);
game.h
void DisplayBoard(char board[ROWS][COLS], int row, int col);
game.c
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("******* 掃雷 *******\n");
for (j = 0; j <= row; j++)
{
printf("%d ",j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ",i);
for (j = 1; j <= col; j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
5.布置雷
在布置雷的代碼中,我們會用上隨機(jī)數(shù)rand()函數(shù)和時間戳,所以我們要在game.h中包含它們頭文件#include<stdlib.h>和#include<time.h>。同時在主函數(shù)內(nèi)要補(bǔ)上這行代碼
srand((unsigned int)time(NULL));
text.c
SetMine(mine, ROW, COL);
game.h
void SetMine(char mine[ROWS][COLS], int row, int col);
game.c
void SetMine(char mine[ROWS][COLS], int row, int col)
{
int count = Easy_Count;
while(count)
{ int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
6.排查雷
在排查雷的過程中,如果我們剛好排到了雷,那么我們就被炸死,不用排查周圍的雷.
但是如果沒有排到雷,就要排查非雷坐標(biāo)周圍的雷,所以我們還需要一個函數(shù)來排查非雷坐標(biāo)周圍的雷。
game.h
排查非雷坐標(biāo)周圍的雷
int GetMineCount(char mine[ROWS][COLS], int row, int col);
game.c
原理:因?yàn)槲覀兎抢罪@示的是0,有雷則顯示1,所以我們把非雷坐標(biāo)周圍八個坐標(biāo)加起來,然后減去8*‘0’就知道周圍有幾個雷了,別忘記了‘0’加上1就是‘1’哦!
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return (mine[x - 1][y + 1] + mine[x][y + 1]
+ mine[x + 1][y + 1] + mine[x - 1][y]
+ mine[x + 1][y]+ mine[x - 1][y - 1]
+ mine[x][y - 1] + mine[x + 1][y - 1] - 8 * '0');
}
text.c
FindMine(mine, show, ROW, COL);
game.h
void FindMine(char ming[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
游戲?yàn)楹唵坞y度,在game.h內(nèi)定義Easy_Count為10,代表9*9=81個地方共有十個雷
創(chuàng)建一個整形變量win,如果排查到非雷,則win++,當(dāng)win<ROW * COL-Easy_Count則掃雷成功
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
while (win < ROW * COL - Easy_Count)
{
printf("請輸入要排查的坐標(biāo):>");
scanf("%d %d",&x,&y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遺憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//該坐標(biāo)不是雷,則排查其周圍有沒有雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐標(biāo)非法,請重新輸入\n");
}
}
}
四.所有代碼及效果展示
text.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()
{ //mine 數(shù)組用來存放布置雷的信息
char mine[ROWS][COLS] = { 0 };
//show 數(shù)組用來存放排查雷的信息
char show[ROWS][COLS] = { 0 };
//初始化棋盤
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盤
DisplayBoard(show, ROW, COL);
//布置雷
SetMine(mine, ROW, COL);
/*DisplayBoard(mine, ROW, COL);*/
//排查雷
FindMine(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
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);
return 0;
}
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Easy_Count 10
//初始化棋盤
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 ming[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//排查非雷坐標(biāo)周圍的雷
int GetMineCount(char mine[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
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)
{
int i = 0;
int j = 0;
printf("******* 掃雷 *******\n");
for (j = 0; j <= row; j++)
{
printf("%d ",j);
}
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)
{
int count = Easy_Count;
while(count)
{ int x = rand() % row + 1;
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
return (mine[x - 1][y + 1] + mine[x][y + 1]
+ mine[x + 1][y + 1] + mine[x - 1][y]
+ mine[x + 1][y]+ mine[x - 1][y - 1]
+ 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)
{
int x = 0;
int y = 0;
int win = 0;
while (win < ROW * COL - Easy_Count)
{
printf("請輸入要排查的坐標(biāo):>");
scanf("%d %d",&x,&y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("很遺憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
//該坐標(biāo)不是雷,則排查其周圍有沒有雷
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐標(biāo)非法,請重新輸入\n");
}
}
}
文章來源:http://www.zghlxwxcb.cn/news/detail-451519.html
本文到此結(jié)束,關(guān)注我,帶你解鎖進(jìn)階掃雷,下次更精彩!文章來源地址http://www.zghlxwxcb.cn/news/detail-451519.html
到了這里,關(guān)于C初階必寫的C語言小游戲—掃雷,一看就會,看完就能寫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!