本文附贈源代碼,歡迎白嫖~
本篇文章目錄
- (一) 掃雷的c++實作方式
- 1.1 實作方式
- 1.2 代碼細節
- 1.2.1 完成時間的計算
- 1.2.2 地雷圖的隨機性
- 1.2.3 關于游戲的合理性和流暢度
- 1.2.3 鍵盤的操作與控制
- 1.3 注意事項
- 1.3.1 如何解決屏閃的問題
- 1.3.2 玩家試錯的機會
- (二)游戲體驗
- 2.1 游戲完整源代碼
- 2.2 游戲畫面
- 2.3 游戲教程
- (三)總結
(一) 掃雷的c++實作方式
1.1 實作方式
掃雷,顧名思義就是在一片未知的區域尋找在其中的隱藏的地雷,每開啟一個格點,如果這個點中不是雷,就能夠知道其周圍八個點中所蘊含的地雷總數,
當最終找到所有地雷的位置或者在這個程序中不慎踩到了地雷,游戲結束exit(0);,
1.2 代碼細節
1.2.1 完成時間的計算
當玩家掃雷成功時,這時需回傳玩家單輪游戲的用時,實作方法:在玩家開啟第一個雷時,標記t1=time(0);;在玩家掃雷成功時,標記t2=time(0);,最后,輸出t2-t1就是總時間了,
1.2.2 地雷圖的隨機性
地雷的地圖時用二維陣列實作的,而玩家的每一輪游戲的地圖都必須是不同的,因此,要用srand(time(NULL));以及rand()% x來實作,
1.2.3 關于游戲的合理性和流暢度
舉個栗子:在10x10的掃雷地圖中,若有99個雷,這時選中正確的概率非常低,為了避免這種情況,游戲的地圖大小和雷的個數要由玩家自由決定,并且保證游戲的難度,地雷數目要在一定的范圍內,
流暢度 -> 游戲轉換的間隔(時間過渡),Sleep(t)t為時間,以ms為單位,
1.2.3 鍵盤的操作與控制
游戲程序中選擇格點需要用鍵盤來選擇,并非輸入,
實作方式:
- 頭檔案
#include<conio.h> - 呼叫Windows的system部分
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle,&CursorInfo);//獲取控制臺游標資訊 CursorInfo.bVisible = false; //隱藏控制臺游標
- 判斷
char c=gecth()
1.3 注意事項
1.3.1 如何解決屏閃的問題
頻閃是由system("cls")產生的,在運行時,會先清空螢屏,再輸出內容,導致頻閃,
解決方法:
SetConsoleCursorInfo(handle, &CursorInfo);//設定控制臺游標狀態
1.3.2 玩家試錯的機會
為了避免玩家在第一步踩到雷,游戲結束,游戲設定會給予玩家一次復活的機會,繼續游戲,
(二)游戲體驗
2.1 游戲完整源代碼
#include <bits/stdc++.h>
#include <windows.h>
#include <conio.h>
using namespace std;
const int p[8][2]= {{0,1},{1,0},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
char c;
char xmp[21][21];
int mp[21][21],n,m,k,t1,t2;
bool mpb[21][21],bo[21][21];
void dfs0(int x,int y) {
mpb[x][y]=1;
for(int i=0; i<8; i++) {
if(x+p[i][0]<1 || x+p[i][0]>n || y+p[i][1]<1 || y+p[i][1]>m)
continue;
if(mp[x+p[i][0]][y+p[i][1]]==0) {
xmp[x+p[i][0]][y+p[i][1]]='0';
if(!mpb[x+p[i][0]][y+p[i][1]])
dfs0(x+p[i][0],y+p[i][1]);
}
if(mp[x+p[i][0]][y+p[i][1]]>0)
xmp[x+p[i][0]][y+p[i][1]]=mp[x+p[i][0]][y+p[i][1]]+'0';
}
return;
}
void bai(int x,int y) {
system("cls");
if(bo[x][y])
return;
bo[x][y]=1;
system("color C");
for(int k=1; k<=19; k++) {
Sleep(260);
system("cls");
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cout<<xmp[i][j]<<" ";
if(xmp[i][j]=='*')
xmp[i][j]='_';
}
cout<<endl<<endl;
}
int j=y+k;
for(int i=x-k; i<=x+k; i++) {
if(i<1 || i>n || j<1 || j>m)
continue;
if(mp[i][j]==-1) {
xmp[i][j]='*';
for(int l=0; l<8; l++)
xmp[i+p[l][0]][j+p[l][1]]='_';
}
}
j=y-k;
for(int i=x-k; i<=x+k; i++) {
if(i<1 || i>n || j<1 || j>m)
continue;
if(mp[i][j]==-1) {
xmp[i][j]='*';
for(int l=0; l<8; l++)
xmp[i+p[l][0]][j+p[l][1]]='_';
}
}
int i=x+k;
for(int j=x-k; j<=x+k; j++) {
if(i<1 || i>n || j<1 || j>m)
continue;
if(mp[i][j]==-1) {
xmp[i][j]='*';
for(int l=0; l<8; l++)
xmp[i+p[l][0]][j+p[l][1]]='_';
}
}
i=x-k;
for(int j=x-k; j<=x+k; j++) {
if(i<1 || i>n || j<1 || j>m)
continue;
if(mp[i][j]==-1) {
xmp[i][j]='*';
for(int l=0; l<8; l++)
xmp[i+p[l][0]][j+p[l][1]]='_';
}
}
}
system("pause");
system("color 7");
}
void win() {
t2=time(0);
for(int k=1; k<=n; k++) {
Sleep(150);
system("cls");
for(int i=1; i<=m; i++) {
if(mp[k-1][i]>0)
xmp[k-1][i]=mp[k-1][i]+'0';
else
xmp[k-1][i]='*';
xmp[k][i]=45;
}
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++)
cout<<xmp[i][j]<<" ";
cout<<endl<<endl;
}
}
system("cls");
cout<<"游戲成功,總共用時:"<<t2-t1<<"秒"<<endl<<endl;
system("pause");
system("cls");
}
void game() {
memset(mp,0,sizeof mp);
memset(mpb,0,sizeof mpb);
while(1) {
system("cls");
cout<<"請輸入長: ( >=5,<=20 )"<<endl;
cin>>m;
if(m<5 || m>20) {
cout<<"您輸入的數太大或太小了!重新輸入"<<endl;
Sleep(1200);
} else
break;
}
while(1) {
system("cls");
cout<<"請輸入寬: ( >=5,<=12 )"<<endl;
cin>>n;
if(n<5 || n>12) {
cout<<"您輸入的數太大或太小了!重新輸入"<<endl;
Sleep(1200);
} else
break;
}
while(1) {
system("cls");
cout<<"請輸入雷數: ( >=5,<="<<n*m-5<<" )"<<endl;
cin>>k;
if(k<5 || k>n*m-5) {
cout<<"您輸入的數太大或太小了!重新輸入";
Sleep(1200);
} else
break;
}
system("cls");
for(int i=1; i<=3; i++) {
cout<<"正在初始化.";
Sleep(280);
cout<<".";
Sleep(280);
cout<<".";
Sleep(280);
system("cls");
}
srand((unsigned)time(NULL));
for(int i=1; i<=k; i++) {
int x=rand()%n+1,y=rand()%m+1;
if(mp[x][y]==-1) {
i--;
continue;
} else
mp[x][y]=-1;
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
if(mp[i][j]==-1)
continue;
for(int k=0; k<8; k++)
if(mp[i+p[k][0]][j+p[k][1]]==-1)
mp[i][j]++;
}
char s[21][21];
for(int i=1; i<=20; i++)
for(int j=1; j<=20; j++) {
s[i][j]=' ';
xmp[i][j]=22;
}
int x=1,y=1,sum=0;
bool o=0,f=0,fir=0;
while(1) {
sum=0;
system("cls");
s[x][y]='<';
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(xmp[i][j]==127)
sum++;
cout<<xmp[i][j]<<s[i][j];
}
cout<<endl<<endl;
}
cout<<"剩余雷數: "<<k-sum;
if(o) {
Sleep(2000);
bai(x,y);
system("cls");
cout<<"游戲失敗!";
Sleep(2500);
system("cls");
return;
}
c=getch();
switch(c) {
case 'w': {
s[x][y]=' ';
if(--x<1)
x=n;
break;
}
case 's': {
s[x][y]=' ';
if(++x>n)
x=1;
break;
}
case 'a': {
s[x][y]=' ';
if(--y<1)
y=m;
break;
}
case 'd': {
s[x][y]=' ';
if(++y>m)
y=1;
break;
}
case 'j': {
if(!fir) {
t1=time(0);
fir=1;
}
if(mp[x][y]==-1) {
if(!f) {
f=1;
cout<<endl<<"您的rp太低,這是個雷!(僅提醒一次)";
Sleep(2000);
} else {
xmp[x][y]='*';
o=1;
}
}
if(mp[x][y]==0) {
xmp[x][y]='0';
dfs0(x,y);
}
if(mp[x][y]>0)
xmp[x][y]=mp[x][y]+'0';
bool bo=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(mp[i][j]==-1)
continue;
if(xmp[i][j]!=mp[i][j]+'0')
bo=1;
}
}
if(bo)
break;
win();
return;
}
case 'k': {
if(xmp[x][y]==22) {
xmp[x][y]=127;
break;
}
if(xmp[x][y]==127) {
xmp[x][y]='?';
break;
}
xmp[x][y]=22;
break;
}
}
}
}
int main() {
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle,&CursorInfo);//獲取控制臺游標資訊 CursorInfo.bVisible = false; //隱藏控制臺游標
SetConsoleCursorInfo(handle, &CursorInfo);//設定控制臺游標狀態
cout<<" ----歡迎您來到掃雷----";
Sleep(2500);
system("cls");
for(int i=1; i<=2; i++) {
cout<<"加載中.";
Sleep(300);
cout<<".";
Sleep(300);
cout<<".";
Sleep(300);
system("cls");
}
string s[3]= {" "," "," "};
int now=0;
while(1) {
s[now]='<';
cout<<"自定義游戲 "<<s[0]<<endl;
cout<<"游戲教程 "<<s[1]<<endl;
cout<<"退出 "<<s[2]<<endl<<endl;
cout<<"ws上下控制,j確定";
c=getch();
system("cls");
switch(c) {
case 'w': {
s[now]=' ';
if(--now<0)
now=3;
break;
}
case 's': {
s[now]=' ';
if(++now>3)
now=0;
break;
}
case 'j': {
if(now==0)
game();
if(now==1) {
system("cls");
cout<<"wasd控制選中的單元格"<<endl;
cout<<"j翻開單元格,k標記地雷格格"<<endl;
cout<<"第一次翻到雷會給出一次提醒"<<endl<<endl;
cout<<"如果您運氣實在太差"<<endl;
cout<<"翻出的是無法判斷雷的圖"<<endl;
cout<<"接下來就看臉 ^_^"<<endl<<endl;
system("pause");
system("cls");
}
if (now==2)
return 0;
break;
}
}
}
}
2.2 游戲畫面
畫面設計不夠美觀,請諒解!!



2.3 游戲教程
-
wasd控制選中的單元格
-
j翻開單元格,k標記地雷格格
-
第一次翻到雷會給出一次提醒
具體請見游戲內教程
(三)總結
這是一項智力游戲,同時考驗了開發者的代碼能力,看似非常簡單,但實際上有很多細節需要考慮,
爆肝3天,代碼白嫖,點贊請留下, T h a n k Thank Thank y o u ? ( ・ ω ・ ) ノ you?(・ω・)ノ you?(・ω・)ノ
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291575.html
標籤:其他
上一篇:Unity協程——簡單應用
下一篇:C語言實作三子棋游戲
