/*
Copyright(c) 2009 gp-hss <contact_gp_hss@yahoo.co.jp>
*/


#include <stdio.h>
#include <windows.h>

int x;				//5, 10, 15
int y;				//1, 3, 5
int y2; 			//文字消しのための座標値格納変数
int p_y = 7;			//最初の入力する行の指定
int x_y[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};
int ans = 0;			//縦、横、斜めに足した値を格納する変数
int ans_val[6];			//各ゲームのansの値を格納。５ゲームまで
int ans_i = 0;
int ans_i_j = 0;

void output_hyou(void);		//横３、縦３の表を表示
void output_setumei(void);	//説明の表示
int maru_batu(int);		//勝敗の判定、勝⇒1,負⇒0
void input_marubatu(void);	//○、×を交互に入力させる
void output_maru(void);		//○の入力
void output_batu(void);		//×の入力
void cls_string(void);		//文字が重なったときに重なった文字を削除
void cls_new(void);		//もう一度実行するときに画面の一掃
void output_before(int);	//もう一度ゲームをしたときに前回の結果を表示
void cls_new_be(void);		//前回の結果表示を削除
void x_y_val(int *, int *);	//入力された値を専用の座標値に変換

int main()
{
	char cont = 'e';
	int i, j,count = 0;

	COORD coset;
	HANDLE hOut;
	WORD wAttribute;

	do {
		if (cont == 'm') {
			count++;
			if (ans_i_j == 6) {
				cls_new_be();
				ans_i_j = 1;
				count = 1;
			}
			output_before(count);
			cls_new();
			p_y = 7;
			for (i = 0; i < 3; i++) {
				for (j = 0; j < 3; j++)
					x_y[i][j] = 0;
			}
			ans = 0;
		}

		output_hyou();
		output_setumei();
		input_marubatu();

		ans_val[ans_i] = ans;
		ans_i++;
		ans_i_j++;
		if (ans_i == 5)
			ans_i = 0;

		hOut = GetStdHandle(STD_OUTPUT_HANDLE);
		coset.X = 25;
		coset.Y = 3;
		SetConsoleCursorPosition(hOut, coset);
		printf("終了するには ENTER を押す\n");

		coset.X = 25;
		coset.Y = 4;
		SetConsoleCursorPosition(hOut, coset);
		printf("もう一度するには m を入力\n");

		coset.X = 25;
		coset.Y = 5;
		SetConsoleCursorPosition(hOut, coset);
		getchar ();
		cont = getchar ();

	} while (cont == 'm'); 

	return 0;	

}

void output_hyou(void)
{
	HANDLE hOut;
	COORD co;
	int i = 0, k = 0;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	for (i = 3; i < 14; i +=5) {
		co.X = i;
		co.Y = 0;

		SetConsoleCursorPosition(hOut, co);

		printf("[%d]", ++k);
	}
	for (i = 1, k = 0; i < 6; i += 2) {
		co.X = 0;
		co.Y = i;

		SetConsoleCursorPosition(hOut, co);
		
		printf("[%d]", ++k);
	}
	putchar ('\n');

	co.X = 7;
	co.Y = 7;
	SetConsoleCursorPosition(hOut, co);
	printf("横   縦");
	
}

void output_setumei(void)
{
	HANDLE hOut;
	COORD coset;
	int i;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	for (i = 1; i < 6; i++) {
		coset.X = 55;
		coset.Y = i;
		SetConsoleCursorPosition(hOut, coset);
		switch (i) {
			case 1: printf("置く場所の指定には"); break;
			case 2: printf("それぞれの数値を入力後"); break;
			case 3: printf("必ず ENTER を押す。"); break;
			case 4: printf("正しくないと不具合発生。"); break;
			case 5: printf("では楽しんでください。"); break;
		}
	}
}

int maru_batu(int count)
{
	COORD coset;
	HANDLE hOut;
	int i, j;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	coset.X = 25;
	coset.Y = 2;
	SetConsoleCursorPosition(hOut, coset);

	for (i = 0; i < 3; i++) {
		for (j = 0; j < 3; j++) 
			ans += x_y[j][i];
		if (ans == 3) {
			printf("○の勝ちです。\n");
			return 1;
		}
		if (ans == -3) {
			printf("×の勝ちです。\n");
			return 1;
		}
		ans = 0;
	}

	for (j = 0; j < 3; j++)  {
		for (i = 0; i < 3; i++)
			ans += x_y[j][i];
		if (ans == 3) {
			printf("○の勝ちです。\n");
			return 1;
		}
		if (ans == -3) {
			printf("×の勝ちです。\n");
			return 1;
		}
		ans = 0;
	}

	for (i = 0; i < 3; i++)
		ans += x_y[i][i];
	if (ans == 3) {
		printf("○の勝ちです。\n");
		return 1;
	}
	if (ans == -3) {
		printf("×の勝ちです。\n");
		return 1;
	}
	ans = 0;

	j = 2;
	for (i = 0; i < 3; i++) {
		ans += x_y[i][j];
		j--;
	}
	if (ans == 3) {
		printf("○の勝ちです。\n");
		return 1;
	}
	if (ans == -3) {
		printf("×の勝ちです。\n");
		return 1;
	}
	ans = 0;

	if (count == 10) {
		printf("引き分けです。\n");
		ans = 0;
		return 1;
	}

	return 0;
}

void input_marubatu(void)
{
	int i;

	for (i = 2; i < 11; i++) {
		if ((i % 2) == 0) {
			output_maru();
			if(maru_batu(i) == 1)
				break;
		} else {
			output_batu();
			if(maru_batu(i) == 1)
				break;
		}
	}
}

void output_maru(void)
{
	COORD co;
	HANDLE hOut;
	int i;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	input2:
	co.X = 0;
	co.Y = p_y;
	SetConsoleCursorPosition(hOut, co);
	printf("\n○ : ");
	co.X = 8;
	co.Y = p_y + 1;
	SetConsoleCursorPosition(hOut, co);
	scanf("%d", &x);
	co.X = 13;
	co.Y = p_y + 1;
	SetConsoleCursorPosition(hOut, co);
	scanf("%d", &y);
	p_y++;

	if ((x != 1 && x != 2 && x != 3) || (y != 1 && y != 2 && y != 3)) {
		if (p_y == (y2 + 1))
			cls_string();
		for ((i = p_y); i < (p_y + 2); i++) {
			co.X = 25;
			co.Y = i;
			SetConsoleCursorPosition(hOut, co);
			if (p_y == i) {
				printf("\aその場所には置けません。");
				y2 = i;
			}
			if ((p_y + 1) == i) {
				printf("もう一度入力してください。");
			}				
		}
		goto input2;
	}	
	if (((x_y[x - 1][y - 1] == 1) || (x_y[x - 1][y - 1] == -1)) && (x_y[x - 1][y - 1] != 0)) {
		if (p_y == (y2 + 1))
			cls_string();
		for ((i = p_y); i < (p_y + 2); i++) {
			co.X = 25;
			co.Y = i;
			SetConsoleCursorPosition(hOut, co);
			if (p_y == i) {
				printf("\aその場所には置けません。");
				y2 = i;
			}
			if ((p_y + 1) == i) {
				printf("もう一度入力してください。");
			}				
		}
		goto input2;
	}

	x_y[x - 1][y - 1] = 1;

	x_y_val(&x, &y);
	co.X = x;
	co.Y = y;
	SetConsoleCursorPosition(hOut, co);
	printf("○");

}

void output_batu(void)
{
	COORD co;
	HANDLE hOut;
	int i;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	input:
	co.X = 0;
	co.Y = p_y;
	SetConsoleCursorPosition(hOut, co);
	printf("\n× : ");
	co.X = 8;
	co.Y = p_y + 1;
	SetConsoleCursorPosition(hOut, co);
	scanf("%d", &x);
	co.X = 13;
	co.Y = p_y + 1;
	SetConsoleCursorPosition(hOut, co);
	scanf("%d", &y);
	p_y++;

	if ((x != 1 && x != 2 && x != 3) || (y != 1 && y != 2 && y != 3)) {
		if (p_y == (y2 + 1))
			cls_string();
		for ((i = p_y); i < (p_y + 2); i++) {
			co.X = 25;
			co.Y = i;
			SetConsoleCursorPosition(hOut, co);
			if (p_y == i) {
				printf("\aその場所には置けません。");
				y2 = i;
			}
			if ((p_y + 1) == i) {
				printf("もう一度入力してください。");
			}				
		}
		goto input;
	}
	if (((x_y[x - 1][y - 1] == 1) || (x_y[x - 1][y - 1] == -1)) && (x_y[x - 1][y - 1] != 0)) {
		if (p_y == (y2 + 1))
			cls_string();
		for ((i = p_y); i < (p_y + 2); i++) {
			co.X = 25;
			co.Y = i;
			SetConsoleCursorPosition(hOut, co);
			if (p_y == i) {
				printf("\aその場所には置けません。");
				y2 = i;
			}
			if ((p_y + 1) == i) {
				printf("もう一度入力してください。");
			}				
		}
		goto input;
	}

	x_y[x - 1][y - 1] = -1;
	x_y_val(&x, &y);
	co.X = x;
	co.Y = y;

	SetConsoleCursorPosition(hOut, co);

	printf("×");

}

void cls_new(void)
{
	HANDLE hOut;
	COORD coset;
	int x_val, y_val;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	for (y_val = 0; y_val < (p_y + 10); y_val++) {
		for(x_val = 0; x_val < 52; x_val++) {
			coset.X = x_val;
			coset.Y = y_val;
			SetConsoleCursorPosition(hOut, coset);
			putchar(' ');
		}
	}
}		

void cls_string(void)
{
	HANDLE hOut;
	COORD coset;
	int x_val;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	for (x_val = 25; x_val < 52; x_val++) {
		coset.X = x_val;
		coset.Y = y2;
		SetConsoleCursorPosition(hOut, coset);
		putchar(' ');
	}
	for (x_val = 45; x_val < 52; x_val++) {
		coset.X = x_val;
		coset.Y = (y2 + 1);
		SetConsoleCursorPosition(hOut, coset);
		putchar(' ');
	}		
}

void output_before(int count)
{
	HANDLE hOut;
	COORD coset;
	int i = 0, k, c_count = count;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	for (k = (8 + (c_count - 1) * 3); k > 7; k -= 3) {	
			coset.X = 55;
			coset.Y = k;
			SetConsoleCursorPosition(hOut, coset);
			printf("< %d 回前 の 勝  敗 >", c_count--);
			coset.X = 55;
			coset.Y = k + 1;
			SetConsoleCursorPosition(hOut, coset);			
			if (ans_val[i] == 3) {
				printf(" 勝 … ○  負 … ×");
			}
			if (ans_val[i] == 0) 
				printf(" 勝 … △  負 … △");
			if (ans_val[i] == -3) {
				printf(" 勝 … ×  負 … ○");
			}
			i++;	
	}
}

void cls_new_be(void)
{
	HANDLE hOut;
	COORD coset;
	int x_val, y_val;

	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	for (y_val = 8; y_val < 22; y_val++) {
		for(x_val = 55; x_val < 77; x_val++) {
			coset.X = x_val;
			coset.Y = y_val;
			SetConsoleCursorPosition(hOut, coset);
			putchar(' ');
		}
	}
}

void x_y_val(int *x1, int *y1)
{
	int i;

	for (i = 1; i < 4; i++) {
		if(*x1 == i) {
			*x1 += (i * 4);
			*x1 -= 1;
		}
	}
	switch (*y1) {
		case 1: break;
		case 2: *y1 = 3; break;
		case 3: *y1 = 5; break;
	}
}