C언어 공부

다차원배열

Bordercolli 2023. 7. 24. 10:21
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