C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷的完整過(guò)程
一、問(wèn)題描述
用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷。
二、基本流程
1.菜單界面。
2.創(chuàng)建地圖 (兩個(gè)地圖)。
3.初始化地圖。
4.打印地圖。
5.程序讀取玩家輸入的要翻開(kāi)位置的坐標(biāo),并校驗(yàn)。
6.如果不是地雷,統(tǒng)計(jì)當(dāng)前位置周?chē)椎膫€(gè)數(shù), 并顯示到地圖上.。
7.判定游戲是否勝利。
三、步驟
1.菜單界面
1.開(kāi)始游戲 0.退出游戲
int menu(){
printf("----------------------\n");
printf("------1.開(kāi)始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請(qǐng)輸入你的選擇:");
scanf("%d", &choice);
return choice;
}
2.創(chuàng)建地圖
我們需要兩張地圖,所以要?jiǎng)?chuàng)建兩個(gè)二維數(shù)組。
第一個(gè)二維數(shù)組,表示玩家看到的地圖。(show)
第二個(gè)二維數(shù)組,表示當(dāng)前位置是不是地雷(1表示是地雷,0表示不是地雷)。(mine)
使用宏定義的原因:
1.推高代碼可讀性,后續(xù)代碼中遇到9,方便理解含義。
2.提高擴(kuò)展性,如果將來(lái)要修改棋盤(pán)尺寸,代碼修改會(huì)很方便。
#define MAX_ROW 9
#define MAX_COL 9
char show[MAX_ROW][MAX_COL] = { 0 };
char mine[MAX_ROW][MAX_COL] = { 0 };
3.初始化地圖
使用 * 表示未翻開(kāi)的地。
show地圖一開(kāi)始全都是 * 。
mine地圖是由0,1組成的。(1表示是地雷,0表示不是地雷)一開(kāi)始都為0,隨后由電腦隨機(jī)在地圖上生成1。
這里我們使用宏定義了DIFFICULTY,表示地雷的數(shù)量:10個(gè)。
#define DIFFICULTY 10
void init(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
show[row][col] = '*';
//初始化 mine,先全設(shè)為'0', 然后隨機(jī)生成n個(gè)'1'
mine[row][col] = '0';
}
}
int n = DIFFICULTY;
while (n>0){
// 生成雷的隨機(jī)位置
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (mine[row][col] == '1'){
// 如果當(dāng)前位置已經(jīng)有雷了,就直接進(jìn)入下次循環(huán), 重新產(chǎn)生隨機(jī)位置
continue;
}
mine[row][col] = '1';
n--;
}
}
4.打印地圖
打印出地圖。
void printMap(char themap[MAX_ROW][MAX_COL]){
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", themap[row][col]);
}
printf("\n");
}
}
5.玩家翻開(kāi)坐標(biāo)
玩家通過(guò)輸入坐標(biāo)的方式翻開(kāi)土地。
注意:
1.輸入坐標(biāo)要在地圖范圍內(nèi)。
2.不能重復(fù)翻開(kāi)土地。
//程序讀取玩家輸入的要翻開(kāi)位置的坐標(biāo), 并校驗(yàn)
int row = 0;
int col = 0;
printf("請(qǐng)輸入翻開(kāi)的坐標(biāo)(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標(biāo)超過(guò)范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經(jīng)翻開(kāi),請(qǐng)重新輸入:\n");
continue;
}
6.判斷是否為地雷
如果翻開(kāi)的位置在mine上顯示為1,那么翻到地雷了,輸出被炸死,打印地雷地圖,讓玩家死得明白。
如果翻開(kāi)的位置上在mine上不是1,那么繼續(xù)下一步驟。
if (mine[row][col] == '1'){
printf("你已經(jīng)被炸死了?。?!\n");
printMap(mine);
break;
}
7.更新地圖
計(jì)算周?chē)牡乩讛?shù)量,在翻開(kāi)位置顯示。
updateShow(show,mine,row,col);
// 根據(jù)當(dāng)前 row, col 的位置, 計(jì)算出當(dāng)前位置周?chē)袔讉€(gè)雷
// 并且更新顯示到 show 中
void updateShow(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL], int row, int col){
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mine[r][c] == '1') {
count++;
}
}
}
//此時(shí) count 里面就已經(jīng)存好了 row, col 周?chē)?八個(gè)格子 的雷的個(gè)數(shù)
// 把這個(gè)結(jié)果寫(xiě)到 show 中即可.
// 需要把數(shù)字 count 轉(zhuǎn)成對(duì)應(yīng)的字符
show[row][col] = count + '0';
}
8.判斷是否勝利
定義一個(gè)變量safe,表示翻開(kāi)的不是地雷的土地,每次更新地圖后,safe加一。如果最后翻開(kāi)的不是地雷的土地等于地圖的大小減地雷數(shù),那么排除所有地雷,確認(rèn)安全。
//記錄翻開(kāi)的格子的個(gè)數(shù)
int safe = 0;
updateShow(show,mine,row,col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經(jīng)排除所有的雷,你已經(jīng)安全!??!\n");
printMap(mine);
break;
}
四、代碼實(shí)現(xiàn)
#define _CRT_SECURE_NO_WARNINGS
#define MAX_ROW 9
#define MAX_COL 9
#define DIFFICULTY 10
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int menu(){
printf("----------------------\n");
printf("------1.開(kāi)始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請(qǐng)輸入你的選擇:");
scanf("%d", &choice);
return choice;
}
void init(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
show[row][col] = '*';
mine[row][col] = '0';
}
}
int n = DIFFICULTY;
while (n>0){
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (mine[row][col] == '1'){
continue;
}
mine[row][col] = '1';
n--;
}
}
void printMap(char themap[MAX_ROW][MAX_COL]){
printf(" |");
for (int col = 0; col < MAX_COL; col++) {
printf("%d ", col);
}
printf("\n");
printf("--+------------------\n");
for (int row = 0; row < MAX_ROW; row++) {
printf(" %d|", row);
for (int col = 0; col < MAX_COL; col++) {
printf("%c ", themap[row][col]);
}
printf("\n");
}
}
void updateShow(char show[MAX_ROW][MAX_COL], char mine[MAX_ROW][MAX_COL], int row, int col){
int count = 0;
for (int r = row - 1; r <= row + 1; r++) {
for (int c = col - 1; c <= col + 1; c++) {
if (r < 0 || r >= MAX_ROW
|| c < 0 || c >= MAX_COL) {
continue;
}
if (mine[r][c] == '1') {
count++;
}
}
}
show[row][col] = count + '0';
}
void game(){
char show[MAX_ROW][MAX_COL] = { 0 };
char mine[MAX_ROW][MAX_COL] = { 0 };
init(show, mine);
int safe = 0;
while (1){
printMap(show);
int row = 0;
int col = 0;
printf("請(qǐng)輸入翻開(kāi)的坐標(biāo)(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標(biāo)超過(guò)范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經(jīng)翻開(kāi),請(qǐng)重新輸入:\n");
continue;
}
if (mine[row][col] == '1'){
printf("你已經(jīng)被炸死了?。?!\n");
// 打印一遍地雷的地圖, 讓玩家死的明白
printMap(mine);
break;
}
updateShow(show, mine, row, col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經(jīng)排除所有的雷,你已經(jīng)安全!??!\n");
// 打印一遍地雷的地圖, 讓玩家知道雷在哪
printMap(mine);
break;
}
}
}
int main()
{
srand((unsigned int)time(0));
while (1){
int choice = menu();
if (choice == 1){
game();
}
else if (choice == 0){
printf("退出游戲,byebye!");
break;
}
else{
printf("輸入錯(cuò)誤,請(qǐng)重新輸入:");
continue;
}
}
}
總結(jié)
到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易版掃雷的文章就介紹到這了,更多相關(guān)C語(yǔ)言簡(jiǎn)易版掃雷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在QT5中實(shí)現(xiàn)求兩個(gè)輸入值的和并輸出(實(shí)例)
下面小編就為大家?guī)?lái)一篇在QT5中實(shí)現(xiàn)求兩個(gè)輸入值的和并輸出(實(shí)例)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
C語(yǔ)言自定義類(lèi)型超詳細(xì)梳理之結(jié)構(gòu)體 枚舉 聯(lián)合體
今天我們來(lái)學(xué)習(xí)一下自定義類(lèi)型,自定義類(lèi)型包括結(jié)構(gòu)體、枚舉、聯(lián)合體,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考2022-03-03
C++ clock()解析如何使用時(shí)鐘計(jì)時(shí)的應(yīng)用
本篇文章是對(duì)c++中的clock()函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
C++?OpenCV實(shí)現(xiàn)boxfilter方框?yàn)V波的方法詳解
box?filter的作用很簡(jiǎn)單,即對(duì)局部區(qū)域求平均,并把值賦給某個(gè)點(diǎn),一般我們賦給區(qū)域中心。本文將用C++實(shí)現(xiàn)boxfilter方框?yàn)V波,需要的可以了解一下2022-10-10
C++ 實(shí)現(xiàn)即時(shí)通信的示例代碼(直接運(yùn)行)
本文主要介紹了C++ 實(shí)現(xiàn)即時(shí)通信的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
詳解如何將c語(yǔ)言文件打包成exe可執(zhí)行程序
這篇文章主要介紹了詳解如何將c語(yǔ)言文件打包成exe可執(zhí)行程序,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02

