2024. 3. 1. 16:39ㆍC++/보드게임 구현
전 페이지에서 이야기한 것처럼 코드 작성을 연습위해 과거에 작성한 보드 게임을 재작성하였다.
리팩토링이라고 이야기하지 않은 이유는 코드의 가독성을 높이기 위해 고치는 도중,
결과 값을 비롯하여 다수의 변수와 함수 이름, 내부 구조가 변경되었기 때문이다.
규칙은 이전과 동일하다.
[규칙]
1. 5 x 5 크기의 게임 보드
2. 숫자 범위 : 1~25
3. 컴퓨터 VS 플레이어 형식으로 각각 게임 보드를 소유하고 있다.
3. 게임 시작 시 게임 보드의 숫자는 무작위로 섞여 플레이어와 컴퓨터의 숫자 순서가 다름.
4. 원하는 숫자를 입력하면 특수 기호(#)이 출력되도록 설정
5. 특수 기호(#)가 같은 줄을 이루면 빙고!
빙고 조건 : 가로, 세로, 대각선
승리 조건 : 컴퓨터보다 먼저 3 빙고를 먼저 달성.
패배 조건 : 컴퓨터가 먼저 3빙고를 달성.
종료 조건 : 3 빙고가 등장하면 종료.
코드
#include<iostream>
#include<vector>
class GameBoard
{
public:
void InitBoard() {
for (int i = 0; i < 25; i++)
{
Number.push_back(i + 1);
}
BoardReset();
}
void RandomShuffle() {
for (int i = 0; i < 14; i++)
{
int randomNum = rand() % 25;
if (randomNum == i)
continue;
std::swap(Number[i], Number[randomNum]);
}
BoardReset();
}
bool Marking(int input)
{
bool checking = IsCheckInputNum(input);
if (!checking)
{
std::cout << "잘못된 값입니다." << std::endl;
std::cout << "다시 입력해주세요." << std::endl;
std::cout << std::endl;
return checking;
}
//입력된 값이 빙고판 안에 존재하는지 확인
//만약 존재하면 해당 번호의 칸은 '#'으로 표시
for (int i = 0; i < Number.size(); i++)
{
if (input == Number[i])
{
isCheckNum = true;
Number[i] = 35;
break;
}
else
{
isCheckNum = false;
}
}
if (isCheckNum)
{
BoardReset();
}
}
void PrintBoard()
{
std::cout << "==============================" << std::endl;
std::cout << "빙고 수 : "<<BingGoCount<<std::endl;
std::cout << "=============================="<<std::endl;
for (int i = 0; i < 5; i++)
{
for (int k = 0; k < 5; k++)
{
if (Board[i][k]==35)
{
std::cout << "| " << char(Board[i][k]) << " |";
}
else
{
if (Board[i][k]<10)
{
std::cout <<"| " << Board[i][k] << " |";
}
else
std::cout <<"| " << Board[i][k] << " |";
}
}
std::cout << std::endl;
}
std::cout << "==============================" << std::endl;
}
void IsCheckBingGo()
{
BingGoCount = 0;
IsCheckBingGoRow();
IsCheckBingGoColumn();
IsCheckBingGoDiagonal1();
IsCheckBingGoDiagonal2();
}
int GetBinGoCount() {
return BingGoCount;
}
private:
std::vector<int> Number;
std::vector<std::vector<int>> Board;
bool isCheckNum;
int BingGoCount =0;
void BoardReset() {
Board.resize(5, std::vector<int>(5, 0));
for (int i = 0; i < 5; i++)
{
for (int k = 0; k < Number.size()/5; k++)
{
Board[i][k] = Number[5 * i + k];
}
}
}
bool IsCheckInputNum(int input) {
bool Checking=false;
for (int i = 0; i < Number.size(); i++)
{
if (input == Number[i])
{
Checking = true;
break;
}
else
{
Checking = false;
}
}
return Checking;
}
void IsCheckBingGoRow() {
//가로 확인
for (int i = 0; i < 5; i++)
{
int count = 0;
for (int k = 0; k < 5; k++)
{
if (Board[i][k] == 35) {
count++;
}
if (count == 5)
{
BingGoCount++;
}
}
}
}
void IsCheckBingGoColumn() {
//세로 확인
for (int i = 0; i < 5; i++)
{
int count = 0;
for (int k = 0; k < 5; k++)
{
if (Board[k][i] == 35) {
count++;
}
if (count == 5)
{
BingGoCount++;
}
}
}
}
void IsCheckBingGoDiagonal1() {
while (true)
{
int count = 0;
for (int i = 0; i < 5; i++)
{
if (Board[i][i] == 35)
{
count++;
}
if (count == 5)
{
BingGoCount++;
break;
}
}
break;
}
}
void IsCheckBingGoDiagonal2() {
while (true)
{
int count = 0;
for (int i = 0; i < 5; i++)
{
if (Board[i][4 - i] == 35)
{
count++;
}
if (count == 5)
{
BingGoCount++;
break;
}
}
break;
}
}
};
int main()
{
srand(time(NULL));
GameBoard player;
GameBoard computer;
int countTurn = rand() % 2;
if (countTurn == 0)
{
countTurn = -1;
}
player.InitBoard();
computer.InitBoard();
player.RandomShuffle();
computer.RandomShuffle();
while (true)
{
if (countTurn > 0)
{
std::cout << std::endl;
std::cout << "플레이어의 턴!!!" << std::endl;
std::cout << std::endl;
}
else
{
std::cout << std::endl;
std::cout << "컴퓨터의 턴!!!" << std::endl;
std::cout << std::endl;
}
std::cout << "==============================" << std::endl;
std::cout << "플레이어의 보드판" << std::endl;
player.PrintBoard();
std::cout << std::endl;
std::cout << "==============================" << std::endl;
std::cout << "컴퓨터의 보드판" << std::endl;
computer.PrintBoard();
if (countTurn > 0)
{
std::cout << "입력할 값 : ";
int input;
std::cin >> input;
bool inputCheckingPlayer = player.Marking(input);
bool inputCheckingComputer = computer.Marking(input);
if (!inputCheckingPlayer && !inputCheckingComputer)
{
continue;
}
countTurn *= -1;
}
else
{
int input = rand() % 25 +1 ;
bool inputCheckingComputer = computer.Marking(input);
bool inputCheckingPlayer = player.Marking(input);
if (!inputCheckingComputer && !inputCheckingPlayer)
{
continue;
}
std::cout << "컴퓨터가 임의의 수를 지정했습니다." << std::endl;
std::cout << "지정된 수 : " << input<<std::endl;
countTurn *= -1;
}
for (int i = 0; i < 2; i++)
{
std::cout << std::endl;
}
player.IsCheckBingGo();
computer.IsCheckBingGo();
int BingGoCountplayer = player.GetBinGoCount();
int BingGoCountcomputer = computer.GetBinGoCount();
bool gameEnd = BingGoCountplayer >= 3 || BingGoCountcomputer >= 3;
if (gameEnd)
{
if (BingGoCountplayer>=3)
{
std::cout << "플레이어의 승리!!!" << std::endl;
}
else
{
std::cout << "컴퓨터의 승리!!!" << std::endl;
}
std::cout << "게임 종료!!" << std::endl;
break;
}
}
}
설명
이전과 동일하게 게임보드를 의미하는 클래스, GameBoard를 생성함.
플레이어와 컴퓨터 모두 GameBoard를 이용하여 게임 보드판을 생성함.
게임 보드 초기화 밒 빙고 확인 함수들을 private로 설정하여 외부에서 간섭하지 못하도록 은닉.
GetBingGoCount 함수로 BingGo 의 값을 반환받음.
함수 설명
InitBoard() : 게임 보드 초기화 및 설정
ㄴ BoardReset() : 1~25 숫차 초기화 및 게임 보드 초기화.
RandomShuffle() : 숫자 무작위로 섞기.
ㄴ BoardReset() : 위의 내용과 동일.
Marking() : 입력된 내용이 게임 보드 내부에 존재하는지 확인하고 있으면 특수 기호(#)으로 변환.
ㄴ BoardReset() : 위의 내용과 동일.
PrintBoard() : 빙고 게임 진행 화면 출력.
IsCheckBingGo() : 특수 기호(#)들이 빙고를 이루는지 확인.
ㄴ IsCheckBingGoRow() : (횡)빙고가 되는지 확인.
ㄴ IsCheckBingGoColumn() : ()빙고가 되는지 확인.
ㄴ IsCheckBingGoDiagonal1() : (대각)빙고가 되는지 확인.
ㄴ IsCheckBingGoDiagonal2() : (대각선)빙고가 되는지 확인.
'C++ > 보드게임 구현' 카테고리의 다른 글
[C++] 빙고 게임 구현 (2024_02_28) (0) | 2024.03.01 |
---|---|
[C++] 트럼프 카드 리팩토링 (0) | 2024.02.27 |
[C++] 섯다 코딩 리팩토링 (1) | 2024.02.27 |
[C++] 트럼프 카드 게임 구현 (1) | 2024.02.26 |
[C++] 섯다 텍스트 게임 구현 (0) | 2024.02.24 |