C++之警察抓小偷2.0

警察抓小偷更新啦!

本次更新优化了以下几点:

1、修改了小偷被楼房包围导致不能通关的问题

2、让地图变得真正随机

3、亿些细节优化

话不多说,请看代码:

#include<bits/stdc++.h> 
#include<conio.h>
#include<windows.h>
using namespace std;
struct point {
	int x, y;
}thf = { 6,6 };
int n = 1, X, Y;
char street[11][12][12];
int dx[4] = { 0,0,-1,1 };
int dy[4] = { 1,-1,0,0 };
bool vst[12][12];
bool CheckMap(int k) {
	//判断是否可以通过部署警力抓住小偷
	int cnt=0;
	for (int i = 0; i < 12; i++)
		for (int j = 0; j < 12; j++)
			vst[i][j] = 0;
	queue<point> q;
	q.push(thf);
	while (!q.empty()) {
		int thfx = q.front().x, thfy = q.front().y;
		q.pop();
		vst[thfx][thfy] = 1;
		for (int i = 0; i < 4; i++) {
			point nthf;
			nthf.x = thfx + dx[i];
			nthf.y = thfy + dy[i];
			if ( nthf.x>=1&&nthf.x<=11&&nthf.y>=1&&nthf.y<=11 && !vst[nthf.x][nthf.y] && street[k][nthf.x][nthf.y] != '#') q.push(nthf);
		}
	}
	for (int i = 1; i <= 11; i++) {
		if (vst[i][1])  cnt++;
		if (vst[i][11]) cnt++;
	}
	for (int j = 1; j <= 11; j++) {
		if (vst[1][j])  cnt++;
		if (vst[11][j]) cnt++;
	}
	if(cnt>=4) return 1;
	return 0;
}
void clearScreen() {
	system("cls");
}
void first() {//用随机数设置楼房 
	for (int i = 1; i <= 10; i++) {
		for (int j = 1; j <= 50; j++) {
			int x = rand() % 11 + 1;
			int y = rand() % 11 + 1;
			if (x == 6 && y == 6) {
				j--;
				continue;
			}
			if (street[i][x][y] != '#') {
				street[i][x][y] = '#';
			}
			else {
				j--;
			}
		}
		if (!CheckMap(i)) {
			for (int px = 1; px <= 11; px++) {
				for (int py = 1; py <= 11; py++) {
					street[i][px][py] = '.';
				}
			}
			i--;
			continue;
		}
	}
}
void printMap() {
	for (int px = 1; px <= 11; px++) {//输出地图 
		for (int py = 1; py <= 11; py++) {
			char tmp = street[n][px][py];
			if (tmp == '.') {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
			}
			if (tmp == '#') {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
			}
			if (tmp == '@') {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
			}
			if (tmp == '!') {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
			}
			cout << tmp << " ";
		}
		cout << "\n";
	}
}
void getHome() {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	cout << "请输入你的大本营的坐标:\n\n";
	int homex, homey;
	cin >> homex >> homey;
	while (street[n][homex][homey] == '#' || homex != 1 && homex != 11 && homey != 1 && homey != 11) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "大本营的坐标不能是楼房,而且必须在地图边上\n\n";
		cin >> homex >> homey;
	}
	street[n][homex][homey] = '@';
}
void initMap() {
	for (int i = 1; i <= 10; i++) {//地图初始化 
		for (int px = 1; px <= 11; px++) {
			for (int py = 1; py <= 11; py++) {
				if (street[i][px][py] != '#') {
					street[i][px][py] = '.';
				}
			}
		}
		street[i][6][6] = '!';
	}
}
void startGame() {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	cout << "游戏:警察抓小偷\n\n";
	Sleep(2000);
	cout << "作者:阳了个阳C++\n\n";
	Sleep(2000);
	cout << "进入游戏请按y\n\n";
	char key1 = _getch();
	while (key1 != (int)('y')) {
		cout << "进入游戏请按y\n\n";
		key1 = _getch();
	}
	clearScreen();
	cout << "你是一位警官\n\n";
	Sleep(1500);
	cout << "一天,你接到报案,在某街区发现一名小偷\n\n";
	Sleep(1500);
	cout << "你立刻带人赶往街区\n\n";
	Sleep(1500);
	cout << "该街区是一个11*11的地图\n\n";
	Sleep(2000);
	cout << "地图上有一些楼房\n\n";
	Sleep(2000);
	cout << "你可以选择地图边上的任意一个位置作为大本营\n\n";
	Sleep(2000);
	cout << "你可以向其他方格部署警力\n\n";
	Sleep(2000);
	cout << "但请注意,你想要部署警力的格子必须与已部署警力的格子相邻\n\n";
	Sleep(3000);
	cout << "小偷的初始位置会在地图的正中心\n\n";
	Sleep(2000);
	cout << "他每一步会移动到上下左右四个格子里的任意一格\n\n";
	Sleep(2000);
	cout << "如果小偷到达了地图的边界,则小偷获胜\n\n";
	Sleep(2000);
	cout << "如果警察抓住了小偷,则警察胜利\n\n";
	Sleep(2000);
	cout << "如果你准备好了,请输入start\n\n";
	string key2;
	cin >> key2;
	while (key2 != "start") {
		cout << "如果你准备好了,请输入start\n\n";
		cin >> key2;
	}
}
bool Arrange() {
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	cout << "请输入你要部署警力的坐标:\n\n";
	int dx, dy;
	cin >> dx >> dy;
	while (street[n][dx][dy - 1] != '@' && street[n][dx][dy + 1] != '@' && street[n][dx + 1][dy] != '@' && street[n][dx - 1][dy] != '@' || street[n][dx][dy] == '#') {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "你想要部署警力的格子必须与已部署警力的格子相邻,并且不能是楼房\n\n";
		cin >> dx >> dy;
	}
	if (dx == X && dy == Y) {
		return 1;
	}
	street[n][dx][dy] = '@';
	return 0;
}
void moveThief() {
	int rnd = rand() % 5 + 1;
	if (rnd == 1) {//判断小偷的移动
		if (street[n][X - 1][Y] == '.') {
			X -= 1;
			street[n][X][Y] = '!';
			street[n][X + 1][Y] = '.';
		}
		else {
			rnd += 1;
		}
	}
	if (rnd == 2) {//判断小偷的移动
		if (street[n][X + 1][Y] == '.') {
			X += 1;
			street[n][X][Y] = '!';
			street[n][X - 1][Y] = '.';
		}
		else {
			rnd += 1;
		}
	}
	if (rnd == 3) {//判断小偷的移动
		if (street[n][X][Y + 1] == '.') {
			Y += 1;
			street[n][X][Y] = '!';
			street[n][X][Y - 1] = '.';
		}
		else {
			rnd += 1;
		}
	}
	if (rnd == 4) {//判断小偷的移动
		if (street[n][X][Y - 1] == '.') {
			Y -= 1;
			street[n][X][Y] = '!';
			street[n][X][Y + 1] = '.';
		}
		else {
			rnd += 1;
		}
	}
	if (X == 1 || X == 11 || Y == 1 || Y == 11) {
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
		cout << "很遗憾!小偷逃脱了!\n\n";
		Sleep(1000);
		cout << "游戏结束";
		exit(0);
	}
}
int main() {
	srand(time(NULL));
	first();
	initMap();
	startGame();
	clearScreen();
	cout << "Initializing Map…";
	Sleep(3000);
	while (n <= 10) {
		clearScreen();
		X = 6, Y = 6;
		printMap();
		getHome();
		while (1) {
			clearScreen();
			printMap();
			if (Arrange()) {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),               FOREGROUND_INTENSITY | FOREGROUND_RED);
				cout << "小偷被你抓住了!恭喜你!\n\n";
				Sleep(1000);
				cout << "如果想要继续下一局,请按y\n\n";
				if (_getch() == 'y') break;
				else return 0;
			}
			moveThief();
		}
		n++;
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	cout << "恭喜你!你抓住了所有小偷!";
	return 0;
}

老规矩,喜欢的话就点个赞吧!

特别鸣谢:感谢C++小盆友提供的支持与帮助!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值