C語言實現(xiàn)簡易版掃雷的完整過程
一、問題描述
用C語言實現(xiàn)簡易版掃雷。
二、基本流程
1.菜單界面。
2.創(chuàng)建地圖 (兩個地圖)。
3.初始化地圖。
4.打印地圖。
5.程序讀取玩家輸入的要翻開位置的坐標,并校驗。
6.如果不是地雷,統(tǒng)計當前位置周圍雷的個數(shù), 并顯示到地圖上.。
7.判定游戲是否勝利。
三、步驟
1.菜單界面
1.開始游戲 0.退出游戲
int menu(){
printf("----------------------\n");
printf("------1.開始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請輸入你的選擇:");
scanf("%d", &choice);
return choice;
}
2.創(chuàng)建地圖
我們需要兩張地圖,所以要創(chuàng)建兩個二維數(shù)組。
第一個二維數(shù)組,表示玩家看到的地圖。(show)
第二個二維數(shù)組,表示當前位置是不是地雷(1表示是地雷,0表示不是地雷)。(mine)
使用宏定義的原因:
1.推高代碼可讀性,后續(xù)代碼中遇到9,方便理解含義。
2.提高擴展性,如果將來要修改棋盤尺寸,代碼修改會很方便。
#define MAX_ROW 9
#define MAX_COL 9
char show[MAX_ROW][MAX_COL] = { 0 };
char mine[MAX_ROW][MAX_COL] = { 0 };
3.初始化地圖
使用 * 表示未翻開的地。
show地圖一開始全都是 * 。
mine地圖是由0,1組成的。(1表示是地雷,0表示不是地雷)一開始都為0,隨后由電腦隨機在地圖上生成1。
這里我們使用宏定義了DIFFICULTY,表示地雷的數(shù)量:10個。
#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,先全設為'0', 然后隨機生成n個'1'
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'){
// 如果當前位置已經有雷了,就直接進入下次循環(huán), 重新產生隨機位置
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.玩家翻開坐標
玩家通過輸入坐標的方式翻開土地。
注意:
1.輸入坐標要在地圖范圍內。
2.不能重復翻開土地。
//程序讀取玩家輸入的要翻開位置的坐標, 并校驗
int row = 0;
int col = 0;
printf("請輸入翻開的坐標(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標超過范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經翻開,請重新輸入:\n");
continue;
}
6.判斷是否為地雷
如果翻開的位置在mine上顯示為1,那么翻到地雷了,輸出被炸死,打印地雷地圖,讓玩家死得明白。
如果翻開的位置上在mine上不是1,那么繼續(xù)下一步驟。
if (mine[row][col] == '1'){
printf("你已經被炸死了?。?!\n");
printMap(mine);
break;
}
7.更新地圖
計算周圍的地雷數(shù)量,在翻開位置顯示。
updateShow(show,mine,row,col);
// 根據(jù)當前 row, col 的位置, 計算出當前位置周圍有幾個雷
// 并且更新顯示到 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++;
}
}
}
//此時 count 里面就已經存好了 row, col 周圍 八個格子 的雷的個數(shù)
// 把這個結果寫到 show 中即可.
// 需要把數(shù)字 count 轉成對應的字符
show[row][col] = count + '0';
}
8.判斷是否勝利
定義一個變量safe,表示翻開的不是地雷的土地,每次更新地圖后,safe加一。如果最后翻開的不是地雷的土地等于地圖的大小減地雷數(shù),那么排除所有地雷,確認安全。
//記錄翻開的格子的個數(shù)
int safe = 0;
updateShow(show,mine,row,col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經排除所有的雷,你已經安全?。。n");
printMap(mine);
break;
}
四、代碼實現(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.開始游戲------\n");
printf("------0.退出游戲------\n");
printf("----------------------\n");
int choice = 0;
printf("請輸入你的選擇:");
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("請輸入翻開的坐標(row col):");
scanf("%d %d", &row, &col);
if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL){
printf("輸入的坐標超過范圍,重新輸入:\n");
continue;
}
if (show[row][col] != '*'){
printf("已經翻開,請重新輸入:\n");
continue;
}
if (mine[row][col] == '1'){
printf("你已經被炸死了?。?!\n");
// 打印一遍地雷的地圖, 讓玩家死的明白
printMap(mine);
break;
}
updateShow(show, mine, row, col);
safe++;
if (safe == MAX_ROW*MAX_COL - DIFFICULTY){
printf("已經排除所有的雷,你已經安全!??!\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("輸入錯誤,請重新輸入:");
continue;
}
}
}
總結
到此這篇關于C語言實現(xiàn)簡易版掃雷的文章就介紹到這了,更多相關C語言簡易版掃雷內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言自定義類型超詳細梳理之結構體 枚舉 聯(lián)合體
今天我們來學習一下自定義類型,自定義類型包括結構體、枚舉、聯(lián)合體,小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考2022-03-03
C++?OpenCV實現(xiàn)boxfilter方框濾波的方法詳解
box?filter的作用很簡單,即對局部區(qū)域求平均,并把值賦給某個點,一般我們賦給區(qū)域中心。本文將用C++實現(xiàn)boxfilter方框濾波,需要的可以了解一下2022-10-10

