C語(yǔ)言實(shí)現(xiàn)掃雷游戲詳細(xì)代碼實(shí)例
掃雷游戲
思路:先制作一個(gè)菜單讓玩家選擇是玩游戲還是退出游戲,菜單做好了,接著我們開(kāi)始制作掃雷的棋盤(pán)并初始化,初始化弄完了我們下一步開(kāi)始埋雷,雷埋好了就開(kāi)始掃雷。
大概思路就是這樣具體實(shí)現(xiàn)看下面:
菜單的實(shí)現(xiàn)代碼:
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
printf("**************************\n");
printf("*** 1. play 0. exit ***\n");
printf("*** 2. clear ***\n");
printf("**************************\n");
printf("請(qǐng)選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戲?qū)崿F(xiàn)
break;
case 2://清屏選項(xiàng)
system("cls");
break;
case 0:
printf("退出程序!\n");
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新輸入!\n");
Sleep(1000);
system("cls");
break;
}
} while (input);
return 0;
}
這里我們用了Windows庫(kù)函數(shù)清屏,如果屏幕上顯示的東西太多了,我們可以選擇2來(lái)清屏,還有一個(gè)睡眠函數(shù),如果輸出錯(cuò)誤會(huì)短暫的提示你一秒,告訴你選擇錯(cuò)誤了。
效果展示圖:

制作好菜單那我們開(kāi)始實(shí)現(xiàn)整個(gè)游戲的邏輯框架了,定義兩個(gè)二維數(shù)組,一個(gè)用于顯示,一個(gè)用于存放地雷。如果這兩個(gè)東西都只用一個(gè)二維數(shù)組的話后面的實(shí)現(xiàn)邏輯會(huì)比較麻煩所以我選擇使用兩個(gè)二維數(shù)組。
char mine[ROWS][COLS] = { 0 };//用于埋雷
char show[ROWS][COLS] = { 0 };//用于游戲的畫(huà)面顯示
有這兩個(gè)二維數(shù)組我們開(kāi)始初始化
//初始化
void initzeboard(char mine[ROWS][COLS], int rows, int cols, char val)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
mine[i][j] = val;
}
}
}
我遍歷整個(gè)二維數(shù)組來(lái)初始化,val這個(gè)參數(shù)是用于接收這兩個(gè)二維數(shù)組的初始化的內(nèi)容,如果不用這個(gè)val參數(shù)我就要再寫(xiě)一個(gè)函數(shù)封裝很麻煩。
接下來(lái),實(shí)現(xiàn)個(gè)打印棋盤(pán)函數(shù)來(lái)看看我們的初始化是否正確的初始化成我想要的內(nèi)容
打印棋盤(pán)代碼:
//顯示棋盤(pán)
void Display_board(char mine[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf(" 掃雷游戲\n");
printf("---------------------------------\n");
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", mine[i][j]);
}
printf("\n");
}
}
接下來(lái)看看我們初始化的是否正確:

可以看到它正確的初始化了,全0代表埋雷的二維數(shù)組,而*代表的是用戶看到的,正常來(lái)說(shuō),這個(gè)埋雷是不需要顯示出來(lái)的,但是我們需要確認(rèn)是否正確初始化所以打印出來(lái)看看,下一步我們開(kāi)始埋雷。
//埋雷
void random_mine(char mine[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = EASILY;
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (mine[x][y] == '0')//用于判斷是否正確的埋雷,只有我們這沒(méi)被埋過(guò)的雷我們才自減
{
mine[x][y] = '1';
count--;
}
}
}
埋好雷的效果:

1代表是雷,0代表步是雷,埋好的雷會(huì)被賦值成字符1
埋雷我采用隨機(jī)函數(shù)來(lái)幫我埋下雷,弄好這步接來(lái)的就是掃雷這很關(guān)鍵。
掃雷代碼:
//掃雷
void mine_sweeping(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (count < row * col - EASILY)
{
system("cls");
Display_board(show, COL, ROW);
printf("請(qǐng)輸入坐標(biāo):>");
scanf("%d %d", &x, &y);
if ((1 <= x && x <= row) && (1 <= y && y <= col))
{
if (mine[x][y] == '0')
{
int leng = statistics_mine(mine, x, y);
show[x][y] = leng + '0';
count++;
}
else
{
printf("很遺憾你被炸死了\n");
Display_board(mine, ROW, COL);
break;
}
}
else
{
printf("請(qǐng)輸入有效數(shù)字!\n");
}
}
if (count == row * col - EASILY)
{
printf("恭喜你掃雷成功!\n");
Display_board(mine, ROW, COL);
}
}
如果玩家輸入的坐標(biāo)是合法的我們就統(tǒng)計(jì)它周?chē)卸嗌倮?,統(tǒng)計(jì)雷的功能我做成了一個(gè)內(nèi)部函數(shù)防止重名。
如果全部沒(méi)有雷的地方都排查完了,我們就停止循環(huán)。然后打印下雷的棋盤(pán)讓玩家知道哪有雷,如果被炸死了,我們也打印下雷的二維數(shù)組讓玩家死得瞑目。


統(tǒng)計(jì)雷的函數(shù):
//統(tǒng)計(jì)周?chē)椎膫€(gè)數(shù)
static int statistics_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';
}
根據(jù)ASCII碼字符1減去字符0就是整形1,所以根據(jù)此方法我們就只用把周?chē)睦兹考悠饋?lái)減去字符零就可以得到周?chē)椎膫€(gè)數(shù)并返回 。
統(tǒng)計(jì)雷效果圖:

周?chē)鷽](méi)有雷就是0,如果有就顯示個(gè)數(shù)。
通關(guān)也會(huì)打印所有雷的位置并提示你是否通關(guān)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-m4tO2ZuP-1613214039851)(C:\Users\86176\AppData\Roaming\Typora\typora-user-images\image-20210213185535958.png)]
頭文件:
#pragma once #include <stdio.h> #include <Windows.h> #include <time.h> #include <stdlib.h> #define ROW 9 #define COL 9 #define ROWS ROW + 2 #define COLS COL + 2 #define EASILY 0//雷的數(shù)量 //初始化 void initzeboard(char mine[ROWS][COLS], int rows, int cols, char val); //顯示棋盤(pán) void Display_board(char mine[ROWS][COLS], int row, int col); //埋雷 void random_mine(char mine[ROWS][COLS], int row, int col); //掃雷 void mine_sweeping(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
游戲?qū)崿F(xiàn)代碼:
#define _CRT_SECURE_NO_WARNINGS 1
#include "Game.h"
int count = 0;//統(tǒng)計(jì)還剩多少格子沒(méi)被掃
void game()//游戲?qū)崿F(xiàn)
{
char mine[ROWS][COLS] = { 0 };//用于埋雷
char show[ROWS][COLS] = { 0 };//用于游戲的畫(huà)面顯示
//初始化
initzeboard(show, ROWS, COLS, '*');
initzeboard(mine, ROWS, COLS, '0');
//顯示棋盤(pán)
Display_board(show, ROW, COL);
//Display_board(mine, ROW, COL);
//埋雷
random_mine(mine, ROW, COL);
//Display_board(mine, ROW, COL);
//掃雷
mine_sweeping(mine, show, ROW, COL);
}
//初始化
void initzeboard(char mine[ROWS][COLS], int rows, int cols, char val)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
mine[i][j] = val;
}
}
}
//顯示棋盤(pán)
void Display_board(char mine[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf(" 掃雷游戲\n");
printf("---------------------------------\n");
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", mine[i][j]);
}
printf("\n");
}
}
//埋雷
void random_mine(char mine[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int count = EASILY;
while (count)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}
//統(tǒng)計(jì)周?chē)椎膫€(gè)數(shù)
static int statistics_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';
}
//掃雷
void mine_sweeping(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (count < row * col - EASILY)
{
system("cls");
Display_board(show, COL, ROW);
printf("請(qǐng)輸入坐標(biāo):>");
scanf("%d %d", &x, &y);
if ((1 <= x && x <= row) && (1 <= y && y <= col))
{
if (mine[x][y] == '0')
{
int leng = statistics_mine(mine, x, y);
show[x][y] = leng + '0';
count++;
}
else
{
printf("很遺憾你被炸死了\n");
Display_board(mine, ROW, COL);
break;
}
}
else
{
printf("請(qǐng)輸入有效數(shù)字!\n");
}
}
if (count == row * col - EASILY)
{
printf("恭喜你掃雷成功!\n");
Display_board(mine, ROW, COL);
}
}
主函數(shù)代碼:
#define _CRT_SECURE_NO_WARNINGS 1
#include "Game.h"
extern void game();
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
printf("**************************\n");
printf("*** 1. play 0. exit ***\n");
printf("*** 2. clear ***\n");
printf("**************************\n");
printf("請(qǐng)選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戲?qū)崿F(xiàn)
break;
case 2://清屏選項(xiàng)
system("cls");
break;
case 0:
printf("退出程序!\n");
break;
default:
printf("輸入錯(cuò)誤,請(qǐng)重新輸入!\n");
Sleep(1000);
system("cls");
break;
}
} while (input);
return 0;
}
到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)掃雷游戲詳細(xì)代碼實(shí)例的文章就介紹到這了,更多相關(guān)C語(yǔ)言實(shí)現(xiàn)掃雷游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++優(yōu)先級(jí)隊(duì)列的使用指南與模擬實(shí)現(xiàn)
優(yōu)先級(jí)隊(duì)列是一種特殊的隊(duì)列,其中每個(gè)元素都有一個(gè)與之關(guān)聯(lián)的優(yōu)先級(jí),優(yōu)先級(jí)較高的元素會(huì)在隊(duì)列中較早地被處理,而優(yōu)先級(jí)較低的元素會(huì)在后續(xù)處理,本文給大家介紹C++優(yōu)先級(jí)隊(duì)列的使用指南與模擬實(shí)現(xiàn),需要的朋友可以參考下2023-09-09
C++ 中dynamic_cast<>的使用方法小結(jié)
將一個(gè)基類對(duì)象指針(或引用)cast到繼承類指針,dynamic_cast會(huì)根據(jù)基類指針是否真正指向繼承類指針來(lái)做相應(yīng)處理2013-03-03
C++ STL關(guān)聯(lián)式容器自定義排序規(guī)則的2種方法
這篇文章主要介紹了C++ STL關(guān)聯(lián)式容器自定義排序規(guī)則的2種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03

