#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#include <conio.h>
#define MAX_ARRAY_X 5
#define MAX_ARRAY_Y 5
#define MAX_BINGO_NUMBER_RANGE 50
#define MAX_CURSOR 2
#define MAX_PRIORITY 30
typedef unsigned int uint;
void PlayGame(); // 메인게임의 흐름을 관리하는 함수
void InitailizeTable(uint (*bingoTable)[MAX_ARRAY_Y]); // 테이블을 초기화하여 랜덤값을 집어넣어주는 함수
void PrintTable(uint bingoTable[][MAX_ARRAY_Y]);
void SetPriority(int x, int y, uint (*priorityTable)[MAX_ARRAY_Y]); // ai 빙고 테이블을 각 인덱스에 우선순위를 표기하기 위한 함수
bool SetTable(int num, uint (*bingoTable)[MAX_ARRAY_Y], uint(*priorityTable)[MAX_ARRAY_Y], bool ai);
// 빙고테이블에 입력받은 값을 확인하고 알맞은 인덱스에 표기를 하고 true 반환 혹은 그 수가 없거나 이미 입력한 수는 false를 반환
int GetBingoAmount(uint (*bingoTable)[MAX_ARRAY_Y]); // 테이블 내에 완성된 빙고가 몇개인지를 반환하는 함수
int GetAiInput(uint (*priorityTable)[MAX_ARRAY_Y], uint (*bingoTable)[MAX_ARRAY_Y]); // ai 빙고 테이블에서 가장 높은 우선순위를 갖고 있는 인덱스를 반환
int GetGameMode(); // 타이틀화면을 출력하고 메뉴를 선택 메뉴번호를 반환
int main()
{
srand((uint)time(NULL));
uint gameMode;
bool isLoop = true;
while (isLoop)
{
gameMode = GetGameMode();
switch (gameMode)
{
//게임 시작
case 0:
PlayGame();
break;
//게임 끝내기
case 1:
isLoop = false;
break;
}
}
return 0;
}
int GetAiInput(uint(*priorityTable)[MAX_ARRAY_Y], uint(*bingoTable)[MAX_ARRAY_Y])
{
int optimalInput = 0;
int highPoint = 0;
//priorityTable 배열의 모든 값이 0일 경우를 대비해 테이블 위에서 임의 값을 가져온다.
for (int i = 0; i < MAX_ARRAY_X; i++)
{
for (int q = 0; q < MAX_ARRAY_Y; q++)
{
if (bingoTable[i][q] != 0)
{
optimalInput = bingoTable[i][q];
}
}
if (optimalInput != 0)
break;
}
//priorityTable을 통해 가장 최선의 수를 찾아 optimalInput에 넣는다.
for (int i = 0; i < MAX_ARRAY_X; i++)
{
for (int q = 0; q < MAX_ARRAY_Y; q++)
{
if (highPoint < priorityTable[i][q] && priorityTable[i][q] < MAX_PRIORITY)
{
highPoint = priorityTable[i][q];
optimalInput = bingoTable[i][q];
}
}
}
return optimalInput;
}
int GetGameMode()
{
int cursor = 0;
int key = 0;
bool isLoop = true;
while (isLoop)
{
system("cls");
system("color 07");
printf(" ┌───────────────────────┐\n");
printf(" │ │\n");
printf(" │ Bingo game │\n");
printf(" │ vs CPU │\n");
printf(" └───────────────────────┘\n");
printf(" use:↑, ↓, Enter\n\n");
switch (cursor)
{
case 0:
printf(" ▶ 1. Game Start\n");
printf(" 2. Exit Game\n");
break;
case 1:
printf(" 1. Game Start\n");
printf(" ▶ 2. Exit Game\n");
break;
}
key = (int)_getch();
switch (key)
{
case 72:
cursor = (MAX_CURSOR + cursor - 1) % MAX_CURSOR;
break;
case 80:
cursor = (MAX_CURSOR + cursor + 1) % MAX_CURSOR;
break;
case 13:
isLoop = false;
break;
}
}
return cursor;
}
void PlayGame()
{
// 플레이어와 ai를 위한 2차원 배열 선언
uint playerBingoTable[MAX_ARRAY_X][MAX_ARRAY_Y] = {};
uint aiBingoTable[MAX_ARRAY_X][MAX_ARRAY_Y] = {};
uint aiPriorityTable[MAX_ARRAY_X][MAX_ARRAY_Y] = {};
// 플레이어와 ai의 빙고의 수를 세기 위한 변수
uint playerBingo = 0;
uint aiBingo = 0;
// 흐름제어용 변수
bool isLoop = true;
// 플레이어와 ai의 빙고 배열 초기화
InitailizeTable(playerBingoTable);
InitailizeTable(aiBingoTable);
// 플레이어 입력 차례
while (isLoop)
{
while (isLoop)
{
int input;
PrintTable(playerBingoTable);
printf("Input number -> ");
scanf_s("%d", &input);
if (input == 0)
{
printf("You inputed wrong number..!\n");
Sleep(2000);
continue;
}
isLoop = !SetTable(input, playerBingoTable, aiPriorityTable, false);
SetTable(input, aiBingoTable, aiPriorityTable, true);
if (isLoop)
{
printf("You inputed wrong number..!\n");
Sleep(2000);
}
}
isLoop = true;
//빙고확인
playerBingo = GetBingoAmount(playerBingoTable);
aiBingo = GetBingoAmount(aiBingoTable);
if (playerBingo == 5 || aiBingo == 5)
isLoop = false;
// ai 입력 차례
while (isLoop)
{
int input = GetAiInput(aiPriorityTable, aiBingoTable);
PrintTable(playerBingoTable);
isLoop = !SetTable(input, aiBingoTable, aiPriorityTable, true);
SetTable(input, playerBingoTable, aiPriorityTable, false);
if (!isLoop)
{
printf("A.I inputed %d..!", input);
Sleep(3000);
}
}
isLoop = true;
//빙고 확인
playerBingo = GetBingoAmount(playerBingoTable);
aiBingo = GetBingoAmount(aiBingoTable);
if (playerBingo == 5 || aiBingo == 5)
isLoop = false;
}
system("cls");
//승패 확인 후 결과 출력
if (playerBingo == 5)
{
//플레이어 승리
system("color 0a");
printf("Congratulation! You win!\n");
}
else if (aiBingo == 5)
{
//ai 승리
system("color 04");
printf("That's too bad.. You lose...\n");
}
else
{
//무승부
system("color 05");
printf("What!? Draw...\n");
}
Sleep(3000);
system("color 07");
}
void InitailizeTable(uint(*bingoTable)[MAX_ARRAY_Y])
{
int trayArr[25] = {};
int count = 0;
for (int i = 0; i < 25; i++)
{
trayArr[i] = rand() % MAX_BINGO_NUMBER_RANGE + 1;
for (int q = 0; q < i; q++)
{
if (trayArr[q] == trayArr[i])
{
i--;
break;
}
}
}
for (int i = 0; i < MAX_ARRAY_X; i++)
{
for (int q = 0; q < MAX_ARRAY_Y; q++)
{
bingoTable[i][q] = trayArr[count];
count++;
}
}
}
void PrintTable(uint bingoTable[][MAX_ARRAY_Y])
{
system("cls");
printf("┌──┬──┬──┬──┬──┐ 0: Deleted number\n");
for (int i = 0; i < 5; i++)
{
printf("│%2d│%2d│%2d│%2d│%2d│\n", bingoTable[0][i], bingoTable[1][i], bingoTable[2][i], bingoTable[3][i], bingoTable[4][i]);
if (i < 4)
printf("├──┼──┼──┼──┼──┤\n");
}
printf("└──┴──┴──┴──┴──┘\n");
}
void SetPriority(int x, int y, uint(*priorityTable)[MAX_ARRAY_Y])
{
for (int i = 0; i < MAX_ARRAY_X; i++)
{
priorityTable[x][i] += 1;
priorityTable[i][y] += 1;
}
priorityTable[x][y] = MAX_PRIORITY;
}
bool SetTable(int num, uint(*bingoTable)[MAX_ARRAY_Y], uint(*priorityTable)[MAX_ARRAY_Y], bool ai)
{
for (int i = 0; i < MAX_ARRAY_X; i++)
{
for (int q = 0; q < MAX_ARRAY_Y; q++)
{
if (bingoTable[i][q] == num)
{
bingoTable[i][q] = 0;
if (ai)
{
SetPriority(i, q, priorityTable);
}
return true;
}
}
}
return false;
}
int GetBingoAmount(uint(*bingoTable)[MAX_ARRAY_Y])
{
int bingo = 0; //빙고갯수
uint continueousNum = 0; //연속됨을 확인하기 위한 변수
//세로 검사
for (int i = 0; i < MAX_ARRAY_X; i++)
{
for (int q = 0; q < MAX_ARRAY_Y; q++)
{
if (bingoTable[i][q] == 0)
{
continueousNum++;
if (continueousNum == MAX_ARRAY_X)
bingo++;
}
}
continueousNum = 0;
}
//가로 검사
for (int i = 0; i < MAX_ARRAY_Y; i++)
{
for (int q = 0; q < MAX_ARRAY_X; q++)
{
if (bingoTable[q][i] == 0)
{
continueousNum++;
if (continueousNum == MAX_ARRAY_Y)
bingo++;
}
}
continueousNum = 0;
}
//역슬래쉬 검사
for (int i = 0; i < MAX_ARRAY_X; i++)
{
if (bingoTable[i][i] == 0)
{
continueousNum++;
if (continueousNum == MAX_ARRAY_Y)
bingo++;
}
}
continueousNum = 0;
//슬래쉬 검사
for (int i = 0; i < MAX_ARRAY_Y; i++)
{
if (bingoTable[MAX_ARRAY_Y-(i + 1)][i] == 0)
{
continueousNum++;
if (continueousNum == MAX_ARRAY_Y)
bingo++;
}
}
return bingo;
}