【18.7.25】掃雷c語言小遊戲,展開與防第一次炸死功能
阿新 • • 發佈:2018-11-20
遞迴看了N遍終於寫出來了展開功能,心塞。
上效果圖
開啟程式碼,control+F5,走!
輸入1開始遊戲
密集恐懼症,心裡一萬隻草泥馬路過。。。
未開啟前都是‘*’號,玩家根據行標和列標輸入需要掃雷的位置
就快要贏了,當然這個難度可能比較低,但是可以自行設定難度,我自己預設的是20*20的表格,20個大雷子。
Test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()//設計選單
{
printf("■■■■■■ 掃雷遊戲 ■■■■■■\n");
printf ("■■■■■■■■■■■■■■■■■\n");
printf("■■■■■■■■■■■■■■■■■\n");
printf("■■■■■■1.開始遊戲■■■■■■\n");
printf("■■■■■■■■■■■■■■■■■\n");
printf("■■■■■■0.退出遊戲■■■■■■\n");
printf("■■■■■■■■■■■■■■■■■\n");
}
void game()//遊戲函式
{
int i = 0;//迴圈變數
int x = 0;//玩家輸入行標
int y = 0;//玩家輸入列標
char Hidemap[ROW][COL] = {0 };//開發者棋盤;
char Showmap[ROW][COL] = {0};//玩家棋盤;
srand((unsigned int)time(NULL));//增加隨機性;
Initmap(Hidemap,Showmap,ROW,COL);//初始化棋盤;
Devicemine(Hidemap,ROW,COL,Mine);//佈置地雷;
Printmap(Showmap,ROW,COL);//列印玩家棋盤;
for(i=0;i<((ROW-2)*(COL-2)-Mine);i++)//迴圈做多迴圈表格裡除了地雷數的所有地方,但也可提前跳出
{
printf ("請輸入需要開啟的座標:");
scanf("%d%d",&x,&y);
if(x>=1&&x<=ROW&&y>=1&&y<=COL)
{
if(i==0)
{
Savepleyer(Hidemap,ROW,COL,x,y);//增加玩家遊戲體驗,防止第一次就炸死
}
if(Open(Hidemap,Showmap,x,y))//開啟座標,如果不是雷繼續,是雷就執行else。
{
;
}
else
{
break;
}
if(Countshowmine(Showmap,ROW,COL)==Mine)//判定條件,全部雷被找出,玩家就贏了
{
printf("恭喜玩家獲勝/n");
break;
}
Printmap(Showmap,ROW,COL);
}
else
{
printf("對不起,您的輸入有誤,請重新輸\n");
}
}
}
void test()
{
int input = 0;
do
{
menu();//列印選單;
printf("請輸入指令:");
scanf("%d",&input);
switch(input)//玩家是否開始遊戲
{
case 0://推出遊戲
printf("即將退出遊戲\n");
Sleep(2000);
system("cls");
break;
case 1://開始遊戲
printf("遊戲即將開始\n");
Sleep(2000);
system("cls");
game();//進入遊戲函式
break;
default :
printf("輸入錯誤,請您重新輸入\n");
break;
}
}
while(input);
}
int main()//主函式入口進入
{
test();
return 0;
}
這裡注意,建立陣列是一個是開發者,顯示的是雷的佈局,為玩家棋盤服務的陣列。
比如我們玩10*10的表格,但是要建立12*12的表格,原因是如果玩家探索邊緣的地方,在統計的時候,統計周圍八個地區,就會存在陣列的越界,但是我們如果多建立2行2列,但是雷都佈置到內10行10列中,就可以避免這個問題。列印同樣也只打印內10行10列。
Game.c
遊戲核心檔案
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Initmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int row,int col)//初始化兩個陣列
{
memset(Hidemap,'0',row*col*sizeof(Hidemap[0][0]));//開發者棋盤初始化全0
memset(Showmap,'*',row*col*sizeof(Showmap[0][0]));//玩家棋盤未掃區域為*
}
void Devicemine(char Hidemap[ROW][COL],int row,int col,int mine)
{
int x = 0;
int y = 0;
while(mine)
{
x = rand() % (row-2);//產生0-row的餘數
y = rand() % (col-2);//產生0-col的餘數
if(Hidemap[x+1][y+1] == '0')//僅在1-(row-1)區域內佈雷
{
Hidemap[x+1][y+1] = '1';//僅在1-(col-1)區域內佈雷
mine--;
}
}
}
int Countmine(char Hidemap[ROW][COL],int x,int y)//記雷數函式
{
int count = 0;
if(Hidemap[x-1][y-1] == '1')//統計周圍八個地區的雷數
{
count++;
}
if(Hidemap[x-1][y] == '1')
{
count++;
}
if(Hidemap[x-1][y+1] == '1')
{
count++;
}
if(Hidemap[x][y-1] == '1')
{
count++;
}
if(Hidemap[x][y+1] == '1')
{
count++;
}
if(Hidemap[x+1][y-1] == '1')
{
count++;
}
if(Hidemap[x+1][y] == '1')
{
count++;
}
if(Hidemap[x+1][y+1] == '1')
{
count++;
}
return count;//返回周圍雷的個數
}
int Open(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y)//開啟需要排查地方
{
if(Showmap[x][y]=='*')
{
if(Hidemap[x][y]=='0')
{
if(Countmine(Hidemap,x,y)!=0)//如果周圍有雷,就正常顯示周圍雷的個數
{
Showmap[x][y] =Countmine(Hidemap,x,y)+'0';
}
else
{
Unfoldmap(Hidemap,Showmap,x,y);//如果周圍沒雷就得展開這個區域
}
}
else
{
printf("你踩到雷了!\n");
return 0;
}
}
return 1;
}
void Printmap(char arr[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
printf(" 0 ");
for(i=1;i<=(col-2);i++)//列印列標
{
printf("% 3d ",i);
}
printf("\n");
printf(" ┏");//列印裝飾表格
for(j=0;j<col-3;j++)
{
printf("━┳");
}
printf("━┓\n");
for(i=1;i<=(row-2);i++)
{
printf("%2d┃",i);//列印行標
for(j=1;j<=(col-2);j++)
{
printf(" %c",arr[i][j]);
printf("┃");
}
printf("\n");
if(i<row-2)
{
printf(" ┣");
for(j=0;j<col-3;j++)
{
printf("━╋");
}
printf("━┫\n");
}
}
printf(" ┗");
for(j=0;j<col-3;j++)
{
printf("━┻");
}
printf("━┛\n");
}
void Savepleyer(char Hidemap[ROW][COL],int row,int col,int x,int y)
{
int ret = 1;
if(Hidemap[x][y]=='1')
{
Hidemap[x][y] = '0';
while(ret)
{
x = rand() % row;
y = rand() % col;
if(Hidemap[x+1][y+1] == '0')
{
Hidemap[x+1][y+1] = '1';
ret--;
}
}
}
}
void Unfoldmap(char Hidemap[ROW][COL],char Showmap[ROW][COL],int x,int y)
{
Showmap[x][y] = ' ';//周圍沒雷,直接顯示空格,並且自動開啟周圍的幾個區域
Open(Hidemap,Showmap,(x+1),(y+1));
Open(Hidemap,Showmap,(x+1),(y-1));
Open(Hidemap,Showmap,(x+1),(y));
Open(Hidemap,Showmap,(x),(y+1));
Open(Hidemap,Showmap,(x),(y-1));
Open(Hidemap,Showmap,(x-1),(y+1));
Open(Hidemap,Showmap,(x-1),(y-1));
Open(Hidemap,Showmap,(x-1),(y));
}
int Countshowmine(char Showmap[ROW][COL],int row,int col)//判斷剩餘未知區域的個數,個數為雷數時玩家贏
{
int count = 0;
int i = 0;
int j = 0;
for(i=1;i<=(row-2);i++)
{
for(j=1;j<=(col-2);j++)
{
if (Showmap[i][j] == '*')
{
count++;
}
}
}
return count;
}
注意這裡的傳參問題。
Game.h標頭檔案
#ifndef __GAME_H__
#define __GAME_H__
#define ROW 22
#define COL 22
#define Mine 20
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
void Initmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int row, int col);
void Devicemine(char Hidemap[ROW][COL], int row, int col, int mine);
int Countmine(char Hidemap[ROW][COL], int x, int y);
int Open(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
void Printmap(char arr[ROW][COL], int row, int col);
void Savepleyer(char Hidemap[ROW][COL], int row, int col, int x, int y);
void Unfoldmap(char Hidemap[ROW][COL], char Showmap[ROW][COL], int x, int y);
int Countshowmine(char Showmap[ROW][COL], int row, int col);
#endif //__GAME_H__