발전하는 춘배
[원고, SDL3] 2. 윈도우 오목게임 만들기 기록 1 본문
요새 오목 재밌게 해서 오목만들기로했음.
SDL로 GUI 구현해보는게 목표라서
게임 로직 자체는 간단해야 흥미 안 떨어지고 완성할 듯 싶기도 해서 오목으로 정함.
일단 기본로직완성함.
class User
{
private:
public:
unsigned int totalGameCount;
unsigned int winGameCount;
string nickname;
User(string nickname);
void AddWinGameCount();
~User();
};
User::User(string _nickname)
{
nickname = _nickname;
totalGameCount = winGameCount = 0;
}
void User::AddWinGameCount() {
winGameCount++;
}
User::~User()
{
}
class GameOver
{
private:
User* winner = nullptr;
User* loser = nullptr;
public:
bool isGameOver = false;
GameOver(/* args */);
void SetResult(User _winner, User _loser);
User GetWinner();
~GameOver();
};
GameOver::GameOver(/* args */)
{
}
void GameOver::SetResult(User _winner, User _loser) {
winner = &_winner;
loser = &_loser;
}
User GameOver::GetWinner() {
return *winner;
}
GameOver::~GameOver()
{
}
class Game
{
private:
User user1;
User user2;
array<array<int,BOARDSIZE>, BOARDSIZE> board;
GameOver* gameOver;
bool isUser1Turn;
public:
Game(User user1, User user2);
void StartGame();
bool CheckGameOver(int usernum);
void DisplayBoard();
~Game();
};
Game::Game(User user1, User user2) : user1(user1), user2(user2)
{
board = InitializeBoard();
gameOver = new GameOver();
isUser1Turn = true;
StartGame();
}
Game::~Game()
{
delete gameOver;
}
void Game::StartGame() {
cout << "게임 시작!" << endl;
user1.totalGameCount++;
user2.totalGameCount++;
DisplayBoard();
while (!this->gameOver->isGameOver)
{
// 착수
int x, y;
cin >> x >> y;
while(x >= BOARDSIZE || y >= BOARDSIZE || board[x][y] != 0) {
cout << "잘못된 좌표" << endl;
cin >> x >> y;
}
if(isUser1Turn) {
board[x][y] = 1;
} else {
board[x][y] = 2;
}
DisplayBoard();
// 5목 확인
if(CheckGameOver(isUser1Turn ? 1 : 2)) {
break;
}
// 턴종료
isUser1Turn = !isUser1Turn;
}
// 게임종료
User winner = this->gameOver->GetWinner();
cout << "승자: " << winner.nickname << endl;
winner.AddWinGameCount();
}
void Game::DisplayBoard() {
for (size_t i = 0; i < BOARDSIZE; i++)
{
for (size_t j = 0; j < BOARDSIZE; j++)
{
if(board[i][j] == 0) {
if(i == 0) {
if(j == 0) {
cout << "┌─";
}
else if(j == BOARDSIZE - 1) {
cout << "─┐";
}
else {
cout << "─┬─";
}
}
else if(i == BOARDSIZE - 1) {
if(j == 0) {
cout << "└─";
}
else if(j == BOARDSIZE - 1) {
cout << "─┘";
}
else {
cout << "─┴─";
}
} else {
if (j == 0) {
cout << "├─";
}
else if (j == BOARDSIZE - 1) {
cout << "─┤";
}
else {
cout << "─┼─";
}
}
} else {
if(board[i][j] == 1) {
if(j == 0) {
cout << "○─";
}
else if (j == BOARDSIZE - 1)
cout << "─○";
else
cout << "─○─";
} else {
if(j == 0) {
cout << "●─";
}
else if (j == BOARDSIZE - 1)
cout << "─●";
else
cout << "─●─";
}
}
}
cout << endl;
}
}
bool Game::CheckGameOver(int usernum) {
// TODO: 알고리즘 개선
int cnt = 0;
// 1. 세로췍
for (size_t i = 0; i < BOARDSIZE; i++)
{
for (size_t j = 0; j < BOARDSIZE; j++)
{
if (board[i][j] == usernum)
{
cnt = 1;
for (size_t k = 1; k < 5; k++)
{
if(i+k < BOARDSIZE && board[i+k][j] == usernum) {
cnt++;
if (cnt == 5) {
// 5목완성
this->gameOver->isGameOver = true;
this->gameOver->SetResult(usernum == 1 ? user1 : user2, usernum == 1 ? user2 : user1);
return true;
}
} else {
cnt = 0;
break;
}
}
}
}
}
// 2. 가로췍
for (size_t i = 0; i < BOARDSIZE; i++)
{
for (size_t j = 0; j < BOARDSIZE; j++)
{
if (board[i][j] == usernum)
{
cnt = 1;
for (size_t k = 1; k < 5; k++)
{
if(j+k < BOARDSIZE && board[i][j+k] == usernum) {
cnt++;
if (cnt == 5) {
// 5목완성
this->gameOver->isGameOver = true;
this->gameOver->SetResult(usernum == 1 ? user1 : user2, usernum == 1 ? user2 : user1);
return true;
}
} else {
cnt = 0;
break;
}
}
}
}
}
// 3. 우하향대각선췍
for (size_t i = 0; i < BOARDSIZE; i++)
{
for (size_t j = 0; j < BOARDSIZE; j++)
{
if (board[i][j] == usernum)
{
cnt = 1;
for (size_t k = 1; k < 5; k++)
{
if(i+k < BOARDSIZE && j+k < BOARDSIZE && board[i+k][j+k] == usernum) {
cnt++;
if (cnt == 5) {
// 5목완성
this->gameOver->isGameOver = true;
this->gameOver->SetResult(usernum == 1 ? user1 : user2, usernum == 1 ? user2 : user1);
return true;
}
} else {
cnt = 0;
break;
}
}
}
}
}
// 4. 좌하향대각선췍
for (size_t i = 0; i < BOARDSIZE; i++)
{
for (size_t j = 0; j < BOARDSIZE; j++)
{
if (board[i][j] == usernum)
{
cnt = 1;
for (size_t k = 1; k < 5; k++)
{
if(i+k < BOARDSIZE && j-k >= 0 && board[i+k][j-k] == usernum) {
cnt++;
if (cnt == 5) {
// 5목완성
this->gameOver->isGameOver = true;
this->gameOver->SetResult(usernum == 1 ? user1 : user2, usernum == 1 ? user2 : user1);
return true;
}
} else {
cnt = 0;
break;
}
}
}
}
}
return false;
}
요기 췍게임오버는 진짜 대충 짰음.
알고리즘에 자신이 없어서 그냥 시간 좀 걸리더라도 오류없는 확실한 방법으로..
int main(void) {
// 임시유저
User user1(string("user1"));
User user2(string("user2"));
// 게임 생성
Game game(user1, user2);
return 0;
}
오목 기본로직완성.
렌주룰 적용은 아직 때가 아님
이제 SDL을 써먹어 보자.
반응형
'.원고' 카테고리의 다른 글
| [원고, SDL3] 5. 윈도우 오목 게임 만들기 - 버그해결 (3) | 2025.08.25 |
|---|---|
| [원고, SDL3] 4. 윈도우 오목 게임 만들기 - SDL써서 그래픽 띄우기, 클릭이벤트 써먹기 (1) | 2025.08.24 |
| [원고, SDL3] 3. 윈도우 오목 게임 만들기 - 클래스 파일 분할, 분할컴파일 (3) | 2025.08.24 |
| [원고, SDL3] 1. C++로 게임 개발 기록 1 (0) | 2025.08.23 |
| 회고1 / 피로그래밍22기 1차 팀과제 (0) | 2025.01.01 |
