#include <stdio.h>
#include <stdlib.h>

#define MS 5
#define may x
#define nguoi o

typedef enum {e, x, o} xo;

void inBanCo(xo (*bc)[MS]);
void tinhDiem(xo (*bc)[MS], int (*diem)[MS]);
void mayDi(xo (*bc)[MS], int (*diem)[MS]);
int win(xo (*bc)[MS], int (*diem)[MS]);
int hetO(xo (*bc)[MS]);
int checkHang(xo (*bc)[MS], int hang, xo ben);
int checkCot(xo (*bc)[MS], int cot, xo ben);
int checkDuongCheo1(xo (*bc)[MS], xo ben);
int checkDuongCheo2(xo (*bc)[MS], xo ben);
int full0(int (*diem)[MS]);
int checkWin(xo (*bc)[MS], xo ben);
int checkWinHang(xo (*bc)[MS], int h, xo ben);
int checkWinCot(xo (*bc)[MS], int c, xo ben);
int checkWinDuongCheo1(xo (*bc)[MS], xo ben);
int checkWinDuongCheo2(xo (*bc)[MS], xo ben);
void cls();

int main() {
	int n, m;
	int diem[MS][MS];
	xo banCo[MS][MS] = {{e}};

	while (!win(banCo, diem)) {
		cls();
		inBanCo(banCo);
		do {
			do {
				printf("\nBan danh o (hang - cot): ");
				scanf("%d %d", &m, &n);
				if (m < 0 || n < 0 || m > MS || n > MS)
					printf("\nKhong co o do\n\n");
			} while (m < 0 || n < 0 || m > MS || n > MS);
			if (banCo[m - 1][n - 1] != e)
				printf("\nKhong the danh o nay\n");
		} while (banCo[m - 1][n - 1] != e);
		banCo[m - 1][n - 1] = nguoi;
		tinhDiem(banCo, diem);
		mayDi(banCo, diem);
	}

	return 0;
}

int checkDuongCheo2(xo (*bc)[MS], xo ben) {
	for (int k = 0; k < MS; k++)
		if (bc[k][MS - k - 1] == ben)
			return 1;
	return 0;
}

int checkDuongCheo1(xo (*bc)[MS], xo ben) {
	for (int k = 0; k < MS; k++)
		if (bc[k][k] == ben)
			return 1;
	return 0;
}

int checkCot(xo (*bc)[MS], int cot, xo ben) {
	for (int i = 0; i < MS; i++)
		if (bc[i][cot] == ben)
			return 1;
	return 0;
}

int checkHang(xo (*bc)[MS], int hang, xo ben) {
	for (int i = 0; i < MS; i++)
		if (bc[hang][i] == ben)
			return 1;
	return 0;
}

void cls() {
	system("cls");
}

int hetO(xo (*bc)[MS]) {
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++)
			if (bc[i][j] == e)
				return 0;
	return 1;
}

int full0(int (*diem)[MS]) {
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++)
			if (diem[i][j] != 0)
				return 0;
	return 1;
}

int checkWinHang(xo (*bc)[MS], int h, xo ben) {
	for (int i = 0; i < MS; i++)
		if (bc[h][i] != ben)
			return 0;
	return 1;
}

int checkWinCot(xo (*bc)[MS], int c, xo ben) {
	for (int i = 0; i < MS; i++)
		if (bc[i][c] != ben)
			return 0;
	return 1;
}

int checkWinDuongCheo1(xo (*bc)[MS], xo ben) {
	for (int k = 0; k < MS; k++)
		if (bc[k][k] != ben)
			return 0;
	return 1;
}

int checkWinDuongCheo2(xo (*bc)[MS], xo ben) {
	for (int k = 0; k < MS; k++)
		if (bc[k][MS - k - 1] != ben)
			return 0;
	return 1;
}

int checkWin(xo (*bc)[MS], xo ben) {
	for (int k = 0; k < MS; k++) {
		if (checkWinHang(bc, k, ben))
			return 1;
		else if (checkWinCot(bc, k, ben))
			return 1;
	}
	if (checkWinDuongCheo1(bc, ben) || checkWinDuongCheo2(bc, ben))
		return 1;
	return 0;
}

int win(xo (*bc)[MS], int (*diem)[MS]) {
	if (checkWin(bc, may)) {
		cls();
		inBanCo(bc);
		printf("\nMay thang\n");
		return 1;
	}
	if (checkWin(bc, nguoi)) {
		cls();
		inBanCo(bc);
		printf("\nNguoi thang\n");
		return 1;
	}
	if (full0(diem)) {
		cls();
		inBanCo(bc);
		printf("\nHoa co\n");
		return 1;
	}
	if (hetO(bc)) {
		cls();
		inBanCo(bc);
		printf("\nHoa co\n");
		return 1;
	}
	return 0;
}

void mayDi(xo (*bc)[MS], int (*diem)[MS]) {
	int k = 0, l = 0;
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++)
			if (diem[k][l] <= diem[i][j] && bc[i][j] == e) {
				k = i;
				l = j;
			}
	bc[k][l] = may;
}

void tinhDiem(xo (*bc)[MS], int (*diem)[MS]) {
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++) {
			diem[i][j] = 0;
			if (j == i || i == MS - j - 1)
				diem[i][j]++;
		}
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++)
			if (bc[i][j] == may) {
				for (int k = 0; k < MS; k++) {
					if (!checkCot(bc, j, nguoi))
						diem[k][j]++;
					if (!checkHang(bc, i, nguoi))
						diem[i][k]++;
				}
				if (i == j) {
					if (!checkDuongCheo1(bc, nguoi))
						for (int k = 0; k < MS; k++)
							diem[k][k]++;
				}
				if (i == MS - j - 1) {
					if (!checkDuongCheo2(bc, nguoi))
						for (int k = 0; k < MS; k++)
							diem[k][MS - k - 1]++;
				}
			} else if (bc[i][j] == nguoi) {
				for (int k = 0; k < MS; k++) {
					if (checkCot(bc, j, may))
						diem[k][j] = 0;
					else
						diem[k][j]++;
					if (checkHang(bc, i, may))
						diem[i][k] = 0;
					else
						diem[i][k]++;
				}
				if (i == j) {
					if (checkDuongCheo1(bc, may))
						for (int k = 0; k < MS; k++)
							diem[k][k] = 0;
					else
						for (int k = 0; k < MS; k++)
							diem[k][k]++;
				}
				if (i == MS - j - 1) {
					if (checkDuongCheo2(bc, may))
						for (int k = 0; k < MS; k++)
							diem[k][MS - k - 1] = 0;
					else
						for (int k = 0; k < MS; k++)
							diem[k][MS - k - 1]++;
				}
			}
	for (int i = 0; i < MS; i++)
		for (int j = 0; j < MS; j++)
			if (bc[i][j] == nguoi || bc[i][j] == may)
				diem[i][j] = 0;
}

void inBanCo(xo (*bc)[MS]) {
	printf("\n");
	for (int i = 0; i < MS; i++) {
		for (int j = 0; j < MS; j++)
			if (bc[i][j] == e)
				printf("| ");
			else if (bc[i][j] == x)
				printf("|X");
			else
				printf("|O");
		printf("|\n");
	}
}
