/* 11212.net
 * based on c++11
 * test version
 * 抄代码的死个令堂
 */
#include<bits/stdc++.h>
#include<windows.h>
#include<unistd.h>
#include<conio.h>

using namespace std;

#define cls system("cls")

const int D = 64, N = 16;
const int ver = 0, minloadver = 0;
const char vername[] = "test1.0";

#define SetColor(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x)
void colored(short x, short clr = 0){ // x = 1248, 1 : ss, 2 : sc, 4 : cs, 8 : cc;
	int y = 0;
	switch(x & 3){
		case 1: y |= BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY; break;
		case 2: y |= BACKGROUND_RED; break;
		case 3: y |= BACKGROUND_RED | BACKGROUND_INTENSITY; break;
	}
	switch(x >> 2){
		case 0: 
			y |= FOREGROUND_INTENSITY;
			if (clr) y |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
			break;
		case 1: y |= FOREGROUND_GREEN; break;
		case 2: y |= FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break;
		case 3: y |= FOREGROUND_GREEN | FOREGROUND_BLUE; break;
	}
	SetColor(y);
}

class board{
	public:
		short c[N+3][N+3], r[N+3][N+3];
		// c 是横向,r 是纵向 
		// 0 是空白,1 是常规路
		// 0 是空白,1 是根在上、左的特殊路,2 是根在下、右的特殊路,3 是两端都有根的路 
};
class plate{
	public:
		short n, playerx, playery, destix, destiy, playerrotate = 0, destirotate = 0;
		// n*n, 玩家当前坐标,终点坐标,玩家是否随板旋转,终点是否随板旋转 
		board ss, sc, cs, cc;
		// ss 是固定板固定路(黄,常规),sc 是固定板转动路(红,特殊)
		// cs 是转动板固定路(绿,特殊),cc 是转动板转动路(蓝,常规) 
	private:
		void normalroad(const board &b, short col[N + 3 << 2][N + 3 << 2], short x) const {
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j)
					if (b.c[i][j])
						for (int k = (j << 2) + 1;k <= (j << 2) + 5;++k)
							col[(i << 2) + 1][k] |= x;
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j)
					if (b.r[i][j])
						for (int k = (i << 2) + 1;k <= (i << 2) + 5;++k)
							col[k][(j << 2) + 1] |= x;
		}
		void spetialroad(const board &b, short col[N + 3 << 2][N + 3 << 2], short x) const {
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j)
					if (b.c[i][j]){
						if (b.c[i][j] & 1){
							col[i << 2][(j << 2) + 1] |= x;
							col[(i << 2) + 2][(j << 2) + 1] |= x;
							col[(i << 2) + 1][j << 2] |= x;
						}
						if (b.c[i][j] & 2){
							col[i << 2][(j << 2) + 5] |= x;
							col[(i << 2) + 2][(j << 2) + 5] |= x;
							col[(i << 2) + 1][(j << 2) + 6] |= x;
						}
						for (int k = (j << 2) + 1;k <= (j << 2) + 5;++k)
							col[(i << 2) + 1][k] |= x;
					}
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j)
					if (b.r[i][j]){
						if (b.r[i][j] & 1){
							col[(i << 2) + 1][(j << 2)] |= x;
							col[(i << 2) + 1][(j << 2) + 2] |= x;
							col[i << 2][(j << 2) + 1] |= x;
						}
						if (b.r[i][j] & 2){
							col[(i << 2) + 5][j << 2] |= x;
							col[(i << 2) + 5][(j << 2) + 2] |= x;
							col[(i << 2) + 6][(j << 2) + 1] |= x;
						}
						for (int k = (i << 2) + 1;k <= (i << 2) + 5;++k)
							col[k][(j << 2) + 1] |= x;
					}
		}
	public: 
		void singleplate() const {
			short bgcol[N + 3 << 2][N + 3 << 2] = {}, fgcol[N + 3 << 2][N + 3 << 2] = {};
			normalroad(ss, bgcol, 1);
			spetialroad(sc, bgcol, 2);
			spetialroad(cs, fgcol, 4);
			normalroad(cc, fgcol, 8);
			// outp
			for (int i = 0;i <= (n << 2) + 6;++i){
				for (int j = 0;j <= (n << 2) + 6;++j){
					colored(bgcol[i][j]);
					if (i % 4 == 1 && j % 4 == 1){
						int k = i / 4, l = j / 4;
						if (k == playerx && l == playery) 
							printf ("●");
						else {
							if (k == destix && l == destiy) printf ("○");
							else if (k >= 1 && k <= n && l >= 1 && l <= n) printf ("┼ ");
							else printf ("  ");
						}
					}
					else printf ("  ");
				}
				colored(0, 1);
				printf ("  ");
				for (int j = 0;j <= (n << 2) + 6;++j){
					colored(fgcol[i][j]);
					if (i % 4 == 1 && j % 4 == 1){
						int k = i / 4, l = j / 4;
						if (k == playerx && l == playery) 
							printf ("●");
						else {
							if (k == destix && l == destiy) printf ("○");
							else if (k >= 1 && k <= n && l >= 1 && l <= n) printf ("┼ ");
							else printf ("  ");
						}
					}
					else {
						if (fgcol[i][j] >> 2){
							if (i % 4 == 1) printf ("──");
							else printf ("│ ");
						}
						else printf ("  ");
					}
				}
				colored(0, 1);
				printf ("\n");
			}
		}
		void multiplate() const {
			short col[N + 3 << 2][N + 3 << 2] = {};
			normalroad(ss, col, 1);
			spetialroad(sc, col, 2);
			spetialroad(cs, col, 4);
			normalroad(cc, col, 8);
			// outp
			for (int i = 0;i <= (n << 2) + 6;++i){
				for (int j = 0;j <= (n << 2) + 6;++j){
					colored(col[i][j]);
					if (i % 4 == 1 && j % 4 == 1){
						int k = i / 4, l = j / 4;
						if (k == playerx && l == playery) 
							printf ("●");
						else {
							if (k == destix && l == destiy) printf ("○");
							else if (k >= 1 && k <= n && l >= 1 && l <= n) printf ("┼ ");
							else printf ("  ");
						}
					}
					else {
						if (col[i][j] >> 2){
							if (i % 4 == 1) printf ("──");
							else printf ("│ ");
						}
						else printf ("  ");
					}
				}
				colored(0, 1);
				printf ("\n");
			}
		}
		bool moveup(){
			if (playerx-1 >= 1 && (ss.r[playerx-1][playery] || sc.r[playerx-1][playery] || cs.r[playerx-1][playery] || cc.r[playerx-1][playery])){
				--playerx;
				return 1;
			}
			return 0;
		}
		bool movedown(){
			if (playerx+1 <= n && (ss.r[playerx][playery] || sc.r[playerx][playery] || cs.r[playerx][playery] || cc.r[playerx][playery])){
				++playerx;
				return 1;
			}
			return 0;
		}
		bool moveleft(){
			if (playery-1 >= 1 && (ss.c[playerx][playery-1] || sc.c[playerx][playery-1] || cs.c[playerx][playery-1] || cc.c[playerx][playery-1])){
				--playery;
				return 1;
			}
			return 0;
		}
		bool moveright(){
			if (playery+1 <= n && (ss.c[playerx][playery] || sc.c[playerx][playery] || cs.c[playerx][playery] || cc.c[playerx][playery])){
				++playery;
				return 1;
			}
			return 0;
		}
		void leftrotate(){
			plate p;
			if (playerrotate){
				p.playerx = n + 1 - playery;
				p.playery = playerx;
				playerx = p.playerx;
				playery = p.playery;
			}
			if (destirotate){
				p.destix = n + 1 - destiy;
				p.destiy = destix;
				destix = p.destix;
				destiy = p.destiy; 
			}
			// sc
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j){
					if (sc.r[i][j] & 1) p.sc.c[i][j] |= 1;
					if (j < n && sc.r[i-1][j+1] & 2) p.sc.c[i][j] |= 2;
				}
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j){
					if (sc.c[i][j-1] & 2) p.sc.r[i][j] |= 1;
					if (i < n && sc.c[i+1][j] & 1) p.sc.r[i][j] |= 2;
				}
			sc = p.sc;
			// cs
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j){
					if (j && cs.c[j][n+1-i] & 1) p.cs.c[i][j] |= 1;
					if (j < n && cs.c[j+1][n-i] & 2) p.cs.c[i][j] |= 2;
				}
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j){
					if (i && cs.r[j][n+1-i] & 1) p.cs.r[i][j] |= 1;
					if (i < n && cs.r[j-1][n-i] & 2) p.cs.r[i][j] |= 2;
				}
			cs = p.cs;
			// cc
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j)
					p.cc.r[i][j] = cc.c[j][n - i];
			for (int i = 1;i <= n;++i)  
				for (int j = 0;j <= n;++j)
					p.cc.c[i][j] = cc.r[j][n + 1 - i];
			cc = p.cc;
		}
		void rightrotate(){
			plate p;
			if (playerrotate){
				p.playerx = playery;
				p.playery = n + 1 - playerx; 
				playerx = p.playerx;
				playery = p.playery;
			}
			if (destirotate){
				p.destix = destiy;
				p.destiy = n + 1 - destix;
				destix = p.destix;
				destiy = p.destiy;  
			}
			// sc
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j){
					if (sc.r[i-1][j] & 2) p.sc.c[i][j] |= 1;
					if (j < n && sc.r[i][j+1] & 1) p.sc.c[i][j] |= 2;
				}
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j){
					if (sc.c[i][j] & 1) p.sc.r[i][j] |= 1;
					if (i < n && sc.c[i+1][j-1] & 2) p.sc.r[i][j] |= 2;
				}
			sc = p.sc;
			// cs
			for (int i = 1;i <= n;++i)
				for (int j = 0;j <= n;++j){
					if (j && cs.c[n+1-j][i] & 1) p.cs.c[i][j] |= 1;
					if (j < n && cs.c[n-j][i-1] & 2) p.cs.c[i][j] |= 2;
				}
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j){
					if (i && cs.r[n+1-j][i] & 1) p.cs.r[i][j] |= 1;
					if (i < n && cs.r[n-j][i+1] & 2) p.cs.r[i][j] |= 2;
				}
			cs = p.cs;
			// cc
			for (int i = 0;i <= n;++i)
				for (int j = 1;j <= n;++j)
					p.cc.r[i][j] = cc.c[n + 1 - j][i];
			for (int i = 1;i <= n;++i)  
				for (int j = 0;j <= n;++j)
					p.cc.c[i][j] = cc.r[n - j][i];
			cc = p.cc;
		}
}plateA;

short showboard = 1, mode = 0;
// showboard = 1 展示一个盘面,2 展示两个盘面
// mode = 0 主页,1 闯关,2 自创, 9 关于我们 

void mainpage(){
	cls;
	printf ("旋转迷宫 %s\n", vername);
	printf ("按数字键进入对应模式\n");
	printf ("按 esc 退出游戏\n");
	printf ("1 闯关模式\n");
	printf ("2 自创模式\n");
	printf ("9 关于我们\n");
	char ch = getch();
	if (ch == '1') mode = 1;
	else if (ch == '2') mode = 2;
	else if (ch == '9') mode = 9;
	else if (ch == 27) exit(0);
}
void about_us(){
	cls;
	printf ("旋转迷宫 %s\n", vername);
	printf ("作者(团队):a3\n");
	printf ("灵感来源:11212.net\n");
	printf ("感谢游玩!\n\n");
	printf ("按任意键继续\n");
	char ch = getch();
	mode = 0;
}

void customeroutput(){
	if (showboard == 1) plateA.multiplate();
	else plateA.singleplate();
	printf ("按 ctrl + S 导出,按 ctrl + O 导入");
	printf ("当前棋盘大小:%hd\n", plateA.n);
	printf ("玩家转动规则: %d\n", plateA.playerrotate);
	printf ("终点转动规则: %d\n\n", plateA.destirotate);
	printf ("T 玩家,Y 终点,U 黄色道路,I 红色道路,O 绿色道路,P 蓝色道路\n");
	printf ("1, 2 选择是否分盘\n"); 
	printf ("W, S, A, D 四向移动,道路 Q, E 左右旋转\n");
	printf ("按 enter 键放下,按 ctrl + enter 键删除\n");
	printf ("按 esc 退出");
}
void customer(){
	cls;
	customeroutput();
	while (true){
		char ch = tolower(getch());
		if (ch == 'w'){
			plateA.moveup();
		}
		if (ch == 's'){
			plateA.movedown();
		}
		if (ch == 'a'){
			plateA.moveleft();
		}
		if (ch == 'd'){
			plateA.moveright();
		}
		if (ch == 'q'){
			plateA.leftrotate();
		}
		if (ch == 'e'){
			plateA.rightrotate();
		}
		if (ch == '1'){
			showboard = 1;
		}
		if (ch == '2'){
			showboard = 2;
		}
		if (ch == 27){
			break;
		}
		cls;
		customeroutput();
	}
}
int main(){
	system(((string)"title 旋转迷宫 " + (string)vername).c_str()); 
	plateA.n = 3;
	plateA.playerx = plateA.playery = 1;
	plateA.destix = plateA.destiy = 3;
	while (true){
		if (mode == 0)
			mainpage();
		else if (mode == 1){
			
		}
		else if (mode == 2)
			customer();
		else if (mode == 9)
			about_us();
	}
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define elif else if
void Main(); 
void Start();
void Editor();
int main(){
	Main();
	return 0;
}
void Main(){
	printf ("按下数字键进入对应界面\n"); 
	printf ("1 开始打歌(并没有歌)\n");
	printf ("2 写谱\n");
	printf ("3 设置(修改按键、判定、偏好)\n");
	printf ("4 退出\n");
	while (ch == getch()){ 
		if (ch == 1) {
			Start();
			break;
		} 
		elif (ch == 2) {
			Editor();
			break;
		} 
		elif (ch == 3) {
			Settings();
			break;
		} 
		elif (ch == 4) {
			exit(0);
		} 
	} 
}