掃雷超級超級詳細講解:
- 一:第一步選單函式
- 二:主函式創建
- 三:游戲函式的實作
- 1.創建初始化地圖
- 2.列印地圖
- 3.玩家輸入,電腦校驗
- 4.判斷勝負
- 5.列印地雷數函式
- 6.回圈實作
- 7.回圈最終判定
- 四:源代碼
提到掃雷,我們每個人都會有自己的記憶,今天我來用C語言寫一個簡易版的掃雷,我會站在一個比較基礎的角度去分析問題,讓我們一起看看掃雷的完整步驟吧!
要想做一個簡單的小游戲,我們首先會考慮到如何讓用戶看到我們的游戲,如何操作,所以我們先做一個簡單的游戲互動選單吧!
我們首先寫一個選單函式menu:
一:第一步選單函式
int menu(){
int choice = 0;
printf("****************\n");
printf("**1.play********\n");
printf("**2.quit********\n");
printf("****************\n");
printf("輸入你的選擇:\n");
scanf("%d", &choice);
return choice;
}
當我們的選單函式創建完成了,我們就要考慮main函式的創建了,main函式是我們的最基礎(在這里我們可以將最開始創建的選單函式的分支選擇陳述句寫道這里面),
二:主函式創建
int main(){
while (1){
int choice = menu();
if (choice == 1){
game();
}
else if (choice == 2){
printf("bye\n");
break;
}
else{ printf("輸入錯誤\n");
}
}
system("pause");
return 0;
}
看到我們的選擇陳述句了嗎?是不是有一個game函式,這就是我們接下來的任務了!這才是主要的游戲撰寫!
但是如何寫一個游戲呢?
最重要的是先有思路,我們先把思路清晰,然后在根據我們列出的步驟來寫代碼!這樣才是適合新手的方案!
三:游戲函式的實作
注意: 思路比具體的代碼更重要.
1 . 創建地圖并初始化. (兩個地圖,一個給用戶看,一個給自己埋雷用)
2 . 列印地圖(向用戶展示基本的游戲界面)
3 . 程式讀取玩家輸入的要翻開位置的坐標, 并校驗(電腦判斷玩家下的棋子位置在自己埋雷的地圖中是什么!)
4 . 判定該位置的坐標是否是地雷. 如果是地雷, 直接 GameOver
5 . 如果不是地雷, 統計當前位置周圍雷的個數, 并顯示到地圖上.(就是掃雷的基本規則,一個地方周圍的八個地方有沒有雷子!)
6 . 然后回圈以上步驟直到滿足下一個條件7!
7 . 判定游戲是否勝利!(核心邏輯應該是判斷當前是不是把所有不是雷的位置都翻開了,)
1.創建初始化地圖
首先我們做第一步:創建初始化地圖(2個)
void init(char showmap[MAX_ROW][MAX_COL],
char minemap[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
showmap[row][col] = ' *';
}
}
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
minemap[row][col] = '0';
}
}
int n=DEFAULT_MINE_COUNT ;//10個雷子數!!!!
while (n>0){
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (minemap[row][col] == '1'){
continue;
}
minemap[row][col] ='1';
n--;
}
}
注意我為了方便,用宏定義來寫了9行9列10雷!
#define MAX_ROW 9
#define MAX_COL 9
#define DEFAULT_MINE_COUNT 10
其中一個都是*** 這個是給玩家看的,一個是全為0,然后用rand函式賦值10個1作為雷子!
rand函式就是一個簡單的偽亂數函式(我的其他博客有詳細介紹!)
2.列印地圖
- 列印地圖(向用戶展示基本的游戲界面)
這個步驟是我們列印棋盤的函式,每一次下棋都會更新!
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");
}
}
3.玩家輸入,電腦校驗
- 程式讀取玩家輸入的要翻開位置的坐標, 并校驗(電腦判斷玩家下的棋子位置在自己埋雷的地圖中是什么!)
注意:這里不是函式!!你先看得懂就好了,最后我們一起總結在game函式里!!
int row = 0;
int col = 0;
printf("請輸入你的坐標:");
scanf("%d %d", &row, &col);
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL){
continue;
}
if (showmap[row][col] !='*'){
continue;
}
4.判斷勝負
- 判定該位置的坐標是否是地雷. 如果是地雷, 直接 GameOver
為了讓玩家死得明白,我們在死前幫助他列印一邊地圖!!注意是minemap(真正的地雷地圖!!!)
if (minemap[row][col] == '1'){
printf("你輸了!\n");
printmap(minemap);
break;
}
5.列印地雷數函式
- 如果不是地雷, 統計當前位置周圍雷的個數, 并顯示到地圖上.(就是掃雷的基本規則,一個地方周圍的八個地方有沒有雷子!)
這個函式比較復雜,我們用+1 ,-1的小二層回圈鑲嵌來表示的周圍的地雷,也就是遍歷周圍的8個格子是不是地雷!!!!
void updateshowmap(char showmap[MAX_ROW][MAX_COL] ,
char minemap[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 (minemap[R][C] == '1'){
count++;
}
if (R < 0 || R >= MAX_ROW
|| C < 0 || C >= MAX_COL) {
continue;
}
}
}
showmap[row][col] = count + '0';
}
6.回圈實作
- 然后回圈以上步驟直到滿足下一個條件7!
這一步在game函式中簡單的就可以解決,先省略,,看下來的game函式!!!
7.回圈最終判定
- 判定游戲是否勝利!(核心邏輯應該是判斷當前是不是把所有不是雷的位置都翻開了,)
if (count == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT) {
printf("游戲勝利!\n");
printmap(minemap);
break;
};
走到這里你是不是看懂了呢?只需最后一步我們把game函式總結起來,你就會豁然開朗!!!!
注意我們有一個檢驗正確性的輔助方法,就是列印我們的正確地圖,記得讓你朋友試試的時候刪掉!!
printmap(minemap);
printf("=================================\n");//輔助
如下:
void game(){
char showmap[MAX_ROW][MAX_COL] = { 0 };
char minemap[MAX_ROW][MAX_COL] = { 0 };
init(showmap, minemap);
int count = 0;
while (1){
printmap(minemap);
printf("=================================\n");//輔助
printmap(showmap);
int row = 0;
int col = 0;
printf("請輸入你的坐標:");
scanf("%d %d", &row, &col);
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL){
continue;
}
if (showmap[row][col] !='*'){
continue;
}
if (minemap[row][col] == '1'){
printf("你輸了!\n");
printmap(minemap);
break;
}
updateshowmap(showmap, minemap, row, col);
count++;
if (count == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT) {
printf("游戲勝利!\n");
printmap(minemap);
break;
}
}
}
所有的函式都被我們整合在了game里面!是不是很簡單!!!
四:源代碼
下面我把完整的源代碼寫在這里,你可以直接復制試一試!
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_ROW 9
#define MAX_COL 9
#define DEFAULT_MINE_COUNT 10
int menu(){
int choice = 0;
printf("****************\n");
printf("**1.play********\n");
printf("**2.quit********\n");
printf("****************\n");
printf("輸入你的選擇:\n");
scanf("%d", &choice);
return choice;
}
void init(char showmap[MAX_ROW][MAX_COL],
char minemap[MAX_ROW][MAX_COL]){
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
showmap[row][col] = ' *';
}
}
for (int row = 0; row < MAX_ROW; row++){
for (int col = 0; col < MAX_COL; col++){
minemap[row][col] = '0';
}
}
int n=DEFAULT_MINE_COUNT ;
while (n>0){
int row = rand() % MAX_ROW;
int col = rand() % MAX_COL;
if (minemap[row][col] == '1'){
continue;
}
minemap[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 updateshowmap(char showmap[MAX_ROW][MAX_COL] ,
char minemap[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 (minemap[R][C] == '1'){
count++;
}
if (R < 0 || R >= MAX_ROW
|| C < 0 || C >= MAX_COL) {
continue;
}
}
}
showmap[row][col] = count + '0';
}
void game(){
char showmap[MAX_ROW][MAX_COL] = { 0 };
char minemap[MAX_ROW][MAX_COL] = { 0 };
init(showmap, minemap);
int count = 0;
while (1){
printmap(minemap);
printf("=================================\n");//輔助
printmap(showmap);
int row = 0;
int col = 0;
printf("請輸入你的坐標:");
scanf("%d %d", &row, &col);
if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL){
continue;
}
if (showmap[row][col] !='*'){
continue;
}
if (minemap[row][col] == '1'){
printf("你輸了!\n");
printmap(minemap);
break;
}
updateshowmap(showmap, minemap, row, col);
count++;
if (count == MAX_ROW * MAX_COL - DEFAULT_MINE_COUNT) {
printf("游戲勝利!\n");
printmap(minemap);
break;
}
}
}
int main(){
srand((unsigned int)time(0));
while (1){
int choice = menu();
if (choice == 1){
game();
}
else if (choice == 2){
printf("bye\n");
break;
}
else{ printf("輸入錯誤\n");
}
}
system("pause");
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/209419.html
標籤:其他
