扫雷

基本思路:1.设置三个9*9的数组,第一个用来实现光标的移动,第二个用来输出整个页面,雷和数字的情况,第三个用来记录每个格子是否被翻过,并且判断是否胜利。
                   2.设计函数遍历周围八格,返回周围八格的雷数
                   3.实现一个功能:在点到附近没有雷的块时,自动翻开旁边所有的没有雷的块(递归,广度优先算法的一种)
                   4.输出整个棋盘的输出函数(可以写的简洁的,太晚了,不想改了)
                   eg:随机生成雷的函数没写完,困了。

 

 

 

 


#include<iostream>
#include<conio.h>
#include<Windows.h>
#include <ctime>
using namespace std;
int qiPan[9][9] = { 0 };  //声明一个9行9列的数组来存储
int qiPanTwo[9][9] = { 0 }; //声明一个9行9列的数组来存储
int qiPanThree[9][9] = { 0 };//声明一个9行9列的数组在表示这个格子有没有被翻开
int X = 4;   //2.声明并初始化光标的横纵坐标
int Y = 4;
 
void CSH()
{
qiPan[4][4] = 9;  //更改棋盘中光标所在元素的值
}
 
 
int checkAndSetNearBombNumber(int x, int y) {
//检查当前方块周围的雷数量
int num = 0;
 
if (qiPanTwo[x][y]==10) {
//若该方块有地雷,则不用判断它周围有几个雷
return 0;
}
else {
//用两个循环当前方块周围8格扫一遍
for (int i = -1; i <= 1; i++) 
{
for (int j = -1; j <= 1; j++)
{
int nx = x + i;
int ny = y + j;
if (!(ny == y && nx == x) && (nx >= 0 && nx <= 9 - 1) && (ny >= 0 && ny <= 9 - 1)) 
{
if (qiPanTwo[nx][ny] == 10) 
{
num++; 
}
}
}
}
return num; // 设置该方块附近的地雷的数量
}
}
 
 
int Check()
{
int temp = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
{
if (qiPanThree[i][j] == 0)
{
temp++;
}
}
if (temp == 10)
{
return 1;
}
else return 0;
}
 
 
void Show()
{
for (int h = 0; h < 9; h++) //打印 
{
for (int l = 0; l < 9; l++)
{
if (qiPan[h][l] == 9) //由于光标所在图层应该在棋子图层之上,所以优先考虑。
{
cout << "·";
}
else if (qiPanThree[h][l] == 0)
{
cout << "■";
}
else if (checkAndSetNearBombNumber(h, l) == 0 && qiPanThree[h][l] == 1 && qiPanTwo[h][l] != 10)
{
cout << "□";
}
else if (checkAndSetNearBombNumber(h, l) == 1 && qiPanThree[h][l] == 1)
{
cout << "1 ";
}
else if (checkAndSetNearBombNumber(h, l) == 2 && qiPanThree[h][l] == 1)
{
cout << "2 ";
}
else if (checkAndSetNearBombNumber(h, l) == 3 && qiPanThree[h][l] == 1)
{
cout << "3 ";
}
else if (checkAndSetNearBombNumber(h, l) == 4 && qiPanThree[h][l] == 1)
{
cout << "4 ";
}
else if (checkAndSetNearBombNumber(h, l) == 5 && qiPanThree[h][l] == 1)
{
cout << "5 ";
}
else if (checkAndSetNearBombNumber(h, l) == 6 && qiPanThree[h][l] == 1)
{
cout << "6 ";
}
else if (checkAndSetNearBombNumber(h, l) == 7 && qiPanThree[h][l] == 1)
{
cout << "7 ";
}
else if (checkAndSetNearBombNumber(h, l) == 8 && qiPanThree[h][l] == 1)
{
cout << "8 ";
}
else if (qiPanTwo[h][l] == 10 && qiPanThree[h][l] == 1)
{
cout << "×";
}
}
cout << endl;
 
}
}
 
 
void autoOpen(int x, int y) {
//自动翻开周围无雷的方块
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int nx = x + i;
int ny = y + j;
if (!(ny == y && nx == x) && (nx >= 0 && nx <= 9 - 1) && (ny >= 0 && ny <= 9 - 1) && qiPanThree[nx][ny] == 0) {
if (checkAndSetNearBombNumber(nx, ny) == 0 && qiPanTwo[nx][ny] != 10) {
qiPanThree[nx][ny] = 1;
autoOpen(nx, ny);
}
else {
if (qiPanTwo[nx][ny] != 10)
{
qiPanThree[nx][ny] = 1;
}
}
}
}
}
}
 
 
/*void setBomb() {
//生成炸弹并且放进随机的方块中
int x;
int y;
int number = 10;
srand(time(NULL));
while (number--) 
{
 
}
}
*/
 
int main()
{
qiPanTwo[1][1] = 10;
qiPanTwo[1][8] = 10;
qiPanTwo[1][2] = 10;
qiPanTwo[2][4] = 10;
qiPanTwo[3][6] = 10;
qiPanTwo[4][4] = 10;
qiPanTwo[5][2] = 10;
qiPanTwo[6][8] = 10;
qiPanTwo[7][1] = 10;
qiPanTwo[8][0] = 10;
CSH();
Show();
char xx;  //控制台从键盘获得一个字符的函数(方法)
while (xx = _getch())
{
switch (xx)   //控制
{
case 'w':  //上
X = X - 1;  //使光标纵坐标-1 
qiPan[X][Y] = 9; //将光标写入棋盘 
qiPan[X + 1][Y] = 0; //使原本位置的值还原 
system("cls");
Show();
break;
case 's':  //下
X = X + 1;
qiPan[X][Y] = 9;
qiPan[X - 1][Y] = 0;
system("cls");
Show();
break;
case 'a':  //左
Y = Y - 1;
qiPan[X][Y] = 9;
qiPan[X][Y + 1] = 0;
system("cls");
Show();
break;
case 'd':  //右
Y = Y + 1;
qiPan[X][Y] = 9;
qiPan[X][Y - 1] = 0;
system("cls");
Show();
break;
case 'j':   //选定位置
qiPanThree[X][Y] = 1;
if (qiPanTwo[X][Y] == 10)
{
system("cls");
Show();
cout << "你踩到雷了" << endl;
break;
}
autoOpen(X, Y);
if (Check() == 1)
{
system("cls");
Show();
cout << "你赢了" << endl;
break;
}
system("cls");
Show();
 
}
}
}
 
posted @ 2022-06-18 10:38  Sheep灬  阅读(548)  评论(0编辑  收藏  举报