C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
掃雷
楔子:
掃雷游戲是我們小時(shí)候無(wú)聊時(shí)消磨時(shí)間的小玩意,雖然更新到Win10系統(tǒng)后經(jīng)典的掃雷游戲不再了,不過(guò)它現(xiàn)在仍以一種抓蟲(chóng)子的游戲形式存在于Windows這個(gè)系統(tǒng)平臺(tái),不禁感慨游戲還是那個(gè)游戲,不過(guò)人已經(jīng)不是那些人了啊.
其實(shí)掃雷游戲的實(shí)現(xiàn)也主要運(yùn)用了數(shù)組和函數(shù)封裝與調(diào)用的知識(shí),具體請(qǐng)看程序.
以下為程序主體:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
//定義方格大小
#define MAX_ROW 10
#define MAX_COL 10
//定義方格雷陣中的地雷數(shù)
#define DEFAULT_MINE_COUNT 10
//制作圖形化游戲界面函數(shù)(菜單)
int Menu() {
printf("=============================\n");
printf("|| <掃雷游戲> ||\n");
printf("|| 1.開(kāi)始游戲 0.退出游戲 ||\n");
printf("=============================\n");
int choice = 0;
while (1) {
scanf("%d", &choice);
if (choice != 0 && choice != 1) {
printf("您的輸入有誤,請(qǐng)重新輸入!\n");
continue;
}
return choice;
}
}
//清空方格函數(shù) 這里地雷表示為 * ,安全無(wú)地雷表示為 0
void Init(char show_map[MAX_ROW + 2][MAX_COL + 2],
char mine_map[MAX_ROW + 2][MAX_COL + 2]) {
for (int row = 0; row < MAX_ROW + 2; ++row) {
for (int col = 0; col < MAX_COL + 2; ++col) {
show_map[row][col] = '*';
}
}
for (int row = 0; row < MAX_ROW + 2; ++row) {
for (int col = 0; col < MAX_COL + 2; ++col) {
mine_map[row][col] = '0';
}
}
//能夠隨機(jī)的構(gòu)造出 N 個(gè)數(shù),放在雷陣中
int mine_count = DEFAULT_MINE_COUNT;
while (mine_count > 0) {
//隨機(jī)布置地雷
int row = rand() % MAX_ROW + 1;
int col = rand() % MAX_COL + 1;
if (mine_map[row][col] == '1') {
continue;
}
mine_map[row][col] = '1';
--mine_count;
}
}
void DisplayMap(char map[MAX_ROW + 2][MAX_COL + 2]) {
printf(" ");
//打印坐標(biāo)橫行
for (int row = 1; row <= MAX_ROW; ++row) {
printf("%d ", row);
}
printf("\n");
//打印上邊框
for (int row = 1; row <= MAX_ROW; ++row) {
printf("---");
}
printf("\n");
for (int row = 1; row <= MAX_ROW; ++row) {
printf("%02d|", row);
for (int col = 1; col <= MAX_COL; ++col) {
printf("%c ", map[row][col]);
}
printf("\n");
}
printf("\n");
printf("\n");
printf("\n");
}
void UpdateShowMap(char show_map[MAX_ROW + 2][MAX_COL + 2],
char mine_map[MAX_ROW + 2][MAX_COL + 2], int row, int col) {
//這個(gè)函數(shù)要根據(jù)mine_map來(lái)計(jì)算row,col位置上周?chē)怯袔讉€(gè)地雷
//把結(jié)果寫(xiě)到對(duì)應(yīng)的show_map位置上
//===========此處這8個(gè)位置對(duì)應(yīng)的下標(biāo)不會(huì)越界======
//===========因?yàn)橐肓艘蝗吙?==================
//row和col取值是[1,MAX_ROW]
//數(shù)組下標(biāo)取值為[0,MAX_ROW + 1]
int mine_count = 0;
for (int i = row - 1; i <= row + 1; ++i) {
for (int j = col - 1; j <= col + 1; ++j) {
mine_count =
mine_map[i - 1][j - 1] - '0' +
mine_map[i - 1][j] - '0' +
mine_map[i - 1][j + 1] - '0' +
mine_map[i][j - 1] - '0' +
mine_map[i][j + 1] - '0' +
mine_map[i + 1][j - 1] - '0' +
mine_map[i + 1][j] - '0' +
mine_map[i + 1][j + 1] - '0';
if (mine_map[i][j] == '1') {
show_map[i][j] = '*';
}
else {
show_map[i][j] = '0' + mine_count;
}
}
}
}
//游戲主邏輯,入口
void Game() {
//具體的一局掃雷游戲
//兩個(gè)二維數(shù)組來(lái)表示地圖
//第一個(gè)數(shù)組表示給玩家展示的地圖
char show_map[MAX_ROW + 2][MAX_COL + 2];
//此處加上一圈邊框(防止數(shù)組下標(biāo)越界)
//對(duì)于show_map:里面元素有2種情況:
//1.這個(gè)位置沒(méi)有被掀開(kāi),用 * 表示
//2.這個(gè)位置已經(jīng)被掀開(kāi)了,用一個(gè)具體的數(shù)字來(lái)表示(例如字符'2'來(lái)表示)
char mine_map[MAX_ROW + 2][MAX_COL + 2];
//第二個(gè)數(shù)組表示雷陣
//對(duì)于mine_map,里面的元素以下情況:
//1.這個(gè)位置是地雷,使用字符'1'表示
//2.這個(gè)位置不是地雷,使用字符'0'表示
int blank_count = 0;//空格數(shù) 不包含地雷,被掀開(kāi)的格子數(shù)
//1.對(duì)這兩個(gè)數(shù)組進(jìn)行初始化
//2.打印初始地圖
Init(show_map, mine_map);
DisplayMap(show_map);
while (1) {
//3.讓玩家輸入坐標(biāo),判定是否合法
int row, col;
printf("請(qǐng)輸入坐標(biāo):\n");
scanf("%d %d", &row, &col);
if (row <= 0 || row > MAX_ROW
|| col <= 0 || col > MAX_COL) {
printf("您的輸入不合法,重新輸入!\n");
continue;
}
//4.判斷玩家是否踩雷,如果是,游戲結(jié)束
if (mine_map[row][col] == '1') {
printf("游戲結(jié)束!\n");
printf("掃雷失敗!\n");
DisplayMap(mine_map);
break;
}
//5,如果沒(méi)踩雷,判定是否掀開(kāi)了全部格子(玩家勝利)
//6.就統(tǒng)計(jì)該位置周?chē)袔讉€(gè)雷,并把這個(gè)數(shù)字更新到地圖上
UpdateShowMap(show_map, mine_map, row, col);
DisplayMap(show_map);
int blank_cnt = 0;
for (row = 1; row <= MAX_ROW; ++row)
{
for (col = 1; col <= MAX_COL; ++col)
{
if (show_map[row][col] != '*')
{
++blank_cnt;
if (blank_cnt == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT)
{
DisplayMap(mine_map);
printf("掃雷成功,游戲結(jié)束\n");
break;
}
}
}
}
printf("\n");
}
}
void Start() {
//這是游戲入口函數(shù),游戲菜單
while (1) {
int choice = Menu();
if (choice == 0) {
break;
}
Game();
}
}
//主函數(shù)
int main() {
Start();//由開(kāi)始函數(shù)引導(dǎo)游戲開(kāi)始
system("pause");
return 0;
}
需要注意的是:
1.大佬可以通過(guò)更改程序首部的宏定義來(lái)改變方格大小,擴(kuò)充界面大小以提高難度.
2.整個(gè)游戲邏輯必須明晰:
打印方格
隨機(jī)布置雷陣
玩家輸入掀開(kāi)方格坐標(biāo)
判斷是否踩雷(若是,游戲結(jié)束.否則顯示出周?chē)藗€(gè)數(shù)的地雷數(shù))
若未踩雷判斷是否除了地雷外掀開(kāi)了所有方格(若是,掃雷成功.否則繼續(xù)游戲)
更新表示地圖
循環(huán)步驟,返回至用戶(hù)輸入環(huán)節(jié),繼續(xù)游戲,直至游戲截止.
總結(jié):
程序內(nèi)部需要有許多的注意點(diǎn),比如引入一圈邊框,他的作用就是為了確保更新地圖時(shí)數(shù)組下標(biāo)不會(huì)越界,是一種保護(hù)機(jī)制,但是這種機(jī)制的構(gòu)建可能會(huì)在程序其他地方的完善工作帶來(lái)不小的工程量,但是有這么一道設(shè)定,總比程序直接報(bào)錯(cuò)或者運(yùn)行一段時(shí)間由玩家反饋這個(gè)bug來(lái)的劃算/值得一些,所以盡可能在開(kāi)發(fā)環(huán)節(jié)做到極致,以免折騰后面修改代碼缺陷的自己.
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷小游戲
- C語(yǔ)言實(shí)現(xiàn)掃雷小游戲(適合初學(xué)者)
- C語(yǔ)言?huà)呃子螒虻膶?shí)現(xiàn)代碼
- C語(yǔ)言代碼實(shí)現(xiàn)掃雷游戲
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲
- C語(yǔ)言代碼實(shí)現(xiàn)掃雷小游戲
- C語(yǔ)言實(shí)現(xiàn)掃雷游戲
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小程序
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷小游戲
- C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)掃雷小游戲
相關(guān)文章
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問(wèn)題
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
Trae+Qt+MSVC環(huán)境配置的實(shí)現(xiàn)示例
本文主要介紹了Trae+Qt+MSVC環(huán)境配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
Qt自定義控件實(shí)現(xiàn)簡(jiǎn)易儀表盤(pán)
這篇文章主要為大家詳細(xì)介紹了Qt自定義控件實(shí)現(xiàn)簡(jiǎn)易儀表盤(pán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12
C++語(yǔ)言中std::array的用法小結(jié)(神器用法)
這篇文章主要介紹了C++語(yǔ)言中std::array的用法小結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11

