이 프로젝트에서는 OOP(Object-Oriented Programming) 개념을 활용하여 Text RPG를 구현하였습니다.
코드의 가독성을 높이고 유지보수를 용이하게 하기 위해 파일을 분할하여 관리합니다.
📂 TextRPG
│── 📂 Game
│ ├── Game.h
│ ├── Game.cpp
│── 📂 Field
│ ├── Field.h
│ ├── Field.cpp
│── 📂 Creature
│ ├── Creature.h
│ ├── Creature.cpp
│ ├── Player.h
│ ├── Player.cpp
│ ├── Monster.h
│ ├── Monster.cpp
│── main.cpp
✅ 게임 시작 시 직업 선택
✅ 랜덤으로 몬스터 생성 후 자동 전투
✅ 플레이어의 HP가 0이 될 때까지 전투 반복
✅ 몬스터가 사망하면 새로운 몬스터 생성
✅ 전투 종료 후 다시 직업 선택 가능
main.cpp (메인 엔트리 포인트)#include <iostream>
#include "Game.h"
using namespace std;
// Text RPG - OOP
int main()
{
srand((unsigned int)time(nullptr));
Game game;
game.Init();
while (true)
game.Update();
return 0;
}
srand((unsigned int)time(nullptr)); → 몬스터를 랜덤으로 생성하기 위해 난수 초기화Game 클래스의 Init() 함수를 호출하여 게임 초기화while (true) game.Update(); → 무한 루프를 통해 게임 진행Creature (모든 생명체의 기본 클래스)Creature.h#pragma once
enum CreatureType
{
CT_Player = 0,
CT_Monster = 1
};
class Creature
{
public:
Creature(int creatureType)
: _creatureType(creatureType), _hp(0), _attack(0), _defence(0) {}
virtual ~Creature() {}
virtual void PrintInfo() = 0;
void OnAttacked(Creature* attacker);
bool IsDead() { return _hp <= 0; }
protected:
int _creatureType;
int _hp;
int _attack;
int _defence;
};
Creature.cpp#include "Creature.h"
void Creature::OnAttacked(Creature* attacker)
{
int damage = attacker->_attack - _defence;
if (damage < 0)
damage = 0;
_hp -= damage;
if (_hp < 0)
_hp = 0;
}
Creature 클래스는 플레이어와 몬스터의 공통적인 기능을 제공하는 부모 클래스입니다.OnAttacked() 함수는 공격을 받았을 때 데미지를 계산합니다.IsDead() 함수는 HP가 0 이하인지 확인하여 생사 여부를 반환합니다.Player (플레이어 클래스)Player.h#pragma once
#include "Creature.h"
enum PlayerType
{
PT_Knight = 1,
PT_Archer = 2,
PT_Mage = 3
};
class Player : public Creature
{
public:
Player(int playerType) : Creature(CT_Player), _playerType(playerType) {}
virtual ~Player() {}
virtual void PrintInfo();
protected:
int _playerType;
};
class Knight : public Player
{
public:
Knight() : Player(PT_Knight)
{
_hp = 150;
_attack = 10;
_defence = 5;
}
};
class Archer : public Player
{
public:
Archer() : Player(PT_Archer)
{
_hp = 80;
_attack = 15;
_defence = 3;
}
};
class Mage : public Player
{
public:
Mage() : Player(PT_Mage)
{
_hp = 50;
_attack = 25;
_defence = 3;
}
};
Player.cpp#include "Player.h"
#include <iostream>
using namespace std;
void Player::PrintInfo()
{
cout << "-------------------------\n";
cout << "[Player] HP : " << _hp << ", ATT : " << _attack << ", DEF : " << _defence << '\n';
cout << "-------------------------\n";
}
Player 클래스는 Creature를 상속받으며, 기사, 궁수, 마법사 직업을 정의합니다.PrintInfo()를 통해 플레이어의 정보를 출력합니다.Monster (몬스터 클래스)Monster.h#pragma once
#include "Creature.h"
enum MonsterType
{
MT_Slime = 1,
MT_Orc = 2,
MT_Skeleton = 3
};
class Monster : public Creature
{
public:
Monster(int monsterType) : Creature(CT_Monster), _monsterType(monsterType) {}
virtual void PrintInfo();
protected:
int _monsterType;
};
class Slime : public Monster
{
public:
Slime() : Monster(MT_Slime)
{
_hp = 50;
_attack = 5;
_defence = 2;
}
};
class Orc : public Monster
{
public:
Orc() : Monster(MT_Orc)
{
_hp = 80;
_attack = 8;
_defence = 3;
}
};
class Skeleton : public Monster
{
public:
Skeleton() : Monster(MT_Skeleton)
{
_hp = 100;
_attack = 15;
_defence = 4;
}
};
Monster.cpp#include "Monster.h"
#include <iostream>
using namespace std;
void Monster::PrintInfo()
{
cout << "-------------------------\n";
cout << "[Monster] HP : " << _hp << ", ATT : " << _attack << ", DEF : " << _defence << '\n';
cout << "-------------------------\n";
}
Monster 클래스는 Creature를 상속받으며, 슬라임, 오크, 스켈레톤 몬스터를 정의합니다.Field (전투 및 몬스터 생성)Field.h#pragma once
class Player;
class Monster;
class Field
{
public:
Field();
~Field();
void Update(Player* player);
void CreateMonster();
void StartBattle(Player* player);
private:
Monster* _monster;
};
Field.cpp#include "Field.h"
#include <stdlib.h>
#include "Monster.h"
#include "Player.h"
Field::Field() : _monster(nullptr) {}
Field::~Field()
{
if (_monster != nullptr)
delete _monster;
}
void Field::Update(Player* player)
{
if (_monster == nullptr)
CreateMonster();
StartBattle(player);
}
void Field::CreateMonster()
{
int randValue = rand() % 3 + 1;
switch (randValue)
{
case MT_Slime:
_monster = new Slime();
break;
case MT_Orc:
_monster = new Orc();
break;
case MT_Skeleton:
_monster = new Skeleton();
break;
}
}
Game (게임 관리)Game.h#pragma once
class Player;
class Field;
class Game
{
public:
Game();
~Game();
void Init();
void Update();
void CreatePlayer();
private:
Player* _player;
Field* _field;
};