본문 바로가기
C++

[C++] 실전 프로젝트로 배우는 코딩: 작은 게임 만들기 💻

by 다다면체 2025. 1. 9.
728x90
반응형

반응형

안녕하세요! 오늘은 간단한 틱택토 게임을 만들면서 C++ 코딩 실력을 한 단계 끌어올리는 시간을 가져보겠습니다. 이 프로젝트를 통해 기본 문법부터 체계적인 코드 설계까지 경험하며 실력 향상에 큰 도움이 될 것입니다. 함께 시작해볼까요?

1. 틱택토 게임 구현 (핵심 기능)🎮

틱택토는 간단하지만 게임 로직과 구조 설계를 배우기에 아주 좋은 예제입니다. 다음 단계에 따라 게임을 구현해 보겠습니다.

핵심 구현 요소:

  • 게임 보드 관리: 2차원 배열( std::vector<std::vector<char>> )을 사용하여 게임 상태를 저장합니다. 각 칸은 'X', 'O', 또는 빈 칸(' ')으로 표현됩니다.
  • 사용자 입력 처리: 사용자가 입력한 위치가 유효한지 검증합니다. (범위 초과, 이미 채워진 칸 등)
  • 승리 조건 확인: 가로, 세로, 대각선 방향으로 같은 기호가 3개 연속으로 있는지 확인합니다.
  • 무승부 확인: 모든 칸이 채워졌지만 승자가 없는 경우 무승부로 처리합니다.
  • 게임 루프: 게임이 끝날 때까지 플레이어의 입력을 반복적으로 처리합니다.

코드 예제:

#include <iostream>
#include <vector>
#include <string>

class TicTacToe {
private:
    std::vector<std::vector<char>> board;
    char currentPlayer;

    void printBoard() {
        for (const auto& row : board) {
            for (const auto& cell : row) {
                std::cout << cell << " ";
            }
            std::cout << std::endl;
        }
    }

    bool isWinner() {
        for (int i = 0; i < 3; ++i) {
            if (board[i][0] == currentPlayer && board[i][1] == currentPlayer && board[i][2] == currentPlayer) return true;
            if (board[0][i] == currentPlayer && board[1][i] == currentPlayer && board[2][i] == currentPlayer) return true;
        }
        if (board[0][0] == currentPlayer && board[1][1] == currentPlayer && board[2][2] == currentPlayer) return true;
        if (board[0][2] == currentPlayer && board[1][1] == currentPlayer && board[2][0] == currentPlayer) return true;
        return false;
    }

    bool isDraw() {
        for (const auto& row : board) {
            for (const auto& cell : row) {
                if (cell == ' ') return false;
            }
        }
        return true;
    }

public:
    TicTacToe() : board(3, std::vector<char>(3, ' ')), currentPlayer('X') {}

    void play() {
        while (true) {
            printBoard();
            int row, col;
            std::cout << "Player " << currentPlayer << ", enter row and column (0-2): ";
            std::cin >> row >> col;

            if (row < 0 || row > 2 || col < 0 || col > 2 || board[row][col] != ' ') {
                std::cout << "Invalid move. Try again." << std::endl;
                continue;
            }

            board[row][col] = currentPlayer;
            if (isWinner()) {
                printBoard();
                std::cout << "Player " << currentPlayer << " wins!" << std::endl;
                break;
            }
            if (isDraw()) {
                printBoard();
                std::cout << "It's a draw!" << std::endl;
                break;
            }

            currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
        }
    }
};

int main() {
    TicTacToe game;
    game.play();
    return 0;
}

2. 게임 상태 저장 및 불러오기 (파일 입출력)🔐

게임 진행 상황을 파일에 저장하고 불러오는 기능을 추가하여 편의성을 높일 수 있습니다.

 

파일 저장 및 로드 예제:

#include <fstream>

void saveGame(const std::vector<std::vector<char>>& board, const std::string& filename) {
    std::ofstream outFile(filename);
    if (!outFile) {
        std::cerr << "Error opening file for saving!" << std::endl;
        return;
    }
    for (const auto& row : board) {
        for (const auto& cell : row) {
            outFile << cell;
        }
        outFile << std::endl;
    }
    outFile.close();
}

void loadGame(std::vector<std::vector<char>>& board, const std::string& filename) {
    std::ifstream inFile(filename);
    if (!inFile) {
        std::cerr << "Error opening file for loading!" << std::endl;
        return;
    }
    std::string line;
    for (int i = 0; i < 3 && std::getline(inFile, line); ++i) {
        for (int j = 0; j < 3; ++j) {
            board[i][j] = line[j];
        }
    }
    inFile.close();
}

 

  • 저장/로드 시 현재 플레이어 정보도 함께 저장/로드해야 합니다.
  • 파일 형식을 좀 더 명확하게 정의하여 오류 발생 가능성을 줄일 수 있습니다. (예: JSON 또는 간단한 텍스트 포맷)

3. 코드 모듈화 및 클래스 분리 (고급 설계)🔧

더욱 체계적인 코드 관리를 위해 기능을 분리하여 클래스로 구성하는 것이 좋습니다.

모듈화 예시:

  • GameLogic: 게임 규칙, 승리 조건, 무승부 판단 등 게임 로직을 담당합니다.
  • UIHandler: 사용자 입력 처리, 게임 보드 출력 등 사용자 인터페이스를 담당합니다.
  • FileHandler: 파일 저장 및 로드를 담당합니다.

예시 (간략):

C++
 
class GameLogic {
public:
    // ... 게임 로직 관련 함수들 ...
};

class UIHandler {
public:
    // ... 사용자 인터페이스 관련 함수들 ...
};

class FileHandler {
public:
    // ... 파일 입출력 관련 함수들 ...
};
  • 각 클래스 간의 관계를 명확히 정의하고, 의존성을 최소화하는 설계를 고려해야 합니다.
  • 싱글톤 패턴, 팩토리 패턴 등 디자인 패턴을 적용하여 코드의 유연성과 확장성을 높일 수 있습니다.

4. 추가 기능 및 확장 방향🚀

  • 인공지능(AI) 추가: 간단한 AI를 구현하여 컴퓨터와 대전하는 기능을 추가할 수 있습니다. (Minimax 알고리즘 등)
  • 그래픽 인터페이스(GUI) 추가: 콘솔 기반이 아닌 창 기반의 게임으로 만들 수 있습니다. (Qt, SFML 등 라이브러리 활용)
  • 네트워크 기능 추가: 두 명의 플레이어가 네트워크를 통해 게임을 즐길 수 있도록 기능을 추가할 수 있습니다.

5. 마무리🎉

이 튜토리얼을 통해 틱택토 게임을 직접 구현해보면서 C++ 코딩의 기초부터 객체 지향 설계까지 다양한 경험을 하셨으리라 생각합니다. 이 프로젝트를 발판 삼아 더욱 복잡하고 흥미로운 프로젝트에 도전해보세요! 궁금한 점이 있다면 언제든지 질문해주세요.

728x90
반응형