본문 바로가기

Programming/C

[C언어] 프로젝트 7. 동물 뒤집기

반응형

 

0123456
동물 뒤집기 - 쌍둥이를 찾아서

선수 과목

  1. 다차원 배열 기본
  2. 다차원 배열 접근
  3. 다차원 배열 선언
  4. 다차원 배열 사용
#include <stdio.h>
#include <time.h>
//10마리의 서로 다른 동물 (각 카드 2장씩)
//사용자로부터 2개의 입력값을 받아서 -> 같은 동물 찾으면 카드 뒤집기
//모든 동물 쌍을 찾으면 게임 종료
//총 실패 횟수 알려주기

int arrayAnimal[4][5]; //카드 지도 (20장의 카드)
int checkAnimal[4][5]; //뒤집혔는지 여부 확인

char * strAnimal[10]; //동물의 이름 캐릭터 포인터형 

//char* cPtr = "테스트"; //테스트라는 글자의 주소를 가진다, 쉽게 접근가능

void initAnimalArray();//동물 배열
void initAnimalName();
void shuffleAnimal();
int getEmptyPosition(); //좌표에서 빈 공간 찾기


int conv_pos_x(int x);
int conv_pos_y(int y);

void printAnimals(); //동물 위치 출력
void printQuestion(); //문제 출력 (카드 지도)

int main(void)
{
	srand(time(NULL));
	initAnimalArray(); 
	initAnimalName();

	shuffleAnimal(); 

	int failCount = 0; //실패 횟수

	while (1) //무한루프 게임진행
	{
		int select1 = 0; //사용자가 선택한 처음 수
		int select2 = 0; //사용자가 선택한 두번째 수

		printAnimals(); //동물 위치 출력
		printQuestion(); //문제 출력 (카드 지도)
		printf("뒤집을 카드를 2개 고르세요 :");
		scanf_s("%d %d", &select1, &select2);

		if (select1 == select2) //같은 카드 선택 무효
			continue;

		//좌표에 해당하는 카드를 뒤집어 보고 같은지 안같은지 확인
		//정수 좌표를 x,y 좌표로 변환

		int firstSelect_x = conv_pos_x(select1);
		int firstSelect_y = conv_pos_y(select1);

		int secondSelect_x = conv_pos_x(select2);
		int secondSelect_y = conv_pos_y(select2);
		
		if ((checkAnimal[firstSelect_x][firstSelect_y] == 0
			&&
			checkAnimal[secondSelect_x][secondSelect_y] == 0)
			&&
			(arrayAnimal[firstSelect_x][firstSelect_y]
				== arrayAnimal[secondSelect_x][secondSelect_y])
			)

			//카드가 이미 선택이 되었는지 여부 확인, 뒤집은건 다시 뒤집기 불가능
			//카드가 뒤집히지 않았는지, 두 동물이 같은지
			//같은동물인 경우

		{
			printf("\n\n빙고! : %s 발견 \n\n", strAnimal[arrayAnimal[firstSelect_x][firstSelect_y]]);
			//첫번째 값이든 두번째값이든 똑같은 값이므로
			// 찾았다는걸 알림
			checkAnimal[firstSelect_x][firstSelect_y] = 1; //선택된 카드라는 것 표기
			checkAnimal[secondSelect_x][secondSelect_y] = 1;

			
		}
			//다른 동물인 경우
		else
		{
			printf("\n\n 떙!! (틀렸거나 이미 뒤집힌 카드입니다.)\n");
			printf("%d : %s\n", select1, strAnimal[arrayAnimal[firstSelect_x][firstSelect_y]]);
			printf("%d : %s\n", select2, strAnimal[arrayAnimal[secondSelect_x][secondSelect_y]]);
			// 틀린카드를 알려줌
            printf("\n\n");

			failCount++;
		}
		
		//모든 카드를 찾았는지 여부, 1: 참, 0 :거짓
		if (foundAllAnimals() == 1)
		{
			printf("\n\n 축하합니다! 모든 동물을 다 찾았네요 \n");
			printf("지금까지 총 %d번 실수하였습니다. \n", failCount);
			break; //while문 탈출
		}
	}

	return 0;
}

void initAnimalArray()
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			arrayAnimal[i][j] = -1;
		}
	}
}

void initAnimalName()
{
	strAnimal[0] = "원숭이";
	strAnimal[1] = "하마";
	strAnimal[2] = "강아지";
	strAnimal[3] = "고양이";
	strAnimal[4] = "돼지";

	strAnimal[5] = "코끼리";
	strAnimal[6] = "기린";
	strAnimal[7] = "낙타";
	strAnimal[8] = "타조";
	strAnimal[9] = "호랑이";
}

void shuffleAnimal()
{
	//□□□□□
	//□□□□□
	//□□□□□
	//□□□□□
	//□□□□□

	//비어있는 맵에서 비어있는 2개의 위치를 찾아 똑같은 동물을 집어넣는다.
	//10번하면 20번

	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			int pos = getEmptyPosition(); //비어있는 위치 반환
			int x = conv_pos_x(pos); 
			int y = conv_pos_y(pos); //반환한 값을 x,y로 변경

			arrayAnimal[x][y] = i;
		}
	}
}

int getEmptyPosition()
{
	//□□□□□  0  1  2  3  4 
	//□□□□□  5  6  7  8  9
	//□□□□□ 10 11 12 13 14
	//□□□□□ 15 16 17 18 19
	
	while (1)
	{
		int randPos = rand() % 20; //0~19 사이의 숫자 반환
		//19 -> (3,4)
		int x = conv_pos_x(randPos);
		int y = conv_pos_y(randPos);
		
		if (arrayAnimal[x][y]==-1) //초기 -1로 설정했기때문에 -1일경우 빈공간
		{
			return randPos; //반복 작업을 안하려면 구조체로도 정의가능
		}
		
	}
	return 0;
}

int conv_pos_x(int x)
{
	//19 -> (3,4) 5로 나눌경우 x값을 구할 수 있다
	return x / 5;
}

int conv_pos_y(int y)
{
	//19 -> 19/5 ?몫은 3, 나머지 4, 5로 나눈 나머지값을 활용해 y값을 구할 수 있다.
	return y % 5;
}

void printAnimals()
{
	//□□□□□  1  1  2  2  3 
	//□□□□□  3  4  4  5  5
	//□□□□□  6  6  7  7  8
	//□□□□□  8  9  9 10 10
	printf("\n=============위치공개=================\n\n");
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%8s", strAnimal[arrayAnimal[i][j]]); //8칸 공간에 문자열 입력
		}
		printf("\n");
	}
	printf("\n=====================================\n\n");
}
void printQuestion() //문제 출력 (카드 지도)
{
	printf("\n\n(문제)\n");

	int seq = 0; //몇번카드를 눌렀는지 확인하기 편하게 임시로 번호를 붙임

	//seq							//check animal
	//□□□□□  0  1  2  3  4		// 0 0 0 0 0
	//□□□□□ 하마6  7  8  9		// 1 0 0 0 0
	//□□□□□ 10 11 12하마14		// 0 0 0 1 0 
	//□□□□□ 15 16 17 18 19		// 0 0 0 0 0

	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			//카드를 뒤집어서 정답을 맞혔으면 '동물 이름'

			if (checkAnimal[i][j] != 0)
			{
				printf("%8s", strAnimal[arrayAnimal[i][j]]);
			}


			//정답을 못맞혔으면 뒷면 -> 위치를 나타내는 숫자
			else
			{
				printf("%8d", seq);

			}
			seq++; //정답 맞히거나 못맞히거나 인덱스값 증가
		}
		printf("\n");
	}
}

int foundAllAnimals()
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			if (checkAnimal[i][j] == 0)
			{
				return 0;
			}
		}
	}
	return 1; // 모두 다 찾음
}
반응형