[C++] Bingo


배열까지 배우고 배운 것(난수, 배열)을 활용해서 컴퓨터와 빙고하기를 만들어보았다.

소스코드를 저장하기 위해서 이 포스트를 작성하였다.

음.. AI는 단순히 난수를 활용하는 것이기 때문에 조금 단순한 빙고가 되겠지만

혹시 딥러닝을 활용하면 최선의 경우를 찾아서 더 재밌게 빙고를 할 수 있지 않을까?

그나저나 수업 때 배운 것에 살을 붙여서 AI랑 하는 것을 만들어본건데

잘못하면 스파게티 코드가 될 것 같다..

소스코드

#include <iostream>
#include <ctime>

void bingo_checking(bool my_turn, int check_number);
void input_ing(bool my_turn);

// 전역변수 목록
const int	numbers = 5;
const int	square = numbers * numbers;
const int	Exit = 0;
int	num[square] = {};
int	my_bingo = 0;
int AI_bingo = 0;
bool is_my_turn = true;
int count = 0; // 총 숫자 몇개를 입력받았는지 체크하는 카운트

int main()
{
	srand((unsigned int)time(0));
	int Rand = rand();

	/*
	숫자 빙고게임!
	5 x 5 빙고칸을 만들어서 1 ~ 25 사이의 숫자를 고록루 섞어서 출력한다.
	단, 중복되는 숫자는 없어야 한다.

	0을 입력하면 종료하기!
	*/



	for (int i = 0; i < square; i++)
	{
		num[i] = i + 1;
	}

	// 셔플 알고리즘
	for (int i = 0; i < 1000; i++)
	{
		int	Index1 = rand() % square;
		int	Index2 = rand() % square;

		if (Index1 == Index2)
			continue;

		int	tmp = num[Index1];
		num[Index1] = num[Index2];
		num[Index2] = tmp;
	}

	while (true)
	{
		system("cls"); // 도스창 초기화하는 명령어

		for (int i = 0; i < numbers; i++)
		{
			// 가로는 5개를 출력해야 하기 떄문에 5번 반복한다.
			for (int j = 0; j < numbers; j++)
			{
				// 여기서 i가 행, j가 열 역할을 한다!
				// i 값은 0 ~ numbers - 1, j값은 0 ~ numbers - 1 사이로 나오게 된다.
				// 이것을 이용하여 0 ~ square - 1까지 차례로 증가되게 식을 만들어야 한다.
				// 저장된 값이 INT_MAX일 경우 *로 출력하도록 수정해주면 된다!

				if (num[numbers * i + j] == INT_MAX)
					std::cout << '*' << '\t';

				else if (num[numbers * i + j] == INT_MAX - 1)
					std::cout << '#' << '\t';

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

			// 다음 줄로 개행을 한다!
			std::cout << std::endl;
		}

		std::cout << "My_Bingo : " << my_bingo << std::endl;
		std::cout << "AI_Bingo : " << AI_bingo << std::endl;

		if (my_bingo >= 5)
		{
			std::cout << "게임에서 승리하였습니다!" << std::endl;
			break;
		}

		else if (count == square)
		{
			std::cout << "더 이상 숫자를 입력받을 수 없으므로 게임을 종료합니다." << std::endl;
			break;
		}

		input_ing(is_my_turn);
		
	}

	return 0;
}

void input_ing(bool my_turn)
{
	// 나의 턴일 경우 숫자를 입력받는다.

	if (my_turn == true)
	{
		std::cout << "숫자를 입력하세요 (0 : 종료) : ";

		int	input_num = 0;
		std::cin >> input_num;

		if (input_num == Exit)
		{
			std::cout << "종료합니다." << std::endl;
			exit(0);
		}

		else if (input_num < Exit || input_num > square)
			return;

		// 아래의 bool 변수는 25개의 숫자를 반복하며 입력받은 숫자를 찾을 때
		// 25개중 입력받은 숫자가 없을 경우 false,
		// 있을 경우 true를 대입하여
		// 25개의 숫자중 입력받은 숫자가 있는지를 판단할 때 사용한다.
		bool	find = false;

		// 입력받은 숫자를 찾아서 *로 만들어야 한다.
		for (int i = 0; i < square; i++)
		{
			if (num[i] == input_num)
			{
				// 그리고 이미 입력한 값을 다시 입력해도 문제가 발생하지 않도록 만들어줘야한다.
				// 여기에서 true로 바꾸는 코드를 실행하지 못하면 find는 계속해서
				// false를 유지하고 있을 것이다.
				find = true;

				// INT_MAX : int로 표현할 수 있는 최대값 (2147483647)
				// 저장된 값이 INT_MAX일 경우 *로 출력하도록 수정해주면 된다!
				num[i] = INT_MAX;
				count++;
				break;
			}
		}

		// 이미 입력한 숫자를 입력했을 경우 다시 입력받게 하는 코드.
		if (!find)
		{
			std::cout << "이미 입력한 숫자입니다. 다시 입력하세요." << std::endl;
			input_ing(true);
		}
		bingo_checking(my_turn, INT_MAX);
		is_my_turn = false;
	}

	// 상대방의 턴일 경우 숫자를 입력받는다.
	if (my_turn == false)
	{

		// 상대방의 턴에서 숫자 입력 ( 랜덤 )
		int	input_num = rand() % square + 1;

		// 아래의 bool 변수는 25개의 숫자를 반복하며 입력받은 숫자를 찾을 때
		// 25개중 입력받은 숫자가 없을 경우 false,
		// 있을 경우 true를 대입하여
		// 25개의 숫자중 입력받은 숫자가 있는지를 판단할 때 사용한다.
		bool	find = false;

		// 입력받은 숫자를 찾아서 *로 만들어야 한다.
		for (int i = 0; i < square; i++)
		{
			if (num[i] == input_num)
			{
				// 그리고 이미 입력한 값을 다시 입력해도 문제가 발생하지 않도록 만들어줘야한다.
				// 여기에서 true로 바꾸는 코드를 실행하지 못하면 find는 계속해서
				// false를 유지하고 있을 것이다.
				find = true;

				// INT_MAX : int로 표현할 수 있는 최대값 (2147483647)
				// 저장된 값이 INT_MAX일 경우 *로 출력하도록 수정해주면 된다!
				num[i] = INT_MAX - 1;
				count++;
				break;
			}
		}

		// 이미 입력한 숫자를 입력했을 경우 다시 입력받게 하는 코드.
		if (!find)
		{
			input_ing(false);
		}

		bingo_checking(my_turn, INT_MAX - 1);
		is_my_turn = true;
	}
}
void bingo_checking(bool my_turn, int check_number)
{
	// 매번 빙고라인이 몇개인지 체크를 해주므로 임시 저장할 변수 설정.
	int	bingo_check = 0;

	// 여기까지 내려왔다면 정상적인 숫자를 입력하여 *로 바꾸었다는 것.
	// 가로 5줄, 세로 5줄, 대각선 2줄을 조사하여 몇개의 빙고가 완성되었는지 판단해야한다.

	// 가로, 세로, 대각선에 *이 몇개인지 체크하기 위한 변수
	int	check_count_H = 0;
	int	check_count_V = 0;
	int	check_count_X = 0;

	for (int i = 0; i < numbers; i++)
	{
		check_count_H = 0;

		// 가로 1줄을 체크하는 과정
		for (int j = 0; j < numbers; j++)
		{
			if (num[i * numbers + j] == check_number)
				check_count_H++;
		}

		// 위에서 가로 1줄을 체크했을때 check_count가 numbers라면
		// 해당 줄은 모두 *로 바뀌었다는 이야기이다.
		if (check_count_H == numbers)
			bingo_check++;
	}

	for (int i = 0; i < numbers; i++)
	{
		check_count_V = 0;

		// 세로 1줄을 체크하는 과정
		for (int j = 0; j < numbers; j++)
		{
			if (num[numbers * j + i] == check_number)
				check_count_V++;
		}

		// 위에서 세로 1줄을 체크했을때 check_count가 numbers라면
		// 해당 줄은 모두 *로 바뀌었다는 이야기이다.
		if (check_count_V == numbers)
			bingo_check++;
	}

	// 좌상 -> 우하 대각선 체크
	for (int i = 0; i < numbers; i++)
	{
		if (num[numbers * i + i] == check_number)
			check_count_X++;
	}

	// 좌상 -> 우하 대각선 체크 후 빙고 여부 확인
	if (check_count_X == numbers)
		bingo_check++;

	check_count_X = 0;

	// 우상 -> 좌하 대각선 체크
	for (int i = 0; i < numbers; i++)
	{
		if (num[numbers * (i + 1) - (i + 1)] == check_number)
			check_count_X++;
	}

	// 우상 -> 좌하 대각선 체크 후 빙고 여부 확인
	if (check_count_X == numbers)
		bingo_check++;

	// bingo_check를 전역변수 bingo에 대입.
	if (my_turn == true)
		my_bingo = bingo_check;
	else
		AI_bingo = bingo_check;

	return;
}


© 2022.07. by Wookey_Kim

Powered by Hydejack v7.5.2