본문 바로가기

c언어 기초

c언어 다차원배열 multidimensional array 프로젝트 카드뒤집기게임 - 나도코딩

#include <stdio.h>
#include <time.h>

// 10마리의 서로 다른 동물 (각 카드 2장씩)
// 사용자로부터 2개의 입력값을 받아서 같은 동물 찾으면 카드 뒤집기
// 모든 동물 쌍을 찾으면 게임 종료
// 총 실패 횟수 알려주기

int arrayAnimal[4][5]; // 카드 지도 (20장의 카드)
void initAnimalArray();
char* strAnimal[10]; // 10개의 공간을 만들고, 공간에 들어갈 데이터는 주소
void shuffleAnimal();
void initAnimalName();
int getEmptyPosition();
int conv_pos_x(int x);
int conv_pos_y(int y);
void printAnimal();
void printQuestion();
int checkAnimal[4][5]; // 뒤집혔는지 여부 확인
int foundAllAnimals();


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

	initAnimalArray();
	initAnimalName();

	shuffleAnimal();

	int failCount = 0;

	while (1)
	{
		int select1 = 0; // 사용자가 선택한 처음 수
		int select2 = 0; // 사용자가 선택한 두번째 수

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

		if (select1 == select2)
			continue;

		// 좌표에 해당하는 카드를 뒤집어보고 같은 지 안 같은 지 확인
		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(카드가 뒤집히지 않았는지 && 두 동물이 같은지)
		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\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;
		}

	}

	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()

// ㅁ ㅁ ㅁ ㅁ ㅁ 
// ㅁ ㅁ ㅁ ㅁ ㅁ 
// ㅁ ㅁ ㅁ ㅁ ㅁ            
// ㅁ ㅁ ㅁ ㅁ ㅁ          
{
	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);


			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;
		// 19 -> (3,4)

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

		if (arrayAnimal[x][y] == -1)
		{
			return randPos;
		}
	}
	return 0;
}


int conv_pos_x(int x)
{
	// 19 -> (3,4)
	return x / 5;
}
int conv_pos_y(int y)
{
	return y % 5;
}


void printAnimal()
{
	printf("\n======이건 비밀인데.... 몰래 보여줍니다...======\n");
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%8s", strAnimal[arrayAnimal[i][j]]);
		}
		printf("\n");
	}
	printf("\n======================================================================\n\n");
}

void printQuestion()
{
	printf("\n\n(문제)\n");
	int seq = 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; // 모두 다 찾음
}

간단한 카드게임 만들기 프로젝트다.

 

============================================================================================

 

char *strAnimal[10]은 10개의 공간을 만들고 각 공간에 들어갈 데이터는 문자열의 주소인 것을 의미한다.

char *strAnimal[3] = {"dog", "cat", "monkey"};라고 실행하면 char *strAnimal = {111111,222222,333333} 이렇게 반환.

즉, 각 문자열들은 그 형태에 상관없이 메모리 공간에 저장되고, 그 문자열이 저장된 위치의 주소값이 반환된다.

그리고 반환된 주소는 각 문자열의 첫 번째 문자의 주소값이다.

다시 정리하자면, 위와 같이 선언했을 때

○ 각 메모리 공간에 문자열들 각각 저장됨.

○ 각 문자열들의 첫번째 문자의 주소값이 반환.

○ 그 반환 값이 포인터변수에 저장.

 

 

char str1[] = "coding"; 과 char* str2 = "coding"; 의 차이점 

 

○ str1은 그 자체로 문자열 전체를 저장하는 배열

○ str2는 메모리 상에 자동으로 저장된 문자열 coding의 첫 번째 문자를 단순히 가리키고만 있는 포인터 변수

○ str1은 변수 형태의 문자열로 값의 변경이 가능하지만, str2는 상수 형태의 문자열로 값의 변경이 불가능함.

str1과 str2는 문자열의 시작 주소 값을 가진다는 면에서는 같다.

 

============================================================================================

 

initAnimalArray로 4행5열의 배열 만들고, initAnimalName으로 동물이름들을 선언.

 

shuffleAnimal은 4행5열 배열 중 2개를 1쌍으로 섞어준다. 함수 안의 pos는 getEmptyPosition을 이용해서 랜덤으로 수를 받을 것이다. 랜덤으로 받은 수 2개는 각각 4행5열 배열의 좌표로 바꿔지고 같은 i값이 저장될 것이다. 

 

getEmptyPosition은 while 무한루프를 이용해서 랜덤으로 뽑은 수를 4행5열 배열을 좌표로 바꿔줄 것이다. (비어있어야함)

 

shulffle과 getEmptyPosition을 수행하면

1 5 2 5 6

3 7 9 4 0          ArrayAnimal 이 이렇게 저장되어 있을거임.

8 9 8 6 0

7 1 2 4 3     

 

int failCount는 게임이 끝나고 몇번 틀렸는지 알기 위해 선언

 

printAnimal은 4행5열 배열(ArrayAnimal)에 저장된 값들을 동물들로 바꿔서 보여줄 것이다.

ex) strAnimal[Animal[i][j]] => strAnimal[arrayAnimal[3][4]] => strAnimal[3] = "고양이"

 

printQuestion은 카드를 맞췄을 때 (선택한 두 카드의 좌표 checkAnimal[ ][ ] 값은 1로 바꿔줘서) 0이 아닐 때 동물이름을 출력하도록 하고, 0일 때는 좌표(0~19)를 보여줌. seq는 for 반복문을 반복하면서 0 ~ 19를 4행5열 배열처럼 보이게함.

 

foundAllAnimals는 위에서 카드를 맞췄을 때 그 좌표값들의 checkAnimal[ ][ ]을 1로 바꿔줬는데, checkAnimal에 저장된 값들이 모두 1인지 확인.  그리고 모두 1이라면 1을 반환

main함수 안에서 foundAllAnimals의 반환값이 1이면 break로 while문 탈출하고 종료.