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
반응형
'C++' 카테고리의 다른 글
[C++] 코딩 스타일: 모범 사례로 코드 깨끗하게 만들기 ✍️ (2) | 2025.01.09 |
---|---|
[C++] 테스트와 디버깅 도구로 코드 품질 보장하기 🛠️ (1) | 2025.01.09 |
[C++] 디자인 패턴: 싱글톤, 팩토리, 데코레이터 구현하기 🏗️ (2) | 2025.01.08 |
[C++] 커스텀 STL Allocator로 메모리 최적화하기 🛠️ (0) | 2025.01.08 |
[C++] 고성능 프로그래밍: 메모리 정렬과 SIMD 활용하기 ⚡ (3) | 2025.01.08 |