icon안동민 개발노트

간단한 게임 로직 구현


게임 설명

  • 컴퓨터가 1부터 100 사이의 임의의 숫자를 선택합니다.
  • 플레이어는 이 숫자를 맞추기 위해 숫자를 입력합니다.
  • 컴퓨터는 플레이어의 입력이 정답보다 큰지, 작은지, 또는 정답인지 알려줍니다.
  • 플레이어가 숫자를 맞출 때까지 게임은 계속됩니다.
  • 게임이 끝나면 플레이어가 몇 번 시도했는지 알려줍니다.

필요한 C++ 개념

  • 변수와 데이터 타입 int, bool
  • 조건문 if-else
  • 반복문 while
  • 입출력 스트림 cin, cout
  • 난수 생성 (C++ 11의 <random> 라이브러리 사용)

게임 구현

 다음은 숫자 맞추기 게임의 전체 코드입니다. 코드를 단계별로 살펴보고 각 부분의 역할을 이해해 봅시다.

#include <iostream>
#include <random>
#include <ctime>
 
int main() {
    // 난수 생성을 위한 설정
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 100);
 
    // 1에서 100 사이의 난수 생성
    int secretNumber = dis(gen);
    
    int guess;
    int attempts = 0;
    bool isCorrect = false;
 
    std::cout << "1부터 100 사이의 숫자를 맞춰보세요!" << std::endl;
 
    while (!isCorrect) {
        std::cout << "추측한 숫자를 입력하세요: ";
        std::cin >> guess;
        attempts++;
 
        if (guess < secretNumber) {
            std::cout << "너무 작습니다! 더 큰 숫자를 입력하세요." << std::endl;
        } else if (guess > secretNumber) {
            std::cout << "너무 큽니다! 더 작은 숫자를 입력하세요." << std::endl;
        } else {
            isCorrect = true;
            std::cout << "정답입니다! " << attempts << "번 만에 맞추셨습니다." << std::endl;
        }
    }
 
    return 0;
}

코드 설명

  1. 필요한 헤더 파일 포함
#include <iostream>
#include <random>
#include <ctime>
  • <iostream> : 입출력을 위해 필요합니다.
  • <random> : C++ 11에서 도입된 난수 생성을 위한 라이브러리입니다.
  • <ctime> : 시간을 시드로 사용하기 위해 포함합니다.
  1. 난수 생성 설정
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 100);
  • std::random_device : 난수 생성을 위한 시드를 제공합니다.
  • std::mt19937 : 메르센 트위스터 난수 생성기입니다.
  • std::uniform_int_distribution : 1부터 100 사이의 균일한 정수 분포를 생성합니다.
  1. 게임에 필요한 변수 선언
int secretNumber = dis(gen);
int guess;
int attempts = 0;
bool isCorrect = false;
  • secretNumber : 컴퓨터가 선택한 비밀 숫자입니다.
  • guess : 플레이어가 추측한 숫자를 저장합니다.
  • attempts : 시도 횟수를 기록합니다.
  • isCorrect : 정답을 맞췄는지 여부를 나타냅니다.
  1. 게임 루프
while (!isCorrect) {
    // 게임 로직
}
  • isCorrect가 false인 동안 계속해서 반복합니다.
  1. 사용자 입력 받기
std::cout << "추측한 숫자를 입력하세요: ";
std::cin >> guess;
attempts++;
  • 사용자로부터 추측한 숫자를 입력받고, 시도 횟수를 증가시킵니다.
  1. 조건 검사 및 결과 출력
if (guess < secretNumber) {
    std::cout << "너무 작습니다! 더 큰 숫자를 입력하세요." << std::endl;
} else if (guess > secretNumber) {
    std::cout << "너무 큽니다! 더 작은 숫자를 입력하세요." << std::endl;
} else {
    isCorrect = true;
    std::cout << "정답입니다! " << attempts << "번 만에 맞추셨습니다." << std::endl;
}
  • 추측한 숫자와 비밀 숫자를 비교하여 적절한 메시지를 출력합니다.
  • 정답을 맞췄을 경우, isCorrect를 true로 설정하여 게임을 종료합니다.

실행 결과

 프로그램을 실행하면 다음과 같은 결과를 볼 수 있습니다.

1부터 100 사이의 숫자를 맞춰보세요!
추측한 숫자를 입력하세요: 50
너무 큽니다! 더 작은 숫자를 입력하세요.
추측한 숫자를 입력하세요: 25
너무 작습니다! 더 큰 숫자를 입력하세요.
추측한 숫자를 입력하세요: 37
너무 작습니다! 더 큰 숫자를 입력하세요.
추측한 숫자를 입력하세요: 43
정답입니다! 4번 만에 맞추셨습니다.

실습

 1. 난이도 선택 : 게임 시작 전 사용자가 난이도(쉬움: 1-50, 보통: 1-100, 어려움: 1-200)를 선택할 수 있게 만들어보세요.

 2. 제한된 시도 횟수 : 최대 시도 횟수를 정하고, 그 횟수 안에 맞추지 못하면 게임 오버가 되도록 수정해보세요.

 3. 점수 시스템 : 시도 횟수에 반비례하는 점수 시스템을 구현해보세요.

 4. 다시 하기 기능 : 게임이 끝난 후 사용자가 다시 게임을 할 수 있는 옵션을 추가해보세요.

 5. 힌트 시스템 : 일정 횟수마다 비밀 숫자의 범위를 좁혀주는 힌트를 제공하는 기능을 추가해보세요.

주의사항

 1. 입력 검증

 사용자가 유효하지 않은 입력(예 : 문자나 범위 밖의 숫자)을 할 경우를 대비한 예외 처리를 추가하는 것이 좋습니다.

 2. 난수 생성

 C++ 11 이전 버전에서는 rand() 함수를 사용했지만, 이는 품질이 좋지 않은 난수를 생성할 수 있습니다.

 가능하면 C++ 11의 <random> 라이브러리를 사용하는 것이 좋습니다.

 3. 코드 구조화

 게임 로직을 함수로 분리하여 코드를 더 구조화하고 가독성을 높일 수 있습니다.

결론

 이 실습을 통해 조건문, 반복문, 그리고 기본적인 입출력 처리를 활용하여 간단한 게임을 구현해보았습니다.

 이러한 기본적인 프로그래밍 개념들은 더 복잡한 프로그램을 개발할 때도 핵심적인 역할을 합니다.

 발전 과제를 통해 프로그램을 개선해보면서 C++ 프로그래밍 실력을 더욱 향상시킬 수 있을 것입니다.


 참고자료

  • C++ 공식 문서의 난수 생성 관련 페이지 : C++ Random
  • 게임 프로그래밍 패턴 (Robert Nystrom 저) : 게임 개발에 사용되는 다양한 설계 패턴을 소개합니다.
  • "Effective C++" (Scott Meyers 저) : C++ 프로그래밍의 더 깊은 이해를 위한 필독서입니다.