1. 程式人生 > 程式設計 >C++實現簡單掃雷小遊戲

C++實現簡單掃雷小遊戲

本文例項為大家分享了C++實現簡單掃雷小遊戲的具體程式碼,供大家參考,具體內容如下

標頭檔案Mine_Sweep.h

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <Windows.h>
using namespace std;

typedef pair<int,int> P;
const int M = 10;
const int N = 10;

void InitGame(int A[M][N]);//初始化遊戲
void Map(int A[M][N],int Static[M][N]);//地圖
void Result(int A[M][N]);//遊戲結果
int IfSafety(int A[M][N],int x,int y);//周圍是否有地雷
void Operate(int A[M][N],int Static[M][N],int y); //操作產生的影響
void Welcome(); //歡迎介面
void GameOver(); //結束介面
void gotoxy(int x,int y);   //指標位置
void color(int c);  //改變顏色

實現部分

#include"Mine_Sweep.h"

void InitGame(int A[M][N])
{
 //從右開始順時針->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
 int Sign[8][2] = { {1,0},{1,1},{0,{-1,-1},-1} };
 int count = 0;//產生M個不同隨機數
 int Random; //隨機數1-100
 int x,y;  //橫縱座標
 srand(unsigned(time(NULL)));
 //清空
 for (int i = 0; i < M; i++)
 for (int j = 0; j < N; j++)
 A[i][j] = 0;
 //把M個雷安放好
 while (count < M)
 {
 Random = rand() % 100 + 1;
 x = Random / 10;  //轉換為X
 y = Random - 10 * x; //轉換為Y
 if (A[x][y] == 0)  //地雷設為-1,無地雷設為0,1,2...
 {
 A[x][y] = -1;
 count++;
 }
 }
 //構建一個虛擬的地圖即增加外圍[M][N]->[M+2][N+2]目的是為了讓邊界和內部的處理方式一樣
 int Virtual[M + 2][N + 2] = { 0 };
 for (int i = 0; i < M; i++)
 {
 for (int j = 0; j < N; j++)
 {
 Virtual[i + 1][j + 1] = A[i][j];//所有元素向下向右移動1格
 }
 }
 //計算每個地方的地雷分佈情況
 for (int i = 1; i <= M; i++)
 {
 for (int j = 1; j <= N; j++)
 {
 int flag = 0;
 //如果是地雷
 if (Virtual[i][j] == -1)
 continue;  //跳過
 for (int k = 0; k < 8; k++)
 {
 if (Virtual[i + Sign[k][0]][j + Sign[k][1]]==-1)
  flag++;
 }
 A[i-1][j-1] = flag;
 }
 }
}

void Map(int A[M][N],int Static[M][N])
{
 system("cls");
 Welcome();
 //地雷用※表示,數字用123...,未翻開用■ Static[M][N]用於儲存狀態0表示未翻開,1表示翻開
 for (int i = 0; i < M; i++)
 {
 cout << "\t\t\t\t\t"<<" ";
 for (int j = 0; j < N; j++)
 {
 if (Static[i][j] == 0)
 cout << "■";
 else
 {
 if (A[i][j] == -1)
 {
  cout << "※";
  
 }
 else
 {
  if (IfSafety(A,i,j))
  cout << "□";
  else
  cout <<" " <<A[i][j];
 }
 }
 }
 cout << endl;
 }
}

void Operate(int A[M][N],int y)//貪心演算法
{
 queue<P> que;//佇列
 //從右開始順時針->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
 int Sign[8][2] = { {1,-1} };
 if (A[x][y] == -1) //如果翻到地雷,遊戲結束
 {
 Result(A); //顯示結果
 GameOver();   //遊戲結束
 exit(0);
 }
 Static[x][y] = 1;//翻開
 que.push(P(x,y));

 while (que.size()) {
 P p = que.front();
 que.pop();
 if(!IfSafety(A,p.first,p.second))
 continue; //如果周圍有炸彈,繼續遍歷佇列
 
 for (int i = 0; i < 8; i++) {
 int nx = p.first + Sign[i][0];
 int ny = p.second + Sign[i][1];
 if (0 <= nx && nx < M && 0 <= ny && ny < N && Static[nx][ny] == 0) {
 que.push(P(nx,ny));
 Static[nx][ny] = 1;//翻開
 }
 }
 }
}
void Result(int A[M][N])
{
 for (int i = 0; i < M; i++) {
 cout << "\t\t\t\t\t";
 for (int j = 0; j < N; j++)
 cout << A[i][j]<<" ";
 cout << endl;
 }
 
}

int IfSafety(int A[M][N],int y)
{
 //從右開始順時針->右(1,0)右上(1,1)上(0,1)左上(-1,1)左(-1,0)左下(-1,-1)下(0,-1)右下(1,-1)
 int Sign[8][2] = { {1,-1} };
 int Virtual[M + 2][N + 2] = { 0 };
 x = x + 1;//虛擬座標
 y = y + 1;
 for (int i = 0; i < M; i++)
 {
 for (int j = 0; j < N; j++)
 {
 Virtual[i + 1][j + 1] = A[i][j];//所有元素向下向右移動1格
 }
 }
 //計算每個地方的地雷分佈情況
 for (int k = 0; k < 8; k++)
 {
 if (Virtual[x + Sign[k][0]][y + Sign[k][1]] == -1)
 return 0;
 }
 return 1;
}

void Welcome()
{
 cout << "\t\t\t\t\t\t掃雷遊戲"<<endl<<endl;
 cout << "\t\t\t\t===========================================" << endl << endl;
 gotoxy(40,3);
 for (int i = 0; i < M; i++)
 {
 //畫x軸座標
 cout << " " << i + 1;
 }
 
 for (int j = 0; j < M; j++)
 {
 //畫Y軸座標
 gotoxy(38,4+j);
 cout << j + 1<<endl;
 }
 gotoxy(0,4);
}

void GameOver()
{
 cout << "\t\t\t\t遊戲結束,你輸了" << endl;
 getchar();
 getchar();
}

void gotoxy(int x,int y)
{
 COORD pos;
 pos.X = x;
 pos.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}

void color(int c)
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);
}

主函式

#include"Mine_Sweep.h"

int main()
{
 int A[M][N],x,y,Static[M][N] = { 0 };
 color(13);
 InitGame(A);
 cout << "\n\n\n\t\t遊戲說明:" << "你需要在不點錯雷的情況下儘可能快的將所有的雷都標記出來\n";
 cout << "\t\t你點出了一個數字,是1,就說明它周圍的8的格子裡有1個雷,是2就有兩個雷,是3就有三個雷···" << endl;
 cout<< "\t\t但如果你標記錯了雷,那就會boom!遊戲結束。"<<endl;
 cout << "\t\t請先輸入橫座標,再輸入縱座標 eg: 1 2" << endl;
 cout << "\t\t回車鍵開始,祝你好運!" << endl;
 getchar();
 color(15);
 while (1)
 {
 int flag = 1;
 Map(A,Static);
 cout << "\t\t\t\t請輸入要翻開的座標:";
 cin >> x >> y;
 while (x <= 0 || x > M || y <= 0 || y > N)
 {
 cout << "\t\t\t\t超出範圍,請重新輸入要翻開的座標:" ;
 cin >> x >> y;
 }
 Operate(A,Static,x-1,y-1);
 }
 return 0;
}

執行效果

C++實現簡單掃雷小遊戲
C++實現簡單掃雷小遊戲
C++實現簡單掃雷小遊戲
C++實現簡單掃雷小遊戲

更多有趣的經典小遊戲實現專題,分享給大家:

C++經典小遊戲彙總

python經典小遊戲彙總

python俄羅斯方塊遊戲集合

JavaScript經典遊戲 玩不停

java經典小遊戲彙總

javascript經典小遊戲彙總

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。