ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

课程设计扫雷

2021-05-19 13:02:17  阅读:131  来源: 互联网

标签:map 课程设计 handle floatx floaty && printf 扫雷


首先第一步:随机埋雷, 定义一个随机埋雷的对象,循环,取得一个整数范围的数量(0- 格子的数)如果这个格子有地雷为真,那么循环+1
第二步:计算每个格子周边的格子的数量 用循环所有格子,其次在用一个cell类型的数组,并在周围格子的占内存中查找来存放当前方格周边所有的方格 并用int unm来记录 (传一个对象给我,然后统计当前的地雷)如果在周围格子中发现了地雷,记录下来并将值传给cell数组
第三步:定义一个周边格子的的数组类将当前格子传给它。 先计算左右、上下、四个角,并返回一个值,到第二步。
第四步:定义打开格子的三种情况:一是有雷,二是空的,三,将格子周边的地雷数显示到这个格子上。

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include
#include<ctype.h>
#define A 17 //地图的高
#define B 17 //地图的宽
#define C 10 //雷的总数
using namespace std;

//全局变量
DWORD a, b;//DWORD=double word
char map[A][B], news, spare;//
int BoomTotalNum, floatx, floaty, flag[A][B], flagnum, mode, slect[A][B], game;//定义变量

//颜色属性
const WORD FORE_BLUE = FOREGROUND_BLUE; //蓝色文本属性
const WORD FORE_GREEN = FOREGROUND_GREEN; //绿色文本属性
const WORD FORE_RED = FOREGROUND_RED; //红色文本属性

//开垦地图结构体
struct node {//struct inode──字符设备驱动相关的重要结构介绍
int x;
int y;//定义整型变量
};
queue dui;//queue列、node节点

//打印位置
void position(int x, int y) {//对应位置
COORD pos = { x,y };
HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);//传递出对应位置信息
SetConsoleCursorPosition(Out, pos);
}

//隐藏光标
void Hide() {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}

//初始化
void Beginning() {
while (!dui.empty()) {
dui.pop();
}
game = 1;
//BoomTotalNum=C;
floatx = A / 2;
floaty = B / 2;
flagnum = 0;
BoomTotalNum = C;
mode = 0;
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
int x, y;
srand((unsigned)time(0));
for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) {
map[i][j] = ’ ';
flag[i][j] = 0;
slect[i][j] = 0;
}
while (BoomTotalNum) {
x = rand() % A;
y = rand() % B;
if (map[x][y] == ’ ') {
map[x][y] = ‘@’;
BoomTotalNum–;
}
}
SetConsoleTextAttribute(handle_out, FORE_GREEN);
for (int i = 0; i < A; i++) {
for (int j = 0; j < B; j++) printf(“█”);
printf("\n");
}
position(floaty * 2, floatx);
SetConsoleTextAttribute(handle_out, FORE_RED);
printf(“”); //光标位置
position(44, 9);
printf(“扫雷模式”);
position(44, 5);
printf("剩余雷数:%d ", C - flagnum);
SetConsoleTextAttribute(handle_out, FORE_GREEN);
position(5, 22);
printf(“按“空格”切换模式”);
position(5, 23);
printf(“按“Enter”确认”);
position(5, 24);
printf(“按“方向键”选择方块”);

}

//打印地图的一块儿
void Lump(int xx, int yy) {
switch (map[xx][yy]) {
case ‘1’: printf(“①”); break; //周围雷的数量(下同)
case ‘2’: printf(“②”); break;
case ‘3’: printf(“③”); break;
case ‘4’: printf(“④”); break;
case ‘5’: printf(“⑤”); break;
case ‘6’: printf(“⑥”); break;
case ‘7’: printf(“⑦”); break;
case ‘8’: printf(“⑧”); break;
case ’ ':
if (xx == floatx && yy == floaty) {
if (flag[xx][yy] == 0) {
if (mode % 2 == 0) printf(“”);
else printf(“”);
}
else printf(“”);
}
else {
if (flag[xx][yy] == 0) printf(“█”);
else printf(“”);
}
break;
case ‘@’:
if (xx == floatx && yy == floaty) {
if (flag[xx][yy] == 0) {
if (mode % 2 == 0) printf(“”);
else printf(“”);
}
else printf(“”);
}
else {
if (flag[xx][yy] == 0) printf(“█”);
else printf(“”);
}
break;
case ‘x’: if (floatx == xx && floaty == yy) printf(“”); else printf(" "); break; //已经挖开的空白
}
}

//移动光标
void Move() {
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
int xxx, yyy;
xxx = floatx;
yyy = floaty;
switch (news) {
case 72: floatx–; break; //上
case 80: floatx++; break; //下
case 75: floaty–; break; //左
case 77: floaty++; break; //右
}
if (floatx == -1) floatx = A - 1; floatx %= A; //两端穿模处理
if (floaty == -1) floaty = B - 1; floaty %= B;

position(yyy * 2, xxx);
SetConsoleTextAttribute(handle_out, FORE_GREEN);
Lump(xxx, yyy);	//删除原位置

if (map[floatx][floaty] == 'x') {
	position(floaty * 2, floatx);
	printf("  ");
}

position(floaty * 2, floatx);
SetConsoleTextAttribute(handle_out, FORE_BLUE);
Lump(floatx, floaty);	//更新新位置 

}

//插旗和排雷模式切换
void Mode() {
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息
mode++;
SetConsoleTextAttribute(handle_out, FORE_BLUE);
position(floaty * 2, floatx);
if (mode % 2 == 0) printf(“”);
else printf(“”);

position(44, 9);
if (mode % 2 == 0) {
	SetConsoleTextAttribute(handle_out, FORE_BLUE);
	printf("扫雷模式");
}
else {
	SetConsoleTextAttribute(handle_out, FORE_RED);
	printf("插旗模式");
}

}

//该点周围地雷数
int Boomnum(int xx, int yy) {//利用if语句进行判断
int num = 0;
if ((xx - 1 >= 0) && (yy - 1 >= 0) && (map[xx - 1][yy - 1] == ‘@’)) num++;
if ((xx - 1 >= 0) && (yy + 0 >= 0) && (map[xx - 1][yy] == ‘@’)) num++;
if ((xx - 1 >= 0) && (yy + 1 < B) && (map[xx - 1][yy + 1] == ‘@’)) num++;
if ((xx + 0 >= 0) && (yy - 1 >= 0) && (map[xx][yy - 1] == ‘@’)) num++;
if ((xx + 0 >= 0) && (yy + 1 < B) && (map[xx][yy + 1] == ‘@’)) num++;
if ((xx + 1 < A) && (yy - 1 >= 0) && (map[xx + 1][yy - 1] == ‘@’)) num++;
if ((xx + 1 < A) && (yy + 0 >= 0) && (map[xx + 1][yy] == ‘@’)) num++;
if ((xx + 1 < A) && (yy + 1 < B) && (map[xx + 1][yy + 1] == ‘@’)) num++;
return num;
}

//更新地图
void Open() {
node c;
node d;
while (!dui.empty()) {
dui.pop();
}
c.x = floatx;
c.y = floaty;
dui.push©;
slect[c.x][c.y] = 1;
while (!dui.empty()) {
c = dui.front();
dui.pop();
if (Boomnum(c.x, c.y) != 0) {
map[c.x][c.y] = (Boomnum(c.x, c.y) + 48);
continue;
}
else {
map[c.x][c.y] = ‘x’;
if ((c.x - 1 >= 0) && (c.y - 1 >= 0) && (map[c.x - 1][c.y - 1] == ’ ') && (slect[c.x - 1][c.y - 1] == 0)) {
d.x = c.x - 1;
d.y = c.y - 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x - 1 >= 0) && (c.y - 0 >= 0) && (map[c.x - 1][c.y] == ’ ') && (slect[c.x - 1][c.y] == 0)) {
d.x = c.x - 1;
d.y = c.y - 0;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x - 1 >= 0) && (c.y + 1 < B) && (map[c.x - 1][c.y + 1] == ’ ') && (slect[c.x - 1][c.y + 1] == 0)) {
d.x = c.x - 1;
d.y = c.y + 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x - 0 >= 0) && (c.y - 1 >= 0) && (map[c.x][c.y - 1] == ’ ') && (slect[c.x][c.y - 1] == 0)) {
d.x = c.x - 0;
d.y = c.y - 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x - 0 >= 0) && (c.y + 1 < B) && (map[c.x][c.y + 1] == ’ ') && (slect[c.x][c.y + 1] == 0)) {
d.x = c.x - 0;
d.y = c.y + 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x + 1 < A) && (c.y - 1 >= 0) && (map[c.x + 1][c.y - 1] == ’ ') && (slect[c.x + 1][c.y - 1] == 0)) {
d.x = c.x + 1;
d.y = c.y - 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x + 1 < A) && (c.y - 0 >= 0) && (map[c.x + 1][c.y] == ’ ') && (slect[c.x + 1][c.y] == 0)) {
d.x = c.x + 1;
d.y = c.y - 0;
dui.push(d);
slect[d.x][d.y] = 1;
}
if ((c.x + 1 < A) && (c.y + 1 < B) && (map[c.x + 1][c.y + 1] == ’ ') && (slect[c.x + 1][c.y + 1] == 0)) {
d.x = c.x + 1;
d.y = c.y + 1;
dui.push(d);
slect[d.x][d.y] = 1;
}
}
}
}

int main() {

Relife: //重玩处
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE); //获得标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
GetConsoleScreenBufferInfo(handle_out, &csbi); //获得窗口缓冲区信息

Hide();		//隐藏光标
Beginning();//初始化地图
a = GetTickCount();
while (1) {
	if (_kbhit() != 0) {
		spare = _getch();

		//按其他
		if ((spare != (-32)) && (spare != 13) && (spare != ' ')) continue;//跳过 

		//按Enter
		if (spare == 13) {	//确认 
			//排雷
			if (mode % 2 == 0) {
				if (map[floatx][floaty] == '@' && flag[floatx][floaty] == 0) {
					break;	//触雷
					game = 0;
				}

				if (flag[floatx][floaty] == 1) continue;	//有旗跳过
				Open();
				position(0, 0);
				SetConsoleTextAttribute(handle_out, FORE_GREEN);
				for (int i = 0; i < A; i++) {
					for (int j = 0; j < B; j++) Lump(i, j);
					printf("\n");
				}
				position(floaty * 2, floatx);
				SetConsoleTextAttribute(handle_out, FORE_BLUE);
				Lump(floatx, floaty);
			}

			//插拔旗
			else {

				//不能插旗的地方
				if (map[floatx][floaty] == 'x' || (map[floatx][floaty] > '0' && map[floatx][floaty] < '9'))
					continue;	//跳过

				//插旗
				if (flag[floatx][floaty] == 0) {
					flagnum++;
					flag[floatx][floaty] = 1;
					position(floaty * 2, floatx);
					SetConsoleTextAttribute(handle_out, FORE_BLUE);
					Lump(floatx, floaty);
				}

				//拔旗 
				else {
					flagnum--;
					flag[floatx][floaty] = 0;
					position(floaty * 2, floatx);
					SetConsoleTextAttribute(handle_out, FORE_BLUE);
					Lump(floatx, floaty);
				}
			}
		}

		//按空格
		if (spare == ' ') Mode();	//切换模式 

		//按方向键 
		if (spare == -32) {
			news = _getch();
			Move();	//移动光标
		}
		for (int i = 0; i < A; i++) for (int j = 0; j < B; j++) if (map[i][j] == 'x' || (map[i][j] > '0' && map[i][j] < '9')) game++;
		if (game == A * B - C + 1) break;
		else game = 1;
		SetConsoleTextAttribute(handle_out, FORE_RED);
		position(44, 5);
		printf("剩余雷数:%d ", C - flagnum);
	}
	else Sleep(10);
	b = GetTickCount64();
	SetConsoleTextAttribute(handle_out, FORE_RED);
	position(44, 7);
	printf("用时:");	//用时 
	if ((b - a) / 60000 < 10) printf("0");
	printf("%d:", (b - a) / 60000);
	if (((b - a) / 1000) % 60 < 10) printf("0");
	printf("%d:", ((b - a) / 1000) % 60);
	if (((b - a) / 10) % 100 < 10) printf("0");
	printf("%d", ((b - a) / 10) % 100);
}
SetConsoleTextAttribute(handle_out, FORE_RED);
position(5, 5);
if (game == 1) printf("游戏结束!");
else printf("恭喜通关!");
position(5, 8);
printf("任意键重玩");
scanf_s("%c %c", &spare, &spare);
system("cls");
position(0, 0);
goto Relife;

}

标签:map,课程设计,handle,floatx,floaty,&&,printf,扫雷
来源: https://blog.csdn.net/zszgzszg/article/details/117024527

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有