728x90
#include <stdio.h>
int main(void)
{
// 다차원 배열 multidimentional array
int arr4[3][3][3]; // 배열 3개 인데, 행이 3, 열이 3임
// □□□ // □□□ // □□□
// □□□ // □□□ // □□□
// □□□ // □□□ // □□□
return 0;
}
3차원이라고 해서 내가 생각하는 3차원은 3d였는데, 그냥 3x3이 3개가 있는 형태였다. 오른쪽에서 왼쪽으로 읽는다.
#include <stdio.h>
int main(void)
{
// 다차원 배열 multidimentional array
int arr4[3][3][3]; // 배열 3개 인데, 행이 3, 열이 3임
// □□□ // □□□ // □□□
// □□□ // □□□ // □□□
// □□□ // □□□ // □□□
int arr2[2][5]= {{1,2,3,4,5},{1,2,3,4,5}};
int arr3[4][2]= {{1, 2}, {1, 2},{1, 2}, {1, 2}};
int arr4[3][3][3]= {{{1,2,3},{1,2,3},{1,2,3}}, {{1,2,3},{1,2,3},{1,2,3}}, {{1,2,3},{1,2,3},{1,2,3}}};
return 0;
}
int arr2[2][5]= {
{1,2,3,4,5},
{1,2,3,4,5}
}; // 위에서 만든 모형과 비슷한 것을 확인할 수 있다.
↑ 이러면 상상하기 쉬워질 것이다.
int arr4[3][3][3]= {
{
{1,2,3},
{1,2,3},
{1,2,3}},
{{1,2,3},
{1,2,3},
{1,2,3}},
{{1,2,3},
{1,2,3},
{1,2,3}}}
;
3차원 배열
다차원배열 프로젝트
#include <stdio.h>
#include <time.h>
int arrayAnimal[4][5]; // 동물 배열을 만들어준다. 카드지도라고 보면 된다. (20장카드)
int checkAnimal[4][5]; // 뒤집혔는지 여부를 확인한다.
char * strAnimal[10]; // 동물들 이름, string 배열로 만든다. 10개의 공간을 만드는데 거기에 들어가는 데이터들이
// character포인터 형이다.
char * cPtr="테스트"; // character포인터는 이 테스트라는 글자가 메모리 공간상에 만들어진다.
/*어떤 메모리 공간속에 그 동물 이름이 저장된 주소가 있는데, 그 주소를 가지고 있는 것
얘는 바로바로 쉽게 접근할 수 있다.*/
void initAnimalArray();
void initAnimalName();
int getEmptyPosition();
int conv_pos_x(int x);
int conv_pos_y(int y);
void printAnimals() ;
void printQuestion();
int foundAllAnimals();
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); // 만약 select 1==2라면 즉, 둘 다 만약 3,3을 고른다면
// 효과가 없어야한다. 처리하면 안되기 때문에
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);
/*카드가 이미 선택이 되었는지를 보아야한다.
이유는 카드가 이미 뒤집은거면 또 뒤집을 수 없기 때문에 카드가 뒤집혔는지 확인하고 동시에
두 동물이 같은지 동시에 확인한다.
만약 위 사항 둘 다 아닌 경우 다른 동물인 경우이다.
카드가 뒤집히지 않은 경우는 checkAnimal의 값이 0인 경우*/
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;
}
}
}
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;
//위에서 어떤 값을 반환했을텐데 반환을 햇다하면 반환한 값을 x, y로 변경을 해줘야한다.
/*이렇게 우리가 가져온 빈공간의 좌표를 우리가 convert해서 한 번 조정을 해서
x,y좌표를 구했으면 우리가 만든 지도(arraynimal)에 i라는 값을 집어넣으면 된다.
i는 0부터 10보다 작을때까지니까, 10마리 포지션과 같게 된다.*/
}
}}
// 좌표에서 빈 공간 찾기
/*앞에서 x, y를 했는데, 왜 아래에서 random position만 보내고 getemptypostion를 호출하느냐???
반복작업을 줄이기 위해서 정수형 자료 말고, 포인트라는 구조체 등등을 사용할 수 있다.
우리가 아직 안배워서 int로 넘긴다.*/
int getEmptyPosition()
{
// □□□□□ 0 1 2 3 4 -> 얘들을 5로 나누면 몫은 모두 0
// □□□□□ 5 6 7 8 9 -> 얘들을 5로 나누면 몫은 모두 1
// □□□□□ 10 11 12 13 14 -> 얘들을 5로 나누면 몫은 모두 2
// □□□□□ 15 16 17 18 19 -> 얘들을 5로 나누면 몫은 모두 3
while(1){
int randPos=rand()%20; // 20개 공간이니까 20개 공간에서 한 개가 나와야한다. (0~19사이 숫자반환)
/*만약 19가 나왔으면??
19는 실제로 3,4좌표에 있는 숫자이다. 그래야 좌표에 접근을 할 수 있다.
그래서 우리가 19라는 값을 조정해서 ?, ?이라고 바꾸는 작업을 해야한다.*/
int x=conv_pos_x(randPos);
int y=conv_pos_y(randPos);
// 이렇게 조정을 하면 이제 3,4 위치를 알게 되었으니까
if (arrayAnimal[x][y]==-1)
{
//초기화할떄 -1로 지정했기 떄문에 만약 -1이 나올경우 이는 비어있음을 의미한다.
//만약 -1이 아니라면 비어있지 않은 것이므로 또 다시 좌표를 찾고, 비었는지 확인
return randPos;
//20번을 하면 더이상 빈 공간이 없을거기 때문에 거기서 끝이 난다.
}
//무한 루프를 돌면서
}
return 0;
}
int conv_pos_x(int x)
{
/*역할: 랜덤으로 받은 값을 xy좌표로 바꾸어 주는 것
만약 19였다고 하면 3,4로 바꿔야한다. 19를 5로 나눠보는 것은 어떨까????*/
return x/5;
}
int conv_pos_y(int y)
{
/*만약 14/5를 하면 4가 남는다. 우리는 이 4를 활용하도록 한다.*/
return y%5; // y를 5로 나눈 나머지 값
}
/* 의도: 우리가 동물이 4x5이런 형태로 카드가 만들어질텐데 10마리의 동물이 한 쌍씩 만들어진 상태
여기서 할려는 동작은 일단 이 맵에서 비어있는 위치를 랜덤으로 두개의 공간을 찾는다.
그러고 그 두 공간에 같은 동물의 이름을 집어넣는다. 이렇게 10번의 작업을 하고나면
한 번할떄마다 두 번씩 동물이름이 들어가야 하니까 10x2=20번 해서 끝나게 된다.
이렇게 해서 맵에다가 랜덤으로 동물을 배치를 한다.
그렇게 하기 위해서 10x2를 위해 이중for문을 만들었다. */
void printAnimals() // 동물 위치 출력
{
// □□□□□ 0 1 2 3 4
// □□□□□ 5 6 7 8 9
// □□□□□ 10 11 12 13 14
// □□□□□ 15 16 17 18 19
/*우리가 동물을 출력하는 거는 위 빈칸에 무슨 동물이 있엇는지를 보여주기 위한 것이다.
문제에서 보여주는 것이 아니라 정답을 확인하기 위해서 보여주는 것이다.*/
printf("\n=========이건 비밀인데 몰래 보여주는 구간=========\n\n");
for(int i=0; i<4; i++)
{
for(int j=0; j<5; j++)
{
printf("%8s", strAnimal[arrayAnimal[i][j]]); // 호랑이 강아지 이런 것들은 영어로 하면 6byte니까 넉넉히 8글자로 지정한다.
// 이러면 8개의 공간을 확보하고 거기에 문자열을 집어넣는다. 그러고 strAnimal 로 해서 우리가 원하는 것은
// 동물의 이름이니까 strAnimal을 삽입
//[] 안에는 몇 번째 동물인거냐를 알고 싶은데, 만약 [1][1]이라면 1이라는 값을 집어넣어야 한다.
// 그런데 이 1은 arrayAninmal 에 저장되어 있으니 []안에는 arrayAninmal을 삽입한다.
// i, j 위치로 하여 동물을 출력한다.
}
printf("\n"); // 가독성을 좋게 하기 위해서 for문 하나 끝날떄마다 줄바꿈을 넣는다.
}
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)
{ // 0이면 아직 카드를 뒤집지 못한 것, 0이 아니면 카드를 뒤집은 것
printf("%8s", strAnimal[arrayAnimal[i][j]]);
}
else
{
printf("%8d", seq); // seq가 하는 일은 우리가 ㅁ맵을 가지고 있을떄,
// 문제를 보여주고 우리가 몇 번 카드를 뒤집으세요 알려주는데, 그거를
//x,y 이런 식으로 표시하기 힘드니까 그냥 임시로 번호를 붙이는 것
// 즉 0 1 2 3 4... 이런식으로 보여주는 것
/*그러면 사용자로부터 0번과 4번을 보여줘 이러면 첫번쨰 것과 다섯번쨰 것을
돌리면 되는 것 7번과 19번을 바꿔줘 그러면 번호 그대로 바꾸어주면 되는 것
그래서 이 동작을 하기 위한 것이 seq라는 변수고 만약 선택한 카드가 이미 뒤집힌
카드라면 그냥 뒤집힌 카드를 보여주면 됨.*/
/* seq checkAnimal
□□□□□ 0 1 2 3 4 0 0 0 0 0
□□□□□ 5 6 7 8 9 1 0 0 0 0
□□□□□ 10 11 12 13 14 0 0 0 1 0
□□□□□ 15 16 17 18 19 0 0 0 0 0
이런 형태로 1이라고 적힌 것은 이미 정답을 찾은 형태
0은 아직 발견하지 못한 상태
*/
}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; // 모두 다 뒤집혔고 모두 다 찾았다.
}
/* 프로젝트 설명
10마리의 서로 다른 동물(각 카드 2장씩)
사용자로부터 두 개의 입력값을 받아서 같은 동물을 찾으면 카드를 뒤집은 상태로 두고 틀리면 원상복귀
모든 동물쌍을 찾으면 게임 종료
총 실패횟수 알려주기
*/
코드 너무 많다 ㅜ 일단 1회독
'C언어 공부' 카테고리의 다른 글
구조체 (0) | 2023.07.24 |
---|---|
다차원 배열 (0) | 2023.07.21 |
포인터2 (0) | 2023.07.18 |
C언어 포인터 다시 공부 (0) | 2023.07.17 |
VSCode에서 c언어 시작하기1 (0) | 2023.07.17 |