1. main.cpp
#include "Status.h"
#include "Player.h"
#include "Warrior.h"
#include "Magician.h"
#include "Thief.h"
#include "Archer.h."
#include <cstdlib>
#include <iostream>
using namespace std;
//step1 ~ step2
int main() {
string name;
const int SIZE = 4;
int stat[SIZE] = { 0 };
//stat[0] = hp, stat[1] = mp, stat[2] = attack, stat[3] = defense
cout << "===========================================" << endl;
cout << " [ 던전 탈출 텍스트 RPG ] " << endl;
cout << "===========================================" << endl;
cout << "용사의 이름을 입력해주세요: ";
cin >> name;
while (true) {
cout << "\nHP와 MP를 입력해주세요: ";
cin >> stat[0] >> stat[1];
if (stat[0] > 50 && stat[1] > 50) {
break;
}
else {
cout << "HP나 MP의 값이 너무 작습니다. 다시 입력해주세요." << endl;
}
}
while (true) {
cout << "공격력과 방어력을 입력해주세요: ";
cin >> stat[2] >> stat[3];
if (stat[2] > 50 && stat[3] > 50) {
break;
}
else {
cout << "공격력이나 방어력이 너무 작습니다. 다시 입력해주세요." << endl;
}
}
printStatus(name, stat); //Status.h, Status.cpp
//step3.
int hpPotion = 5;
int mpPotion = 5;
bool isGameStart = false;
cout << "\n* HP 포션 5개, MP 포션 5개가 기본 지급되었습니다." << endl;
system("pause > nul");
while (!isGameStart) {
system("cls");
cout << "\n============================================" << endl;
cout << "< 캐릭터 강화 >" << endl;
cout << "1. HP UP 2. MP UP 3. 공격력 2배" << endl;
cout << "4. 방어력 2배 5. 현재 능력치 0. 게임 시작" << endl;
cout << "============================================" << endl;
cout << "번호를 선택해주세요: ";
int choice;
cin >> choice;
switch (choice) {
case 1: //hp포션 사용
if (hpPotion > 0) {
stat[0] += 20;
hpPotion--;
cout << "* HP가 20 증가했습니다. (HP 포션 차감: 남은 포션 " << hpPotion << "개)" << endl;
system("pause > nul");
}
else {
cout << "포션 부족! HP 포션이 없습니다." << endl;
system("pause > nul");
}
break;
case 2: //mp포션 사용
if (mpPotion > 0) {
stat[1] += 20;
mpPotion--;
cout << "* MP가 20 증가했습니다. (MP 포션 차감: 남은 포션 " << mpPotion << "개)" << endl;
system("pause > nul");
}
else {
cout << "포션 부족!MP 포션이 없습니다." << endl;
system("pause > nul");
}
break;
case 3: //공격력 2배
stat[2] *= 2;
cout << "* 공격력이 2배가 되었습니다. (현재 공격력: " << stat[2] << ")" << endl;
system("pause > nul");
break;
case 4: //방어력 2배
stat[3] *= 3;
cout << "* 방어력이 2배가 되었습니다. (현재 방어력: " << stat[3] << ")" << endl;
system("pause > nul");
break;
case 5: //상태창 출력
printStatus(name, stat);
system("pause > nul");
break;
case 0: //게임 시작 -> isGameStart = true
cout << "게임을 시작합니다!" << endl;
isGameStart = true;
system("pause > nul");
break;
default: //번호 입력 잘못했을 때 다시 while문 처음으로
cout << "잘못된 번호입니다. 다시 선택해주세요." << endl;
system("pause > nul");
break;
}
}
//step4. 직업 선택
Player* player = nullptr; //Player* Player타입의 객체를 가리키는 포인터(player)
//= nullptr; 로 일단 포인터를 비워둠. 나중에 직업을 가리키기 위함
//new를 이용해서 각자 직업을 케이스별로 할당
bool isjConfirmed = false;
while (!isjConfirmed) {
cout << "\n< 전직 시스템 >" << endl;
cout << name << "님, 직업을 선택해주세요!" << endl;
cout << "1. 전사 2. 마법사 3. 도적 4. 궁수" << endl;
cout << "선택: ";
int jChoice;
cin >> jChoice;
//혹시 모르니까 한번 더 메모리를 비워줌
if (player != nullptr) {
delete player;
player = nullptr;
}
switch (jChoice) {
case 1: //전사
player = new Warrior(name, stat[0], stat[1], stat[2], stat[3]);
cout << "* " << player->getJob() << "로 전직하였습니다. (HP + 30)" << endl;
player->attack();
break;
case 2: //마법사
player = new Magician(name, stat[0], stat[1], stat[2], stat[3]);
cout << "* " << player->getJob() << "로 전직하였습니다. (MP + 30)" << endl;
player->attack();
break;
case 3: //도적
player = new Thief(name, stat[0], stat[1], stat[2], stat[3]);
cout << "* " << player->getJob() << "로 전직하였습니다. (Power + 10)" << endl;
player->attack();
break;
case 4: //궁수
player = new Archer(name, stat[0], stat[1], stat[2], stat[3]);
cout << "* " << player->getJob() << "로 전직하였습니다. (Power + 5, Defence + 5)" << endl;
player->attack();
break;
default:
cout << "다시 선택해주세요. 1~4 사이의 숫자를 입력해야 합니다." << endl;
continue;
}
//직업 선택 이후 확정 or 다시 선택
if (player != nullptr) {
int QChoice;
cout << "\n[" << player->getJob() << "] 을 선택하셨습니다. 이대로 확정하시겠습니까?" << endl;
cout << "1. 확정 2. 다시 선택\n1 또는 2를 입력하세요: ";
cin >> QChoice;
if (QChoice == 1) { //확정
isjConfirmed = true;
cout << "전직이 완료되었습니다." << endl;
player->printPlayerStatus();
}
else { //다시 선택
delete player;
player = nullptr;
cout << "\n직업을 다시 선택하겠습니다." << endl;
}
}
}
return 0;
}
2-1. Status.h
#ifndef STATUS_H_
#define STATUS_H_
#include <iostream>
#include <string>
using namespace std;
const int SIZE = 4;
void printStatus(string name, int stat[]);
#endif
2-2. Status.cpp
#include "Status.h"
void printStatus(string name, int stat[]) {
cout << "\n====================================" << endl;
cout << " " << name << " 의 현재 능력치" << endl;
cout << "====================================" << endl;
cout << "HP: " << stat[0] << " MP: " << stat[1] << endl;
cout << "공격력: " << stat[2] << " 방어력: " << stat[3] << endl;
cout << "====================================" << endl;
}
3-1. Player.h
#ifndef PLAYER_H_
#define PLAYER_H_
#include <iostream>
#include <string>
using namespace std;
class Player {
protected:
string name;
string job;
int level;
int hp, mp, power, defence;
public:
Player(string name, int hp, int mp, int power, int defence);
virtual ~Player() {} //상속 목적의 부모 클래스의 가상 소멸자
virtual void attack() = 0; //순수 가상 함수(player.cpp) -> 각 직업별 함수 오버라이드
void printPlayerStatus(); //전직 이후의 상태창
//getter와 setter 함수. name, job, hp, mp, power, defence
string getName() { return name; }
string getJob() { return job; }
int getHP() { return hp; } //hp값을 반환해줘야 하니까 int.
void setHP(int value) { hp = value; } //반환할 필요는 없으니까 void. value는 공간을 만들어놓음.
int getMP() { return mp; }
void setMP(int value) { mp = value; }
int getPower() { return power; }
int getDefence() { return defence; }
};
#endif
3-2. Player.cpp
#include "Player.h"
//Player:: Player클래스 안에 있는,
//Player(...) 생성자. 캐릭터가 생성될 때 한번 생성.
// : name(), hp()~ 멤버 초기화 리스트. 생성자 생성한 후에 외부에서 받아온 매개변수로 초기화해라.
Player::Player(string name, int hp, int mp, int power, int defence)
: name(name), hp(hp), mp(mp), power(power), defence(defence), level(1), job("초보자") {
}
void Player::printPlayerStatus() {
cout << "------------------------------------" << endl;
cout << "닉네임: " << name << " | 직업: " << job << " | Lv." << level << endl;
cout << "HP: " << hp << " | MP: " << mp << " | 공격력: " << power << " | 방어력: " << defence << endl;
cout << "------------------------------------" << endl;
}
4. 각각 직업별 헤더 파일(ex)Warrior.h)
#ifndef WARRIOR_H_
#define WARRIOR_H_
#include "Player.h"
//자식 클래스 Warrior가 부모 클래스 Player(public만)를 상속하도록 만듬.
class Warrior : public Player {
public:
Warrior(string name, int hp, int mp, int power, int defence) : Player(name, hp, mp, power, defence) {
job = "전사"; //직업명
hp += 30; //직업 특화 스탯
}
//순수 가상함수 오버라이딩
void attack() override {
cout << "* 거대한 장검을 휘두른다!" << endl; //직업 특수 문자열 출력
}
};
#endif
