c++

20210715 빙고 완전체 코드 분석!

TIN9 2021. 7. 15.
반응형

안녕하세요 틴구입니다.

오늘은 저번에 내주신 빙고 *출력에서 더 진행한

*출력, 빙고 출력, AI까지 만드는 것을 배웠어요!! 진짜 미치네요

왜 이렇게 어렵죠? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그럼 바로 코드를 분석해 볼까요??

 

아 그리고 주석에 색을 넣었었는데 색이 좀 진해서 코드랑 구분이 힘들어 색 연하기를 낮췄습니다.


#include <iostream>
#include <time.h>

int main()
{
    srand((unsigned int)time(0));
    rand();
    // Player와 AI 빙고판을 만들기 위한 배열 선언
    int Number[25] = {};
    int AINumber[25] = {};
    // Player와 AI 빙고 숫자를 1 ~ 25로 설정하기 위한 구성
    for (int i = 0; i < 25; ++i)
    {
        Number[i] = i + 1;
        AINumber[i] = i + 1;
    }
    // Player와 AI의 빙고판 숫자를 섞어주기 위한 코드 구성
    for (int i = 0; i < 100; ++i)
    {
        int Index1 = rand() % 25;
        int Index2 = rand() % 25;

        int Temp = Number[Index1];
        Number[Index1] = Number[Index2];
        Number[Index2] = Temp;

        Index1 = rand() % 25;
        Index2 = rand() % 25;

        Temp = AINumber[Index1];
        AINumber[Index1] = AINumber[Index2];
        AINumber[Index2] = Temp;
    }

    /*
    1, 2, 3, *, 5, 6, 7, *, *, 10

    10개짜리의 배열에 *이 아닌 수만
    넣어준다.
    1, 2, 3, 5, 6, 7, 10

    총 7개가 들어가고 7개중 랜덤한 인덱스를 구해서 그 값을 선택하게 해 준다.
    */
    // *이 아닌 숫자를 찾아내기 위한 임의의 배열과 변수를 생성해준다.
    int SelectNumber[25] = {};
    int SelectCount = 0;
    
    int Bingo = 0, AIBingo = 0;

    while (true)
    {
        system("cls");

        std::cout << "====================== Player ======================" << std::endl << std::endl;
        // Player의 빙고판을 출력하는 동시에 Player와 AI가 선택한 것이 빙고판 숫자랑 같을 때 *로 출력
        for (int i = 0; i < 5; ++i)
        {
            for (int j = 0; j < 5; ++j)
            {
                // INT_MAX 는 int타입으로 표현할 수 있는 최대값이 상수로 정해져 있는 것이다.
                if (Number[i * 5 + j] == INT_MAX)
                    std::cout << "*\t";

                else
                    std::cout << Number[i * 5 + j] << "\t";
            }

            // 가로 한줄이 출력이 완료되었다면 개행한다.
            std::cout << std::endl;
        }

        // 빙고를 출력하기 위한 cout구성
        std::cout << "Bingo : " << Bingo << std::endl;
        std::cout << std::endl;

        std::cout << "====================== AI ======================" << std::endl << std::endl;
        // AI의 빙고 숫자 출력과 동시 Player와 AI가 선택한 숫자가 빙고판 숫자랑 동일하면 *출력
        for (int i = 0; i < 5; ++i)
        {
            for (int j = 0; j < 5; ++j)
            {
                // INT_MAX 는 int타입으로 표현할 수 있는 최대값이 상수로 정해져 있는 것이다.
                if (AINumber[i * 5 + j] == INT_MAX)
                    std::cout << "*\t";

                else
                    std::cout << AINumber[i * 5 + j] << "\t";
            }

            // 가로 한줄이 출력이 완료되었다면 개행한다.
            std::cout << std::endl;
        }

        // Player가 숫자를 입력하기 위한 Input변수를 생성과 동시에 초기화를 해줌
        int Input = 0;
        std::cout << "AIBingo : " << AIBingo << std::endl;
        // Bingo가 5개보다 이상이면 Player승리
        if (Bingo >= 5)
        {
            std::cout << "Player 승리" << std::endl;
            break;
        }
        // Bingo가 5개 이상이 아니고 AIBingo가 5개 이상일 시 AI 승리
        else if (AIBingo >= 5)
        {
            std::cout << "AI 승리" << std::endl;
            break;
        }

        std::cout << "Input Number(0 : Exit) : ";
        std::cin >> Input;
        // Player가 0을 선택시 종료하기 위한 if문
        if (Input == 0)
            break;

        // 1 ~ 25 사이의 숫자가 아니라면 다시 입력하게 한다.
        else if (Input < 0 || Input > 25)
            continue;

        // 입력받은 숫자를 찾아서 *로 바꿔준다.
        // 단, 이미 *로 바뀌어버린 숫자를 다시 입력하면
        // 다시 처음부터 입력받도록 한다.
        // 입력받은 숫자를 찾기위한 Find를 bool변수 false로 선언
        bool    Find = false;

        for (int i = 0; i < 25; ++i)
        {
            // 빙고판의 숫자와 Player가 선택한 숫자가 같으면 Find가 true가 되고
            // Number[i]를 임의의 값 INT_MAX로 설정을 두어 *을 표시하기 위한 구성
            if (Number[i] == Input)
            {
                Find = true;
                Number[i] = INT_MAX;
                break;
            }
        }

        // 만약 못찾았다면 다시 입력받게 한다.
        if (Find == false)
            continue;

        // AI의 빙고숫자에서 플레이어가 입력한 값을 찾아서 *로 바꿔주기 위한 코드 구성
        for (int i = 0; i < 25; ++i)
        {
            if (AINumber[i] == Input)
            {
                AINumber[i] = INT_MAX;
                break;
            }
        }

        // AI가 하나 선택한다. 단, 현재 입력이 안된 숫자 중 하나를 랜덤 하게 선택해야 한다.
        // 선택을 위해서 *이 아닌 일반 숫자들을 배열에 넣어준다.
        // *이 아닌 숫자를 찾아내기위해 while문 밖에서 선언한 변수를 초기화시켜준다.
        SelectCount = 0;
        for (int i = 0; i < 25; ++i)
        {
            if (AINumber[i] != INT_MAX)
            {
                SelectNumber[SelectCount] = AINumber[i];
                ++SelectCount;
            }
        }

        // 여기로 빠져나오면 SelectCount는 SelectNumber 배열에 채워준 값의 개수가 된다.
        int RandIndex = rand() % SelectCount;
        Input = SelectNumber[RandIndex];

        std::cout << "AISelect : " << Input << std::endl;

        // AI가 선택한 숫자로 플레이어의 숫자중 찾아서 *로 바꿔준다.
        for (int i = 0; i < 25; ++i)
        {
            if (Number[i] == Input)
            {
                Number[i] = INT_MAX;
                break;
            }
        }

        // AI가 선택한 숫자로 AI의 숫자 중 찾아서 *로 바꿔준다.
        for (int i = 0; i < 25; ++i)
        {
            if (AINumber[i] == Input)
            {
                AINumber[i] = INT_MAX;
                break;
            }
        }


        // 빙고 줄 수를 체크하기 위함
        // Check1은 가로 줄을 체크하기 위함, Check2는 세로줄을 체크하기 위함
        int Check1 = 0, Check2 = 0;
        int AICheck1 = 0, AICheck2 = 0;

        // 체크 전에 빙고 수를 0으로 초기화 하고 모든 줄에 대해서 줄 수를 다시 체크해주도록 한다.
        Bingo = 0;
        AIBingo = 0;

        for (int i = 0; i < 5; ++i)
        {
            // 한줄 체크하기 전에 0으로 초기화를 해주고 그 줄을 체크하도록 한다.
            Check1 = 0;

            // Check2는 세로 줄을 체크하기 위한 변수이다.
            Check2 = 0;

            AICheck1 = 0;
            AICheck2 = 0;

            for (int j = 0; j < 5; ++j)
            {
                // i * 5 + j 는 가로줄 빙고를 체크하기 위한 코드구성
                if (Number[i * 5 + j] == INT_MAX)
                    ++Check1;
                // j * 5 + i 는 세로줄 빙고를 체크하기 위한 코드구성
                if (Number[j * 5 + i] == INT_MAX)
                    ++Check2;
                // AI도 마찬가지
                if (AINumber[i * 5 + j] == INT_MAX)
                    ++AICheck1;
                
                if (AINumber[j * 5 + i] == INT_MAX)
                    ++AICheck2;
            }

            // 한 줄이 끝났을 경우 위에서 체크해놓은 Check1이 5라면 그 줄은 모두 *로 변환된 줄이다.
            if (Check1 == 5)
                ++Bingo;

            if (Check2 == 5)
                ++Bingo;

            if (AICheck1 == 5)
                ++AIBingo;

            if (AICheck2 == 5)
                ++AIBingo;
        }

        // 대각선 체크
        Check1 = 0;
        AICheck1 = 0;
        // 좌측상단에서 우측 하단 대각선을 보면 +6이 커지게 되는 구성이어서 for문 증감값이 += 6이 된다.
        for (int i = 0; i < 25; i += 6)
        {
            // Player의 코드가 *일때 빙고 체크가 1 증가한다
            if (Number[i] == INT_MAX)
                ++Check1;
            // AI의 코드가 *일때 빙고 체크가 1 증가한다
            if (AINumber[i] == INT_MAX)
                ++AICheck1;
        }
        // 체크(*)가 5일 때 빙고 증가
        if (Check1 == 5)
            ++Bingo;

        if (AICheck1 == 5)
            ++AIBingo;

        Check1 = 0;
        AICheck1 = 0;
        // 오른쪽 상단에서 좌측 상단의 배열을 보면 4씩 증가되어서 for문 증감값이 += 4가 된다.
        for (int i = 4; i <= 20; i += 4)
        {
            if (Number[i] == INT_MAX)
                ++Check1;

            if (AINumber[i] == INT_MAX)
                ++AICheck1;
        }

        if (Check1 == 5)
            ++Bingo;

        if (AICheck1 == 5)
            ++AIBingo;
    }

    return 0;
}

 

여기까지 입니다!! 진짜 엄청길죠!!

위 코드가 빙고를 AI와 대전하면서 플레이할 수 있는 코드랍니다...

진짜 블로그 올리고 코드를 직접 계속 쳐봐야겠어요.

이해하는 거랑 이해해서 코드를 칠 수 있는 거랑은 다르니깐요 ㅠㅠ

그럼 다음에 만나요!!

반응형

'c++' 카테고리의 다른 글

20210719 포인터,함수 ~ 과제  (0) 2021.07.20
20210716 구조체 ~ 포인터1  (0) 2021.07.17
20210714 배열 ~ 빙고 게임 과제  (0) 2021.07.15
20210713 과제 풀이 ~ 난수  (0) 2021.07.13
20210712 반복문 for, while, do while  (0) 2021.07.13

댓글