#include<stdio.h>
#include<Windows.h>		// sleep 함수를 위한 라이브러리

#pragma warning(disable : 4996)
// 함수 원형에 대한 정의
void my_opening();
int my_card1(int(*)[4]);
int my_card2(int(*)[4]);
int my_card3(int(*)[4]);
int my_card4(int(*)[4]);
int my_card5(int(*)[4]);

void my_res(int, int, int, int, int);


int main()
{
	// 5개의 카드를 위한 2차원 배열 정의 및 초기화

	int card1[4][4] = { 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 };
	int card2[4][4] = { 2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31 };
	int card3[4][4] = { 4,5,6,7,12,13,14,15,20,21,22,23,28,29,30,31 };
	int card4[4][4] = { 8,9,10,11,12,13,14,15,24,25,26,27,28,29,30,31 };
	int card5[4][4] = { 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };


	int a, b, c, d, e;
	char k;

	my_opening();									// 이 함수로 화면에 안내를 출력

	Sleep(3000);									printf("생각했는가? 시작하려면 엔터를 클릭하라.");
	scanf("%c", &k);
	printf("\n\n");

	a = my_card1(card1);	// 사용자에게 첫 번째 카드를 보여주고 1이나 0을 a에 저장
	b = my_card2(card2);	// 사용자에게 두 번째 카드를 보여주고 1이나 0을 b에 저장
	c = my_card3(card3);	// 사용자에게 세 번째 카드를 보여주고 1이나 0을 c에 저장
	d = my_card4(card4); 	// 사용자에게 네 번째 카드를 보여주고 1이나 0을 d에 저장
	e = my_card5(card5);	// 사용자에게 다섯 번째 카드를 보여주고 1이나 0을 e에 저장

	my_res(a, b, c, d, e);	// 사용자가 생각한 숫자를 계산해서 화면에 출력


	return 0;
}

// my_opening 함수가 처음으로 화면에 안내를 출력
void my_opening()
{
	printf("# 지금부터 여러분을 신비한 마술의 세계로 초대한다.\n\n\n");
	printf("1 - 31의 숫자 중 마음에 드는 숫자를 생각하라. \n\n\n");
}

// my_card1 함수가 ca1에 있는 숫자들을 화면에 출력해 사용자부터 0이나 1을 입력받음
int my_card1(int(*ca1)[4])
{
	int i, j, a;

	while (1)
	{
		// 해당 for 문은 ca1에 있는 숫자들을 출력
		printf("   --------- A 카드 ---------\n");
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				printf("%7d", ca1[i][j]);
			}
			printf("\n");
		}
		printf("   --------------------------\n");
		printf("\n\n");
		printf("A 카드에 생각한 숫자가 있다면 YES(1번), 없다면 NO(0번)를 선택하라. : \n");
		scanf("%d", &a);

		// 사용자가 생각한 숫자가 ca1에 있으면 1을, 아니면 0을 입력하고 그 결과를 a에 저장
		printf("\n\n");
		if (a > -1 && a < 2)

			// 사용자가 입력한 문자가 0이나 1이면 a를 반환하고, 잘못된 입력이면 다시 ca1을 출력
		{
			return a;
		}
	}
}

// my_card2 함수가 ca2에 있는 숫자들을 화면에 출력해 사용자부터 0이나 1을 입력받음
int my_card2(int(*ca2)[4])
{
	int i, j, b;

	while (1)
	{
		printf("   --------- B 카드 ---------\n");

		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				printf("%7d", ca2[i][j]);
			}
			printf("\n");
		}
		printf("   --------------------------\n");
		printf("\n\n");
		printf("B 카드에 생각한 숫자가 있다면 YES(1번), 없다면 NO(0번)를 선택하라.: \n");
		scanf("%d", &b);

		// 사용자가 생각한 숫자가 ca2에 있으면 1을, 아니면 0을 입력하고 그 결과를 b에 저장
		printf("\n\n");
		if (b > -1 && b < 2)

			// 사용자가 입력한 문자가 0이나 1이면 b를 반환하고, 잘못된 입력이면 다시 ca2를 출력
		{
			return b;
		}
	}
}

// my_card3 함수가 ca3에 있는 숫자들을 화면에 출력해 사용자부터 0이나 1을 입력받음
int my_card3(int(*ca3)[4])
{
	int i, j, c;

	while (1)
	{
		printf("   --------- C 카드 ---------\n");
		// 해당 for 문은 ca3에 있는 수들을 출력
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				printf("%7d", ca3[i][j]);
			}
			printf("\n");
		}
		printf("   --------------------------\n");
		printf("\n\n");
		printf("C 카드에 생각한 숫자가 있다면 YES(1번), 없다면 NO(0번)를 선택하라.: \n");
		scanf("%d", &c);

		// 사용자가 생각한 숫자가 ca3에 있으면 1을, 아니면 0을 입력하고 그 결과를 b에 저장
		printf("\n\n");
		if (c > -1 && c < 2)	  // 사용자가 입력한 문자가 0이나 1이면 b를 반환하고, 잘못된 입력이면 다시 ca3를 출력
		{
			return c;
		}
	}
}

// my_card4 함수가 ca4에 있는 숫자들을 화면에 출력해 사용자부터 0이나 1을 입력받음
int my_card4(int(*ca4)[4])
{
	int i, j, d;

	while (1)
	{
		printf("   --------- D 카드 ---------\n");
		// 해당 for 문은 ca4에 있는 숫자들을 출력
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				printf("%7d", ca4[i][j]);
			}
			printf("\n");
		}
		printf("   --------------------------\n");
		printf("\n\n");
		printf("D 카드에 생각한 숫자가 있다면 YES(1번), 없다면 NO(0번)를 선택하라. : \n");
		scanf("%d", &d);

		// 사용자가 생각한 숫자가 ca4에 있으면 1을, 아니면 0을 입력하고 그 결과를 b에 저장
		printf("\n\n");
		if (d > -1 && d < 2)	  // 사용자가 입력한 문자가 0이나 1이면 b를 반환하고, 잘못된 입력이면 다시 ca4를 출력
		{
			return d;
		}
	}
}

// my_card5 함수가 ca5에 있는 숫자들을 화면에 출력해 사용자부터 0이나 1을 입력받음
int my_card5(int(*ca5)[4])
{
	int i, j, e;

	while (1)
	{
		printf("   --------- E 카드 ---------\n");
		// 해당 for 문은 ca5에 있는 숫자들을 출력
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				printf("%7d", ca5[i][j]);
			}
			printf("\n");
		}
		printf("   --------------------------\n");
		printf("\n\n");
		printf("E 카드에 생각한 숫자가 있다면 YES(1번), 없다면 NO(0번)를 선택하라.: \n");
		scanf("%d", &e);

		// 사용자가 생각한 숫자가 ca5에 있으면 1을, 아니면 0을 입력하고 그 결과를 b에 저장
		printf("\n\n");
		if (e > -1 && e < 2)
			// 사용자가 입력한 문자가 0이나 1이면 b를 반환하고, 잘못된 입력이면 다시 ca5를 출력
		{
			return e;
		}
	}
}

// my_res 함수는 사용자가 생각한 숫자를 출력
void my_res(int a, int b, int c, int d, int e)
{
	int res;
	/*
		2진수를 10진수로 변환하는 것처럼 사용자로부터 얻은 a,b,c,d,e에 대해 계산을 진행, 즉 a,b,c,d,e 비트열이라고 가정해 이를 10진수로 변경하면 사용자가 생각한 숫자가 나타남
	*/
	res = (e * 2 * 2 * 2 * 2) + (d * 2 * 2 * 2) + (c * 2 * 2) + (b * 2) + (a);
	printf("당신이 마음에 드는 숫자는 %d이다.\n\n\n", res);
	printf("신기하지 않은가?\n");
}