alt

bug一堆,勿介

//by JesCaim
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
#include <cstring>
using namespace std;
typedef long long ll;
#define M 32
#define random(x) rand()%(x)
char ches[2 * M + 10][M + 10];
char hid[2 * M + 10][M + 10];
bool vis[2 * M + 10][M + 10];
int r, c;
int num;
int cnt = 0;

int cal(char a[][M + 10], int i, int j) {
	int cnt = 0;
	if (a[i + 1][j] == '*') cnt++;
	if (a[i - 1][j] == '*') cnt++;
	if (a[i][j + 1] == '*') cnt++;
	if (a[i][j - 1] == '*') cnt++;
	if (a[i + 1][j + 1] == '*') cnt++;
	if (a[i + 1][j - 1] == '*') cnt++;
	if (a[i - 1][j + 1] == '*') cnt++;
	if (a[i - 1][j - 1] == '*') cnt++;
	return cnt;
}
char tras(int n) {
	return '0' + n;
}

void print(char a[][M + 10]) {
	for (int i = 0; i <= r; i++) {
		for (int j = 0; j <= c; j++) {
			cout << a[i][j];
		}
		cout << endl;
	}
	cout << endl;
}
void print_mine() {
	for (int i = 0; i <= r; i++) {
		for (int j = 0; j <= c; j++) {
			if (ches[i][j] == '*') cout << '*';
			else cout << hid[i][j];
		}
		cout << endl;
	}
}
void dfs(int i, int j) {		//二维深搜
	if (vis[i][j]) return;
	else if ((i<1 || i>r) || (j<1 || j>r)) return;
	else if (ches[i][j] == '*') return;
	else if (hid[i][j] == '@') return;
	else if (ches[i][j] >= '0' && ches[i][j] <= '9') {
		vis[i][j] = true;
		hid[i][j] = ches[i][j];
		return;
	}
	else {
		vis[i][j] = true;
		hid[i][j] = ches[i][j];
		dfs(i + 1, j);
		dfs(i - 1, j);
		dfs(i, j + 1);
		dfs(i, j - 1);
		dfs(i + 1, j + 1);
		dfs(i + 1, j - 1);
		dfs(i - 1, j + 1);
		dfs(i - 1, j - 1);
	}
}
bool isEmpty(char a[][M + 10]) {
	int ct = 0;
	for (int i = 1; i <= r; i++)
		for (int j = 1; j <= c; j++)
			if (a[i][j] != '-') ct++;
	if (ct == r * c) return true;
	else return false;
}
void done() {		//自动标记所有剩余格并结算
	for (int i = 1; i <= r; i++)
		for (int j = 1; j <= c; j++)
			if (hid[i][j] == '-') hid[i][j] = '@';
}

int main() {
	printf("/**************说明**************/\n");
	printf("首先输入尺寸宽*高,例:16 16 并回车\n");
	printf("然后输入埋设雷的数量,例:40 并回车\n");
	printf("游戏中有三条指令:\n");
	printf("例:click 3 2并回车,指点击第3行第2列格子\n");
	printf("例:sign 3 2并回车,指标记第3行第2列格子为雷,标记后显示为@\n");
	printf("例:done并回车,指标记剩余所有未显露的格子并结算,游戏结束\n\n\n\n");
	srand((int)time(0));		//随机种子

	ches[0][0] = ' '; hid[0][0] = ' ';	//边缘绘制
	for (int i = 1; i <= 64; i++) {
		if (i % 5 == 1) ches[0][i] = 'A' + i / 5;
		else ches[0][i] = ' ';
	}
	for (int i = 1; i <= 64; i++) {
		if (i % 5 == 1) ches[i][0] = 'A' + i / 5;
		else ches[i][0] = ' ';
	}
	for (int i = 1; i <= 64; i++) {
		if (i % 5 == 1) hid[0][i] = 'A' + i / 5;
		else hid[0][i] = ' ';
	}
	for (int i = 1; i <= 64; i++) {
		if (i % 5 == 1) hid[i][0] = 'A' + i / 5;
		else hid[i][0] = ' ';
	}

	printf("Enter the size:(MAX 32*32)\n");
	cin >> c >> r;				//输入尺寸
	printf("Enter the number of mine:(MAX 1000,建议数量为size的1/10)\n");
	cin >> num;		//输入地雷数量 
	if (num >= r * c) {
		printf("Error_number!\n");
		return 0;
	}

	int tmp = num; while (tmp > 0) {		//随机设置雷 
		for (int i = 1; i <= r; i++) {
			for (int j = 1; j <= c; j++) {
				if (((random(c) + 1) == 2) && (ches[i][j] != '*') & tmp != 0) {
					ches[i][j] = '*';
					tmp--;
				}
				else if (ches[i][j] != '*') ches[i][j] = '.';
				if (tmp == 0) continue;
			}
		}
	}

	for (int i = 1; i <= r; i++) {			//设置数字 
		for (int j = 1; j <= c; j++) {
			if (cal(ches, i, j) != 0 && ches[i][j] != '*') ches[i][j] = tras(cal(ches, i, j));
		}
	}

	for (int i = 1; i <= r; i++)			//绘制隐藏面
		for (int j = 1; j <= c; j++) {
			hid[i][j] = '-';
		}

	//print(ches);

	bool temp = true;
	for (int i = 1; i <= r; i++)			//开始时打开一块区域
		for (int j = 1; j <= c; j++) {
			if (temp && ches[i][j] == '.') {
				temp = false;
				memset(vis, false, sizeof(vis));
				dfs(i, j);
			}
		}

	while (1) {

		if (isEmpty(hid)) {					//全部显露后开始结算
			for (int i = 1; i <= r; i++) {
				for (int j = 1; j <= c; j++) {
					if (ches[i][j] == '*') {
						if (hid[i][j] != '@') {
							print_mine();
							printf("---------------------------------------------------------------\n");
							printf("*****You Lose!*****\n");
							system("pause");
							return 0;
						}
					}
					else {
						if (hid[i][j] == '@') {
							print_mine();
							printf("---------------------------------------------------------------\n");
							printf("*****You Lose!*****\n");
							system("pause");
							return 0;
						}
					}
				}
			}
			print(hid);
			printf("---------------------------------------------------------------\n");
			printf("\n*****YOU WIN!*****\n");
			system("pause");
			return 0;
		}

		printf("---------------------------------------------------------------\n");
		printf("\n********剩余:%d********\n\n",num-cnt);
		print(hid);
		printf("点击:click r c\n");
		printf("标记雷:sign r c\n");
		printf("标记所有剩余格:done\n");
		printf("Please enter your command:\n");
		string cmd; int row, col;

		cin >> cmd;
		if (cmd == "done") {
			done();
			continue;
		}
		else {
			cin >> row >> col;
			if (cmd == "click") {
				if (hid[row][col] != '-') {			//无效点击已标记或已显露部分,跳过
					printf("Invalid click!\n");
					continue;
				}
				else if (ches[row][col] == '*') {	//踩雷,展示剩余雷,游戏结束
					print_mine();
					printf("---------------------------------------------------------------\n");
					printf("*****You Lose!*****\n");
					system("pause");
					return 0;
				}
				else {								//非踩雷,深搜
					memset(vis, false, sizeof(vis));
					dfs(row, col);
				}
			}
			else if (cmd == "sign") {			//标记地雷
				hid[row][col] = '@';
				cnt++;
			}
			else
				printf("Error_command!\n");
		}

	}
	system("pause");
	return 0;
}