C++版扫雷小游戏(扫雷1.0)
发布时间
阅读量:
阅读量
这是原创的C++版扫雷小游戏,有缺陷请多多指教。
使用C++软件:Dev-C++
网盘带.cpp源代码文件和.exe可执行文件。
链接: https://pan.baidu.com/s/1RY3DLiNqa_fQFs0imGIjWA?pwd=1234
提取码: 1234
游戏版本:扫雷1.0
代码:
#include<stdio.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
struct Map//地图结构体
{
char map;//地图数据
bool open;//地图是否打开
bool flat;//地图插旗子
bool mark;//地图标记
};
int game;//是否开始游戏
Map map[26][51];//地图表
int movex[9] = { 0,-1,0,1,-1,1,-1,0,1 };//坐标及周围8个坐标的横坐标
int movey[9] = { 0,-1,-1,-1,0,0,1,1,1 };//坐标及周围8个坐标的纵坐标
int mapx;//地图的长
int mapy;//地图的宽
int mapf;//总共雷数
int mine;//是否踩雷
int open;//打开坐标数量
int flat;//剩余旗子数量
int gotox, gotoy;//所在的x坐标和y坐标
int colour[9] = { 0,8,11,3,9,1,10,2,6 };//数字用的颜色
void Gotoxy(short x, short y);
void Colourxy(short x, short y);
void Welcome();
void Ask();
void AskSpeak(int i, bool b);
void AskIn(int& x);
void CleanMap();
void ReadyMap();
void CreateMap();
void Help();
void Move();
void MoveOut(int i);
void Open(int x, int y);
void Again();
void AgainSpeak(bool b);
void Over();
int main()//主函数
{
Welcome();
do
{
Ask();
CleanMap();
ReadyMap();
CreateMap();
while (open < mapx * mapy - mapf)//判断是否游戏结束
{
Help();
Move();
if (mine == 1)//踩雷游戏结束
{
break;
}
}
Again();
} while (game);
Over();
return 0;
}
void Gotoxy(short x, short y)//设置光标位置
{
COORD pos = { y,x };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, pos);
}
void Colourxy(short x, short y)//设置光标颜色
{
WORD color = ((y & 0x0F) << 4) + (x & 0x0F);
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hOut, color);
}
void Welcome()//欢迎界面
{
CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(hOut, &cursor_info);//清除光标
printf("欢迎来到扫雷游戏 请全屏\n");
system("pause");
system("cls");
}
void Ask()//地图难度
{
Colourxy(0, 15);
printf("初级,9行9列10个雷 \n");
Colourxy(15, 0);
printf("中级,16行16列40个雷 \n");
printf("高级,16行30列99个雷 \n");
printf("自定义,自定义行、列和雷数\n");
printf("退出游戏 \n\n");
Colourxy(0, 14);
printf("W.S.选择难度");
Colourxy(15, 0);
int i = 1;
char ch = 0;
while (ch != '\r')
{
while (kbhit() == 0);
ch = getch();
switch (ch)
{
case 'w':
case 'W':
AskSpeak(i, 0);
i--;
if (i < 1)
{
i = 5;
}
AskSpeak(i, 1);
break;
case 's':
case 'S':
AskSpeak(i, 0);
i++;
if (i > 5)
{
i = 1;
}
AskSpeak(i, 1);
break;
}
}
Gotoxy(6, 0);
switch (i)
{
case 1:
mapx = 9;
mapy = 9;
mapf = 10;
break;
case 2:
mapx = 16;
mapy = 16;
mapf = 40;
break;
case 3:
mapx = 16;
mapy = 30;
mapf = 99;
break;
case 4:
while (1)
{
printf("请输入雷区行数:(不少于1,不超过25)");
AskIn(mapx);
if (mapx < 1 || mapx>25)
{
printf("输入错误,请重试。\n");
}
else
{
break;
}
}
while (1)
{
printf("请输入雷区列数:(不少于1,不超过50)");
AskIn(mapy);
if (mapy < 1 || mapy>50)
{
printf("输入错误,请重试。\n");
}
else
{
break;
}
}
while (1)
{
printf("请输入雷区雷数:(建议不超过总大小的三分之一)");
AskIn(mapf);
if (mapf<1 || mapf>mapx * mapy)
{
printf("输入错误,请重试。\n");
}
else
{
break;
}
}
break;
case 5:
mapx = 0;
mapy = 0;
mapf = 0;
printf("退出操作中...\n");
Sleep(500);
break;
}
}
void AskSpeak(int i, bool b)//选择的选项
{
Gotoxy(i - 1, 0);
if (b == true)
{
Colourxy(0, 15);
}
else
{
Colourxy(15, 0);
}
switch (i)
{
case 1:
printf("初级,9行9列10个雷 ");
break;
case 2:
printf("中级,16行16列40个雷 ");
break;
case 3:
printf("高级,16行30列99个雷 ");
break;
case 4:
printf("自定义,自定义行、列和雷数");
break;
case 5:
printf("退出游戏 ");
break;
}
Colourxy(15, 0);
}
void AskIn(int& x)//输入
{
char a[101];
scanf("%s", a);
int len = strlen(a);
x = 0;
for (int i = 0; i < len; i++)
{
if (a[i] < '0' || a[i]>'9')
{
x = 0;
break;
}
x *= 10;
x += a[i] - '0';
}
}
void CleanMap()//初始化地图
{
int i, j;
for (i = 1; i <= mapx; i++)
{
for (j = 1; j <= mapy; j++)
{
map[i][j].map = '0';
map[i][j].open = false;
map[i][j].flat = false;
map[i][j].mark = false;
}
}
mine = 0;
open = 0;
flat = mapf;
gotox = 1;
gotoy = 1;
}
void ReadyMap()//准备地图
{
printf("准备地图中...\n");
int i, j;
srand(time(NULL) + 7);//取随机数
i = mapf;
while (i)
{
int readyx = rand() % mapx;
int readyy = rand() % mapy;
if (readyx == 0)readyx += mapx;
if (readyy == 0)readyy += mapy;
if (map[readyx][readyy].map == '*' || readyx == 1 && readyy == 1 && mapf < mapx * mapy)
//一般第一行第一列不设为雷
{
continue;
}
map[readyx][readyy].map = '*';
for (j = 1; j < 9; j++)
{
if (map[readyx + movex[j]][readyy + movey[j]].map != '*' &&
readyx + movex[j] > 0 && readyx + movex[j] <= mapx &&
readyy + movey[j] > 0 && readyy + movey[j] <= mapy)
{
map[readyx + movex[j]][readyy + movey[j]].map++;
}
}
i--;
}
Sleep(300);
printf("地图准备完毕...\n");
Sleep(300);
// 调试
// for(i=1;i<=mapx;i++)
// {
// for(j=1;j<=mapy;j++)
// {
// printf("%c ",map[i][j].map);
// }
// printf("\n");
// }
// Sleep(10000);
system("cls");
}
void CreateMap()//创建地图
{
int i, j;
Colourxy(0, 15);
printf("\n");
for (i = 1; i <= mapx; i++)
{
for (j = 1; j < mapy; j++)
{
printf("# ");
}
if (mapy > 0)
{
printf("#\n");
}
}
Colourxy(0, 14);
Gotoxy(1, 2 * mapy + 9);
printf("扫雷\n");
Colourxy(0, 7);
Gotoxy(3, 2 * mapy + 2);
printf(" 用W.S.A.D控制 \n");
Gotoxy(4, 2 * mapy + 2);
printf(" 操作说明: \n");
Gotoxy(5, 2 * mapy + 2);
printf("1.打开指定行和列。\n");
Gotoxy(6, 2 * mapy + 2);
printf("2.给坐标插上旗子。\n");
Gotoxy(7, 2 * mapy + 2);
printf("3.试探坐标的周围。\n");
Gotoxy(8, 2 * mapy + 2);
printf("4.标记疑惑的坐标。\n");
Gotoxy(9, 2 * mapy + 2);
printf("5.退出当前的游戏。\n");
Colourxy(0, 6);
Gotoxy(1, 0);
printf("#");
Colourxy(15, 0);
}
void Help()//雷数
{
Colourxy(0, 7);
Gotoxy(2, 2 * mapy + 2);
printf(" 还有%d颗地雷。 \n", flat);
Colourxy(15, 0);
Gotoxy(gotox, gotoy * 2 - 2);
}
void Move()//移动
{
char ch;
while (!kbhit());
ch = getch();
switch (ch)
{
case 'w':
case 'W':
MoveOut(15);
if (gotox > 1)
{
gotox--;
}
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case 's':
case 'S':
MoveOut(15);
if (gotox < mapx)
{
gotox++;
}
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case 'a':
case 'A':
MoveOut(15);
if (gotoy > 1)
{
gotoy--;
}
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case 'd':
case 'D':
MoveOut(15);
if (gotoy < mapy)
{
gotoy++;
}
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case '1':
Open(gotox, gotoy);
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case '2':
if (map[gotox][gotoy].open == false)
{
if (map[gotox][gotoy].flat == false)
{
if (flat > 0)
{
map[gotox][gotoy].flat = true;
flat--;
}
}
else
{
map[gotox][gotoy].flat = false;
flat++;
}
}
MoveOut(6);
break;
case '3':
if (map[gotox][gotoy].open == true)
{
int i, j = 0;
for (i = 1; i < 9; i++)
{
if (map[gotox + movex[i]][gotoy + movey[i]].flat == true)
{
j++;
}
}
if (j == map[gotox][gotoy].map - '0')
{
for (i = 1; i < 9; i++)
{
if (map[gotox + movex[i]][gotoy + movey[i]].flat == false)
{
Open(gotox + movex[i], gotoy + movey[i]);
}
}
}
}
Gotoxy(gotox, gotoy * 2 - 2);
MoveOut(6);
break;
case '4':
if (map[gotox][gotoy].open == false)
{
if (map[gotox][gotoy].mark == false)
{
map[gotox][gotoy].mark = true;
}
else
{
map[gotox][gotoy].mark = false;
}
}
MoveOut(6);
break;
case '5':
Gotoxy(mapx + 2, 0);
printf("自动踩雷退出中...");
Sleep(500);
mine = 1;
break;
}
}
void MoveOut(int i)//输出
{
if (map[gotox][gotoy].open == true)
{
if (map[gotox][gotoy].map == '0')
{
Colourxy(0, i);
printf(" ");
}
else
{
Colourxy(colour[map[gotox][gotoy].map - '0'], i);
printf("%c", map[gotox][gotoy].map);
}
}
else if (map[gotox][gotoy].flat == true)
{
Colourxy(4, i);
printf("F");
}
else if (map[gotox][gotoy].mark == true)
{
Colourxy(5, i);
printf("?");
}
else
{
Colourxy(0, i);
printf("#");
}
Colourxy(15, 0);
}
void Open(int x, int y)//打开
{
if (map[x][y].map == '*')
{
mine = 1;
return;
}
if (mine || map[x][y].open == true || x<1 || x>mapx || y<1 || y>mapy)
{
return;
}
map[x][y].open = true;
Gotoxy(x, y * 2 - 2);
if (map[x][y].map == '0')
{
Colourxy(0, 15);
printf(" ");
}
else
{
Colourxy(colour[map[x][y].map - '0'], 15);
printf("%c", map[x][y].map);
}
Colourxy(15, 0);
open++;
if (map[x][y].flat == true)
{
map[x][y].flat = false;
flat++;
}
if (map[x][y].mark == true)
{
map[x][y].mark = false;
}
if (map[x][y].map != '0')
{
return;
}
int i;
for (i = 1; i < 9; i++)
{
if (x + movex[i] > 0 && x + movex[i] <= mapx
&& y + movey[i] > 0 && y + movey[i] <= mapy
&& map[x + movex[i]][y + movey[i]].open == false)
{
Open(x + movex[i], y + movey[i]);
}
}
}
void Again()
{
system("cls");
int i, j;
printf("\n");
for (i = 1; i <= mapx; i++)
{
for (j = 1; j < mapy; j++)
{
if (map[i][j].map == '*')
{
Colourxy(4, 15);
printf("*");
}
else if (map[i][j].map == '0')
{
Colourxy(0, 15);
printf(" ");
}
else
{
Colourxy(colour[map[i][j].map - '0'], 15);
printf("%c", map[i][j].map);
}
printf(" ");
}
if (mapy > 0)
{
if (map[i][mapy].map == '*')
{
Colourxy(4, 15);
printf("*");
}
else if (map[i][mapy].map == '0')
{
Colourxy(0, 15);
printf(" ");
}
else
{
Colourxy(colour[map[i][mapy].map - '0'], 15);
printf("%c", map[i][mapy].map);
}
}
printf("\n");
}
printf("\n");
if (mine == 1)
{
Colourxy(4, 0);
printf("踩到雷了,你输了\n");
}
else
{
Colourxy(14, 0);
printf("扫出所有雷,你赢了\n");
}
printf("\n");
Colourxy(0, 15);
printf("再玩一次\n");
Colourxy(15, 0);
printf("退出游戏\n\n");
Colourxy(0, 14);
printf("W.S.选择,否再玩一次?");
Colourxy(15, 0);
game = 1;
char ch = 0;
while (ch != '\r')
{
while (kbhit() == 0);
ch = getch();
switch (ch)
{
case 'w':
case 'W':
AgainSpeak(0);
game--;
if (game < 1)
{
game = 2;
}
AgainSpeak(1);
break;
case 's':
case 'S':
AgainSpeak(0);
game++;
if (game > 2)
{
game = 1;
}
AgainSpeak(1);
break;
}
}
if (game == 2)
{
game = 0;
}
system("cls");
}
void AgainSpeak(bool b)//选择的选项
{
Gotoxy(mapx + game + 3, 0);
if (b == true)
{
Colourxy(0, 15);
}
else
{
Colourxy(15, 0);
}
switch (game)
{
case 1:
printf("再玩一次");
break;
case 2:
printf("退出游戏");
break;
}
Colourxy(15, 0);
}
void Over()//声明
{
printf("声明:此是FDSO编写。\n");
printf("主编: ");
Colourxy(0, 15);
printf("朱夏夏");
Colourxy(15, 0);
printf("\n");
printf("内测: ");
Colourxy(0, 15);
printf("绿 曦");
Colourxy(15, 0);
printf("\n");
printf("时间:2024.6.15\n");
system("pause");
}
感谢大家的观看,请在评论区里提出宝贵的建议。
全部评论 (0)
还没有任何评论哟~
