
#include <stdio.h>
#include <windows.h>
#include <process.h>

int y_x[19][54];
int player_x = 24;		//0(1) 〜 53(54)
int player_y = 10;		//0(1) 〜 18(19)
int enemy_x = 6;
int enemy_y = 2;
unsigned short count = 0;
HANDLE hOut;

void input_data(void);
void output_data(void);
void move_player(int);
void move_enemy(void);
int con_move(int);
int con_move_enemy(int);

int main()
{
	COORD coset;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	input_data();
	output_data();
	coset.X = player_x;
	coset.Y = player_y;
	SetConsoleCursorPosition(hOut, coset);
	puts("●");
	coset.X = enemy_x;
	coset.Y = enemy_y;
	SetConsoleCursorPosition(hOut, coset);
	puts("◎");

	while(1) {
		if(kbhit())
			move_player(getch());
		
		move_enemy();
		Sleep(10);
	}

	return 0;
}

void input_data()
{
	FILE *fp;
	int i, j;

	fp = fopen("test.txt", "r");
	if(fp == NULL)
		exit(-1);

	for(i = 0; i < 19; i++) {
		for(j = 0; j < 54; j++) {
			if((y_x[i][j] = fgetc(fp)) == ' ')
				y_x[i][j] = 0;
		}
	}
}

void output_data(void)
{
	int i, j;
	COORD coset;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	for(i = 0; i < 19; i++) {
		for(j = 0; j < 54; j++) {
			coset.Y = i;
			coset.X = j;
			SetConsoleCursorPosition(hOut, coset);
			if(y_x[i][j] != 0)
				printf("%c\n", y_x[i][j]);
		}
	}
}
void move_player(int a_val)
{
	COORD coset;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	switch (a_val) {
		case 0x48:			//  ↑ は16進数値で 48 という値を返す
			if(con_move(a_val) == 0)
				return;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("  ");
			player_y -= 1;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("●");
			return;
		case 0x50:			//  ↓ は16進数値で 50 という値を返す
			if(con_move(a_val) == 0)
				return;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("  ");
			player_y += 1;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("●");
			return;
		case 0x4B:			//  ← は16進数値で 4B という値を返す
			if(con_move(a_val) == 0)
				return;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("  ");
			player_x -= 2;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("●");
			return;
		case 0x4d:			//  → は16進数値で 4D という値を返す
			if(con_move(a_val) == 0)
				return;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("  ");
			player_x += 2;
			coset.X = player_x;
			coset.Y = player_y;
			SetConsoleCursorPosition(hOut, coset);
			puts("●");
			return;
	}
}

void move_enemy()
{
	int i;
	COORD coset;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	if(((enemy_x - 18) <= player_x && (enemy_x + 18) >= player_x) && ((enemy_y - 9) <= player_y && (enemy_y + 9) >= player_y)) {
		if(kbhit()) 
			move_player(getch());
		else {
			for(i = 0; i < 13; i++) {
				if(kbhit()) 
					move_player(getch());
				Sleep(10);
			}
		}

		if(player_x < enemy_x) {
			if(kbhit()) 
				move_player(getch());
			if(player_y >= enemy_y) {
				if(kbhit()) 
					move_player(getch());
				switch(count) {
					case 0:
						if(con_move_enemy(0x50) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_y += 1;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count++;
						return;
					case 1:	
						if(con_move_enemy(0x4b) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_x -= 2;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count--;
						return;					
				}
			}
			else if(player_y < enemy_y) {
				if(kbhit()) 
					move_player(getch());
				switch(count) {
					case 0:
						if(con_move_enemy(0x48) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_y -= 1;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count++;
						return;
					case 1:	
						if(con_move_enemy(0x4b) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_x -= 2;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count--;
						return;					
				}
			}
		}
		else if(player_x >= enemy_x) {
			if(kbhit()) 
				move_player(getch());
			if(player_y >= enemy_y) {
				if(kbhit()) 
					move_player(getch());
				switch(count) {
					case 0:
						if(con_move_enemy(0x50) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_y += 1;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count++;
						return;
					case 1:	
						if(con_move_enemy(0x4d) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_x += 2;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count--;
						return;					
				}
			}
			else if(player_y < enemy_y) {
				if(kbhit()) 
					move_player(getch());
				switch(count) {
					case 0:
						if(con_move_enemy(0x48) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_y -= 1;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count++;
						return;
					case 1:	
						if(con_move_enemy(0x4d) == 0)
							return;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("  ");
						enemy_x += 2;
						coset.X = enemy_x;
						coset.Y = enemy_y;
						SetConsoleCursorPosition(hOut, coset);
						puts("◎");
						count--;
						return;					
				}
			}
		}
	}
}

int con_move(int a_val)
{
	switch(a_val) {
		case 0x48:
			if(y_x[player_y - 1][player_x] != 0)
				return 0;
			break;
		case 0x50:
			if(y_x[player_y + 1][player_x] != 0 || player_y == 18)
				return 0;
			break;
		case 0x4b:
			if(y_x[player_y][player_x - 1] != 0 || y_x[player_y][player_x - 2] != 0)	
				return 0;
			break;
		case 0x4d:
			if(y_x[player_y][player_x + 2] != 0 || y_x[player_y][player_x + 3] != 0 || player_x == 52)
				return 0;
			break;
	}
	return 1;
}

int con_move_enemy(int a_val)
{
	switch(a_val) {
		case 0x48:
			if(y_x[enemy_y - 1][enemy_x] != 0)
				return 0;
			break;
		case 0x50:
			if(y_x[enemy_y + 1][enemy_x] != 0 || enemy_y == 18)
				return 0;
			break;
		case 0x4b:
			if(y_x[enemy_y][enemy_x - 1] != 0 || y_x[enemy_y][enemy_x - 2] != 0)	
				return 0;
			break;
		case 0x4d:
			if(y_x[enemy_y][enemy_x + 2] != 0 || y_x[enemy_y][enemy_x + 3] != 0 || enemy_x == 52)
				return 0;
			break;
	}
	return 1;
}