간단한 프로그램
빙고 게임 구현하기
ShadowEye
2021. 6. 10. 08:01
1. 빙고게임 규칙??
- 플레이어와 컴퓨터는 각자 5x5판에 1부터 25까지 숫자가 랜덤한위치에 존재
- 플레이어와 컴퓨터가 돌아가면서 1개의 숫자를 말하고 5개의 숫자가 가로 세로 혹은 대각선에 있을시 빙고
- 둘중 빙고를 3개 성공시 해당플레이어는 승리하고 게임 종료
2. 사용된 키워드
- 중복되지 않는 난수발생기
- 컴퓨터와 플레이어의 데이터 저장하는 자료구조는 구조체를 사용
- 컴퓨터와 플레이어가 공유하는 불러진 숫자판은 배열체 자료구조를 전역변수로 사용
- 구조체를 매개변수로 넘길때 참조형으로 넘김
- 배열을 이차배열이 아닌 1차배열로 구현 (이유는 연습)
3. 코드
#include <iostream>
#include <time.h>
#include <string>
#include <string.h>
#include <Windows.h>
using namespace std;
//빙고만들기
//숫자 입력시 특수기호로 변경
//빙고 카운트가 3이면 끝
//빙고만들기2
//컴퓨터가 존재
enum class ROUND {PLAYER, COMPUTER};
bool checkNum[25] = {};
#define Max 25
struct Bingo
{
string name = "";
int bingo[Max] = {};
int count = 0;
bool checkPos[Max] = {};
void RandomNumGen() {
bool checkNum1[Max] = {};
for (size_t i = 0; i < Max; i++)
{
bool isCheck = true;
while (isCheck)
{
int randNum = rand() % Max;
if (checkNum1[randNum] == false)
{
bingo[i] = randNum + 1;
checkNum1[randNum] = true;
isCheck = false;
}
}
}
}
};
void DrawBingo(Bingo& bingo);
int CheckBingo(Bingo bingo);
void PlayerInput(Bingo& player, Bingo& computer);
int ComputerInput(Bingo& player, Bingo& computer);
//int playerCrossCount = 0;
//int computerCrossCount = 0;
int main(){
//빙고판 랜덤 구현
srand((int)time(NULL));
Bingo player,computer;
player.RandomNumGen();
player.name = "player";
computer.RandomNumGen();
computer.name = "computer";
ROUND round1 = ROUND::PLAYER;
cout << "Game 시작" << endl;
while (player.count < 3 && computer.count < 3)
{
int input;
system("cls");
for (size_t i = 0; i < Max; i++)
{
if (checkNum[i])
{
cout << i+1 << " ";
}
}
cout << endl;
cout<< player.count << "," << computer.count << endl;
DrawBingo( player);
DrawBingo( computer);
if (round1 == ROUND::PLAYER)
{
PlayerInput(player, computer);
round1 = ROUND::COMPUTER;
}
else {
Sleep(1000);
int temp = ComputerInput(player, computer);
cout << "컴퓨터의 선택은 : " << temp << "입니다." << endl;
round1 = ROUND::PLAYER;
}
}
cout << "게임 끝" << endl;
}
void PlayerInput(Bingo& player, Bingo& computer) {
string text = "값을 입력해주세요";
int input;
while (true)
{
cout << text << " : ";
cin >> input;
if (input > 0 && input < Max+1)
{
if (checkNum[input - 1] == false)
{
checkNum[input - 1] = true;
for (size_t i = 0; i < Max; i++)
{
if (player.bingo[i] == input)
{
player.checkPos[i] = true;
}
if (computer.bingo[i] == input)
{
computer.checkPos[i] = true;
}
}
text = "값을 입력해주세요";
return;
}
else {
text = "해당 입력값은 이미 존재합니다. 다시 입력해주세요";
}
}
else {
text = "해당 입력값이 지정범위를 벗어났습니다. 다시 입력해주세요";
}
}
}
int ComputerInput(Bingo& player, Bingo& computer) {
while (true)
{
int randNum = rand() % Max;
if (checkNum[randNum] == false)
{
for (size_t i = 0; i < Max; i++)
{
if (player.bingo[i] == randNum + 1)
{
player.checkPos[i] = true;
}
if (computer.bingo[i] == randNum + 1)
{
computer.checkPos[i] = true;
}
}
checkNum[randNum] = true;
return randNum;
}
}
}
void DrawBingo(Bingo& bingo) {
cout << "+----+----+----+----+----+" << endl;
for (size_t i = 0; i < Max; i++)
{
//true일경우 숫자임
if (bingo.checkPos[i])
cout << "| * ";
//false일경우 별표
else
if (bingo.bingo[i] > 9)
cout << "| "<< bingo.bingo[i] << " ";
else
cout << "| " << bingo.bingo[i] << " ";
if (i % 5 == 4) {
cout << "|" << endl;
cout << "+----+----+----+----+----+" << endl;
}
}
bingo.count = CheckBingo(bingo);
cout << "=========================================" << endl;
cout << "현재 "<< bingo.name<<"의 빙고 개수 : " << bingo.count << endl;
cout << "=========================================" << endl;
cout << endl;
}
int CheckBingo(Bingo bingo) {
//가로체크
bool isHorizontalLine[5] = {};
bool isVerticalLine[5] = {};
bool isCrossLine = false;
bool isInvertCrossLine = false;
int answer = 0;
for (size_t i = 0; i < Max; i++)
{
int horiLine = i / 5;
int vertiLine = i % 5;
//cout << horiLine << "," << vertiLine << " || " << hori[horiLine] << "||" << verti[vertiLine] << endl;
//가로
//세로라인 horiLine번째가 아직 false일경우 별표인지 체크
if (isHorizontalLine[horiLine] == false)
{
//현재 자리가 별표가 아니므로(true) 현재 라인은 이후 확인하지 않기
if (!bingo.checkPos[i])
{
isHorizontalLine[horiLine] = true;
}
}
//세로
//세로라인 vertiLine번째가 아직 false일경우 별표인지 체크
if (isVerticalLine[vertiLine] == false)
{
//현재 자리가 별표가 아니므로(true) 현재 라인은 이후 확인하지 않기
if (!bingo.checkPos[i])
{
isVerticalLine[vertiLine] = true;
}
}
//대각선
//현재 대각선 라인이 트루인지 체크
if (!isCrossLine)
{
//cout << "대각선 체크 : " << i % 6 << " " << checkPos[i] << endl;
//현재 자리가 6으로 나눠지면 대각선 자리에 있음
//현재자리가 트루면 숫자이므로 해당 대각선은 크로스가 아님
if (i % 6 == 0 && !bingo.checkPos[i])
{
isCrossLine = true;
}
}
//맨첫자리와 마지막자리는 필요없음
if (i > 0 && i < Max-1)
{
//역대각선
//현재 역대각선 라인이 트루인지 체크
if (!isInvertCrossLine)
{
//cout << "역대각선 체크 : " << i % 4 << " " << checkPos[i] << endl;
//현재 자리가 4으로 나눠지면 역대각선 자리에 있음
//현재자리가 트루면 숫자이므로 해당 역대각선은 크로스가 아님
if (i % 4 == 0 && !bingo.checkPos[i])
{
isInvertCrossLine = true;
}
}
}
}
if (!isCrossLine) answer++;
if (!isInvertCrossLine) answer++;
for (size_t i = 0; i < 5; i++)
{
if (!isHorizontalLine[i]) answer++;
if (!isVerticalLine[i]) answer++;
}
return answer;
}
4.결과
5. 만들고 나서 느낀점
- 그냥 이차배열을 써야겠다...