/*
====================================================================
RPG 스탯 관리 게임 시스템
====================================================================
이 프로그램은 간단한 RPG 캐릭터의 스탯을 관리하는 게임입니다.
사용자는 포션을 사용하고, 스탯을 강화하며, 스킬을 사용할 수 있습니다.
====================================================================
*/
// 라이브러리 포함 (다른 사람이 만든 코드 가져오기)
#include <iostream> // 콘솔 입출력 기능 (cout, cin 등)
#include <limits> // 입력 버퍼 처리를 위한 기능
// 네임스페이스 사용 선언
// std:: 를 매번 쓰지 않고 cout, cin 등을 바로 사용할 수 있게 해줍니다
using namespace std;
// 함수 선언부 (Function Prototype)
// 컴파일러에게 "이런 함수들이 나중에 나올 예정이야"라고 미리 알려주는 부분
void setPotion(int count, int* p_HPPotion, int* p_MPPotion); // 포션 개수 설정
void showStatus(int hpPotion, int mpPotion, int status[]); // 현재 상태 표시
void healHP(int* p_HPPotion, int status[]); // HP 회복
void healMP(int* p_MPPotion, int status[]); // MP 회복
void enhanceHP(int status[]); // HP 강화
void enhanceMP(int status[]); // MP 강화
void useAttackSkill(int status[]); // 공격 스킬 사용
void useUltimateSkill(int status[]); // 필살기 사용
int getValidInput(); // 안전한 입력받기
// 안전한 숫자 입력을 위한 함수
// 사용자가 문자를 입력했을 때 프로그램이 멈추지 않도록 보호해주는 함수
int getValidInput() {
int value; // 입력받을 숫자를 저장할 변수
// 올바른 숫자가 입력될 때까지 반복
while (!(cin >> value)) { // cin >> value가 실패하면 (문자가 입력되면)
cout << "유효하지 않은 입력입니다. 숫자를 입력해주세요: ";
cin.clear(); // 에러 상태를 초기화
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 입력 버퍼를 비움
}
return value; // 제대로 입력받은 숫자를 돌려줌
}
// 메인 함수 - 프로그램이 시작되는 곳
int main() {
/*
=======================================
게임 데이터 초기화
=======================================
*/
// 캐릭터의 스탯을 저장하는 배열 (크기 4, 모두 0으로 시작)
int status[4] = {0, 0, 0, 0};
// status[0] = HP (체력)
// status[1] = MP (마나)
// status[2] = 공격력
// status[3] = 방어력
// 포션 개수를 저장하는 변수들
int HPPotion = 0; // HP 포션 개수
int MPPotion = 0; // MP 포션 개수
// 게임 시작 시 포션 5개씩 무료 지급!
// 여기서 &를 붙이는 이유: 포인터(주소)를 넘겨주어야 함수에서 값을 바꿀 수 있음
setPotion(5, &HPPotion, &MPPotion);
/*
=======================================
캐릭터 스탯 입력받기
=======================================
*/
// HP와 MP 입력받기 (50보다 커야 함!)
// do-while 루프: 조건에 맞을 때까지 계속 반복
do {
cout << "HP를 입력하세요 (50보다 큰 값): ";
status[0] = getValidInput(); // 안전하게 HP 입력받기
cout << "MP를 입력하세요 (50보다 큰 값): ";
status[1] = getValidInput(); // 안전하게 MP 입력받기
// 만약 HP나 MP 중 하나라도 50 이하라면?
if (status[0] <= 50 || status[1] <= 50) {
cout << "HP와 MP는 모두 50보다 커야 합니다. 다시 입력해주세요." << endl;
}
} while (status[0] <= 50 || status[1] <= 50); // 조건: 둘 다 50보다 클 때까지 반복
// 공격력과 방어력 입력받기 (0보다 커야 함!)
do {
cout << "공격력을 입력하세요 (0보다 큰 값): ";
status[2] = getValidInput(); // 안전하게 공격력 입력받기
cout << "방어력을 입력하세요 (0보다 큰 값): ";
status[3] = getValidInput(); // 안전하게 방어력 입력받기
// 만약 공격력이나 방어력 중 하나라도 0 이하라면?
if (status[2] <= 0 || status[3] <= 0) {
cout << "공격력과 방어력은 모두 0보다 커야 합니다. 다시 입력해주세요." << endl;
}
} while (status[2] <= 0 || status[3] <= 0); // 조건: 둘 다 0보다 클 때까지 반복
// 게임 시작 인사말
cout << "\n*** 스탯 관리 시스템을 시작합니다! ***" << endl;
/*
=======================================
게임 메인 루프 (무한 반복)
=======================================
*/
// while(true): 사용자가 7번(종료)을 선택할 때까지 계속 반복
while (true) {
// 현재 캐릭터 상태를 화면에 보여주기
showStatus(HPPotion, MPPotion, status);
// 게임 메뉴 출력
cout << "\n=== 스탯 관리 메뉴 ===" << endl;
cout << "1. HP 회복" << endl; // HP 포션 사용 → HP +20
cout << "2. MP 회복" << endl; // MP 포션 사용 → MP +20
cout << "3. HP 강화" << endl; // HP를 2배로 만들기
cout << "4. MP 강화" << endl; // MP를 2배로 만들기
cout << "5. 공격 스킬 사용" << endl; // MP 50 소모하는 스킬
cout << "6. 필살기 사용" << endl; // MP의 50% 소모하는 강력한 스킬
cout << "7. 프로그램 종료" << endl; // 게임 끝내기
cout << "선택: ";
// 사용자의 선택을 안전하게 입력받기
int choice = getValidInput();
// 선택에 따라 해당하는 기능 실행하기
switch (choice) {
case 1: // HP 회복 선택
healHP(&HPPotion, status); // HP 회복 함수 호출
break;
case 2: // MP 회복 선택
healMP(&MPPotion, status); // MP 회복 함수 호출
break;
case 3: // HP 강화 선택
enhanceHP(status); // HP 강화 함수 호출
break;
case 4: // MP 강화 선택
enhanceMP(status); // MP 강화 함수 호출
break;
case 5: // 공격 스킬 사용 선택
useAttackSkill(status); // 공격 스킬 함수 호출
break;
case 6: // 필살기 사용 선택
useUltimateSkill(status); // 필살기 함수 호출
break;
case 7: // 종료 선택
cout << "프로그램을 종료합니다." << endl;
return 0; // 프로그램 종료
default:
cout << "잘못된 선택입니다. 1~7 사이의 숫자를 입력해주세요." << endl;
break;
}
}
return 0;
}
/*
====================================================================
함수 정의부 (Function Definition)
====================================================================
*/
// 포션 개수를 설정하는 함수
void setPotion(int count, int* p_HPPotion, int* p_MPPotion) {
*p_HPPotion = count;
*p_MPPotion = count;
}
// 현재 캐릭터 상태를 출력하는 함수
void showStatus(int hpPotion, int mpPotion, int status[]) {
cout << "\n--- 현재 캐릭터 상태 ---" << endl;
cout << "HP: " << status[0] << " (HP 포션: " << hpPotion << "개)" << endl;
cout << "MP: " << status[1] << " (MP 포션: " << mpPotion << "개)" << endl;
cout << "공격력: " << status[2] << endl;
cout << "방어력: " << status[3] << endl;
cout << "-------------------------" << endl;
}
// HP 포션을 사용해서 HP를 회복하는 함수
void healHP(int* p_HPPotion, int status[]) {
if (*p_HPPotion > 0) {
status[0] += 20;
(*p_HPPotion)--;
cout << "HP 포션을 사용했습니다! HP가 20 증가했습니다." << endl;
} else {
cout << "HP 포션이 없습니다!" << endl;
}
}
// MP 포션을 사용해서 MP를 회복하는 함수
void healMP(int* p_MPPotion, int status[]) {
if (*p_MPPotion > 0) {
status[1] += 20;
(*p_MPPotion)--;
cout << "MP 포션을 사용했습니다! MP가 20 증가했습니다." << endl;
} else {
cout << "MP 포션이 없습니다!" << endl;
}
}
// HP를 2배로 강화하는 함수
void enhanceHP(int status[]) {
status[0] *= 2;
cout << "HP 강화를 실행했습니다! HP가 2배로 증가했습니다." << endl;
}
// MP를 2배로 강화하는 함수
void enhanceMP(int status[]) {
status[1] *= 2;
cout << "MP 강화를 실행했습니다! MP가 2배로 증가했습니다." << endl;
}
// 공격 스킬을 사용하는 함수
void useAttackSkill(int status[]) {
if (status[1] >= 50) {
status[1] -= 50;
cout << "공격 스킬을 사용했습니다! MP 50을 소모했습니다." << endl;
} else {
cout << "MP가 부족합니다! (필요 MP: 50)" << endl;
}
}
// 필살기를 사용하는 함수
void useUltimateSkill(int status[]) {
if (status[1] > 0) {
int mpCost = status[1] / 2;
status[1] -= mpCost;
cout << "필살기를 사용했습니다! MP " << mpCost << "를 소모했습니다." << endl;
} else {
cout << "MP가 없어서 필살기를 사용할 수 없습니다!" << endl;
}
}


| 어려웠던 점 | 설명 |
|---|---|
*와 &의 차이 혼동 | 포인터를 사용할 때 값이 바뀌지 않아 원인을 찾는 데 시간이 걸렸음 |
| 주소를 넘겨줘야 하는 이유 이해 지연 | 함수 호출 시 값이 아닌 주소를 넘겨야 하는 이유를 이해하는 데 시간이 걸렸음 |
cin.clear()와 cin.ignore() 사용법 생소 | 입력 오류 처리 방법을 처음 접해서 동작 원리를 이해하는 데 어려움이 있었음 |
| 입력 버퍼 미처리로 인한 무한 루프 | 버퍼를 비워주지 않아 프로그램이 무한 반복되는 문제를 경험했음 |