안녕하세요 틴구입니다.
오늘은 저번에 내주신 빙고 *출력에서 더 진행한
*출력, 빙고 출력, 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 |
댓글