#include<cstdio>
#include<iostream>
#include<queue>
#include<ctime>
#include<algorithm>
#include<string>
#include "windows.h"
using namespace std;
int dx[12] = {0,0,-1,1,1,1,-1,-1,2,2,0,0};
int dy[12] = {1,-1,0,0,-1,-1,1,1,0,0,2,2};
int n=0,m=0,eye=1,exp=20,door=0;
char mig[73][73];
bool vis[73][73];
int dis[71][71];
void all_look(int kx,int ky,int kkx,int kky,int kkkx,int kkky){
	for(int i=0;i<=n+1;i++){
		for(int j=0;j<=n+1;j++){if(i == kkkx && j == kkky) {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置蓝色
				printf("X ");
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
			}
			else if(i==kx && j==ky) {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色
				printf("@ ");
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
			}
			else if(i==kkx && j==kky) {
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);//设置绿色
				printf("S ");
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
			}
			else printf("%c ",mig[i][j]); 
		}
		printf("\n");
	}
}
bool check(int xxx,int yyy){
	if(xxx > n || yyy > n || xxx < 1 || yyy < 1) return false;
	if(mig[xxx][yyy] == '*') return false;
	if(dis[xxx][yyy] != -1) return false;
	return true;
}
void build_check(int x,int y){
	if(mig[x][y]=='*') return;
	if(mig[x][y]=='A') return;
	if(mig[x][y]=='0') return;
	if(mig[x][y]=='X') return;
	mig[x][y]='0';
	for(int i=0;i<4;i++){
		build_check(x+dx[i],y+dy[i]);
	}
}
int waymin(int x,int y,int ex,int ey){//这里采用广度优先搜索,否则会超时。 
	int mw=2;
	for(int i=0;i<4;i++){
		if(mig[x+dx[i]][y+dy[i]]=='0') mig[x+dx[i]][y+dy[i]]='+';
	}
	while(mw<5000){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(mig[i][j]=='+'){
					for(int k=0;k<4;k++){
						if(mig[i+dx[k]][j+dy[k]]=='0') mig[i+dx[k]][j+dy[k]]='#';
						else if(mig[i+dx[k]][j+dy[k]]=='X') return mw;
					}
				}
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				if(mig[i][j]=='#') mig[i][j]='+';
			}
		}
		mw++;
	}
	return -100000;
}
int show(int oo,int pp){
	mig[oo][pp] = 'O';
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++)
			printf("%c ",mig[i][j]);
		printf("\n");
	}
	return 0;
}


void look(int sx,int sy){
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
	if(mig[sx - 1][sy] == '*' || mig[sx - 1][sy] == 'A') printf("    ?\n");
	else printf("    %c\n",mig[sx - 2][sy]);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	printf("  %c %c %c\n",mig[sx - 1][sy - 1],mig[sx - 1][sy],mig[sx - 1][sy + 1]);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
	if(mig[sx][sy - 1] == '*' || mig[sx][sy - 1] == 'A') printf("? %c V %c ",mig[sx][sy - 1],mig[sx][sy + 1]);
	else printf("%c %c V %c ",mig[sx][sy - 2],mig[sx][sy - 1],mig[sx][sy + 1]);
	if(mig[sx][sy + 1] == '*' || mig[sx][sy + 1] == 'A') printf("?\n");
	else printf("%c\n",mig[sx][sy + 2]);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
	printf("  %c %c %c\n",mig[sx + 1][sy - 1],mig[sx + 1][sy],mig[sx + 1][sy + 1]);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
	if(mig[sx + 1][sy] == '*' || mig[sx + 1][sy] == 'A') printf("    ?\n");
	else printf("    %c\n",mig[sx + 2][sy]);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
}
bool x = false,y;
int main(){
//	开局 
	srand(time(NULL));
	y = false;
	eye = 1; 
	if(n==0){
		printf("欢迎来到迷宫游戏!\n你的视野长度为2格。\n请问你要多大的地图(最大70)?[输入0进入闯关模式]\n");
		scanf("%d",&n);
		if(n == 0) x = true;
	}	
	if(x) n=30,m=500;
	if(x){
		if(exp<door*40){
			printf("你输了,成绩:%d 最终分数:%d",door,exp);
			return 0;
		}
		else printf("第%d关,你的分数:%d,本关分数线:%d\n请问本关的视角是什么?(0:开眼,1:闭眼)\n",door+1,exp,(door+1)*40);
		scanf("%d",&eye);
		door++;
	}
	else {
		printf("请问你要放几个障碍?\n");
		scanf("%d",&m);
	}	
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
	for(int i = 0;i <= n + 1;i++) mig[0][i] = mig[n + 1][i] = mig[i][0] = mig[i][n + 1] = 'A';
//	设置障碍 
	int ax=1,ay=1,aax=1,aay=1,xxx,sx,sy; 
	mig[ax][ay]='*';
	mig[aax][aay]='-';
	do{
		for(int i = 1;i <= n;i++)
			for(int j = 1;j <= n;j++)
				mig[i][j] = '+';
		int a = rand() % n + 1;
		int b = rand() % n + 1;
		mig[a][b] = '*';
		for(int i = 2;i <= m;i++){
			int w = rand() % 11;
			if(w < 8){
				a += dx[w];
				b += dy[w];
				if(a > n || a < 1 || b > n || b < 1 || mig[a][b] == '*'){
					a -= dx[w];
					b -= dy[w];
					i--;
					continue;
				}
			}
			else{
				do{
					a = rand() % n + 1;
					b = rand() % n + 1;
				}while(mig[a][b] != '+');
			}
			mig[a][b] = '*';
		}
		do{
			ax = sx = rand() % n + 1;
			ay = sy = rand() % n + 1;
		}while(mig[ax][ay] != '+');
		mig[ax][ay] = 'O';
		build_check(ax,ay);
		do{
			aax = rand() % n + 1;
			aay = rand() % n + 1;
		}while(mig[aax][aay] != '0');
		//printf("%d %d %d %d\n",ax,ay,aax,aay);
		mig[aax][aay] = 'X';
		if(max(ax-aax,aax-ax)+max(ay-aay,aay-ay)>=n/2)
			xxx = waymin(ax,ay,aax,aay);
	}while (max(ax-aax,aax-ax)+max(ay-aay,aay-ay)<n/2 || xxx <= 5);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(mig[i][j]=='#' || mig[i][j]=='0') mig[i][j]='+';
		}
	}
//	正式开始  
	printf("开始游戏!\n");	
	int cnt = 0;
	while(ax != aax || ay != aay){
		printf("你在(%d,%d)\n终点在(%d,%d)\n",ax,ay,aax,aay);
		if(eye==0){
			all_look(ax,ay,sx,sy,aax,aay);
			y = true;
		}
		else if(eye==1) look(ax,ay);
		printf("w:上,s:下,a:左,d:右,e:退出。r:切换视角。sc:清屏。\n");
		string d;
		cin >> d;
		mig[ax][ay] = '-';
		char c = d[0];
		cnt++;
		if(c == 'e'){
			show(sx,sy);
			return 0;
		}
		else if(c == 'r') {
			eye=(eye+1)%2;	
			cnt--;
		}
		else if(d == "sc"){
			system("cls");
			cnt--;
		}
		else if(c == 'w' && ax > 1 && mig[ax - 1][ay] != '*' && mig[ax - 1][ay] != 'A') ax--;
		else if(c == 'a' && ay > 1 && mig[ax][ay - 1] != '*' && mig[ax][ay - 1] != 'A') ay--;
		else if(c == 's' && ax < n && mig[ax + 1][ay] != '*' && mig[ax + 1][ay] != 'A') ax++;
		else if(c == 'd' && ay < n && mig[ax][ay + 1] != '*' && mig[ax][ay + 1] != 'A') ay++;
		else{
			printf("无效操作!");
			cnt--;
			mig[ax][ay] = 'O';
			continue;
		}
		mig[ax][ay] = 'O';
	}
	all_look(ax,ay,sx,sy,aax,aay); 
	printf("你用了%d步\n最少%d步\n",cnt,xxx);
	if(x){
		printf("\n\n\n----------------------------------------------------------------------------\n你获得了%d分\n输入任意字母继续\n\n\n",max(45-cnt+xxx-15*y,0)); 
		exp+=max(45-cnt+xxx-15*y,0);
		string ssssss;
		cin >> ssssss; 
		system("cls");
		main();
	}
	return 0;
}