TIL(21)

이채원·2026년 7월 10일

TIL

목록 보기
21/77

오늘의 할일
1. 코드카타 정리
2. 과제
3. 궁금증 해결
4. 다음 학습 예습

개념 요약


코드카타 정리

n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

int solution(int n) {
    int answer = 0;
    for (int i = 1; i < n; i++) {
        if (n % i == 1) 
        {
            answer = i;
            break;
        }
    }
    return answer;
}

과제

# step 4 - Player 클래스 + 직업 선택 (클래스, 상속, 다형성)

헤더/ 소스파일 안 나눈 버전

ChooseJob.cpp

#include <iostream>
#include <string>
using namespace std;

string name;
const int SIZE = 4;
int playerstat[SIZE] = { 0 };
// {HP, MP, 공격력, 방어력}
int PotionHP = 5;
int PotionMP = 5;
int choice;
bool isGameStart = false;

class Player {
protected :
	string name;
	string job;
	int level;
	int hp;
	int mp;
	int power;
	int defence;

public :
	Player(string name, int hp, int mp, int power, int defence) 
	: name(name), hp(hp), mp(mp), power(power), defence(defence), job("초보자"), level(1) {}

	virtual ~Player() {}

	virtual void attack() = 0;

	void printPlayerStatus() {
		cout << "------------------------------------" << endl;
		cout << "Name: " << name << " | Job: " << job << " | Lv." << level << endl;
		cout << "HP: " << hp << " | MP: " << mp << " | Attack: " << power << " | Defence: " << defence << endl;
		cout << "------------------------------------" << endl;
	}

	string getName() { return name; }
	string getJob() { return job; }
	int getLevel() { return level; }
	int getHp() { return hp; }
	int getMp() { return mp; }
	int getPower() { return power; }
	int getDefence() { return defence; }

	void setName(string name) { this->name = name; }
	void setJob(string job) { this->job = job; }
	void setLevel(int level) { this->level = level; }
	void setHp(int hp) { this->hp = hp; }
	void setMp(int mp) { this->mp = mp; }
	void setPower(int power) { this->power = power; }
	void setDefence(int defence) { this->defence = defence; }
};

class Warrior : public Player {
public:
	Warrior(string name, int hp, int mp, int power, int defence) : Player(name, hp, mp, power, defence) {
		job = "Warrior";
		this->hp += 30;
		cout << "* You became a Warrior! (HP +30)" << endl;

	}
	void attack() override {
		cout << "* Swings a greatsword!" << endl;
	}
};

class Mage : public Player {
public:
	Mage(string name, int hp, int mp, int power, int defence) : Player(name, hp, mp, power, defence) {
		job = "Mage";
		this->mp += 30;
		cout << "* You became a Mage! (MP +30)" << endl;

	}
	void attack() override {
		cout << "* Fires a fireball!" << endl;
	}
};

class Rogue : public Player {
public:
	Rogue(string name, int hp, int mp, int power, int defence) : Player(name, hp, mp, power, defence) {
		job = "Rogue";
		this->power += 30;
		cout << "* You became a Rogue! (POWER +30)" << endl;

	}
	void attack() override {
		cout << "* Stabs with a dagger!" << endl;
	}
};

class Archer : public Player {
public:
	Archer(string name, int hp, int mp, int power, int defence) : Player(name, hp, mp, power, defence) {
		job = "Archer";
		this->defence += 30;
		cout << "* You became a Archer! (DEFENCE +30)" << endl;

	}
	void attack() override {
		cout << "* Shoots an arrow!" << endl;
	}
};

void printTitle()
{
	cout << "===========================================" << endl;
	cout << "	[ Dungeon Escape Text RPG ]" << endl;
	cout << "===========================================" << endl;

}

void statsMenu()
{
	cout << "===========================================" << endl;
	cout << "	" << name << "'s Stats" << endl;
	cout << "===========================================" << endl;
	cout << "HP: " << playerstat[0] << "		MP: " << playerstat[1] << endl;
	cout << "Attack: " << playerstat[2] << "		Defense: " << playerstat[3] << endl;
	cout << endl;
}

void statsCustom()
{
	while (!isGameStart) {
		cout << "===========================================" << endl;
		cout << "	< Character Upgrade >" << endl;
		cout << "1. HP UP    2. MP UP    3. Attack x2" << endl;
		cout << "4. Defense x2  5. Show Stats  0. Start Game" << endl;
		cout << "===========================================" << endl;

		cout << "Choose : ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			system("cls");
			printTitle();
			cout << "Starting the game!" << endl;
			cout << endl;
			cout << "      /| ________________" << endl;
			cout << " O|===|* >________________>" << endl;
			cout << "      ||" << endl;
			isGameStart = true;
			break;

		case 1:
			if (PotionHP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* HP increased by 20. (HP Potion used: " << PotionHP - 1 << " left)" << endl;
			PotionHP -= 1;
			playerstat[0] += 20;
			cout << endl;
			break;

		case 2:
			if (PotionMP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* MP increased by 20. (MP Potion used: " << PotionMP - 1 << " left)" << endl;
			PotionMP -= 1;
			playerstat[1] += 20;
			cout << endl;
			break;

		case 3:
			cout << "* Attack multiplied by 2." << endl;
			playerstat[2] *= 2;
			cout << endl;

			break;

		case 4:
			cout << "* Defense multiplied by 2." << endl;
			playerstat[3] *= 2;
			cout << endl;

			break;

		case 5:
			system("cls");
			printTitle();
			cout << endl;
			statsMenu();
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
}

void enterStats()
{
	while (true)
	{
		cout << "Enter HP and MP: ";
		cin >> playerstat[0];
		cin >> playerstat[1];

		if (playerstat[0] < 50 || playerstat[1] < 50)
		{
			cout << "HP or MP is too low. Try again." << endl;
		}

		else {
			break;
		}
	}

	while (true)
	{
		cout << "Enter Attack and Defense: ";
		cin >> playerstat[2];
		cin >> playerstat[3];

		if (playerstat[2] < 50 || playerstat[3] < 50)
		{
			cout << "Attack or Defense is too low. Try again." << endl;
		}

		else {
			break;
		}
	}
}

Player* createCharacter(string name, int playerstat[]) {
	printTitle();
	cout << "< Job Selection >" << endl;
	cout << name << ", choose your job!" << endl;
	cout << "1. Warrior   2. Mage   3. Rogue   4. Archer" << endl;
	cout << "Choose: ";

	int jobChoice;
	cin >> jobChoice;

	Player* player = nullptr;

	switch (jobChoice) {
	case 1:
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 2:
		player = new Mage(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 3:
		player = new Rogue(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 4:
		player = new Archer(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	default:
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	}
	return player;
}

int main() {
	printTitle();

	cout << "Enter your hero's name: ";
	cin >> name;
	cout << endl;

	enterStats();

	system("cls");
	printTitle();

	statsMenu();

	cout << "* You received " << PotionHP << " HP Potions and " << PotionMP << " MP Potions." << endl;

	statsCustom();

	system("cls");

	Player* player = createCharacter(name, playerstat);

	player->attack();
	player->printPlayerStatus();

	delete player;
	return 0;

}

헤더/소스 파일 나눈 버전

player.h

#pragma once
#include <iostream>
#include <string>

using namespace std;

class Player {
protected:
    string name;
    string job;
    int level;
    int hp;
    int mp;
    int power;
    int defence;

public:
    Player(string name, int hp, int mp, int power, int defence);
    virtual ~Player();

    virtual void attack() = 0;

    void printPlayerStatus();

	string getName() { return name; }
	string getJob() { return job; }
	int getLevel() { return level; }
	int getHp() { return hp; }
	int getMp() { return mp; }
	int getPower() { return power; }
	int getDefence() { return defence; }

	void setName(string name) { this->name = name; }
	void setJob(string job) { this->job = job; }
	void setLevel(int level) { this->level = level; }
	void setHp(int hp) { this->hp = hp; }
	void setMp(int mp) { this->mp = mp; }
	void setPower(int power) { this->power = power; }
	void setDefence(int defence) { this->defence = defence; }
};

player.cpp

#include "Player.h" 


Player::Player(string name, int hp, int mp, int power, int defence): name(name), hp(hp), mp(mp), power(power), defence(defence), job("초보자"), level(1) {}

Player::~Player() {}

void Player::printPlayerStatus() {
    cout << "------------------------------------" << endl;
    cout << "Name: " << name << " | Job: " << job << " | Lv." << level << endl;
    cout << "HP: " << hp << " | MP: " << mp << " | Attack: " << power << " | Defense: " << defence << endl;
    cout << "------------------------------------" << endl;
}

직업별.h

#pragma once
#include "Player.h"

class Rogue : public Player {
public:
    Rogue(string name, int hp, int mp, int power, int defence);
    void attack() override;
};

직업별.cpp

#include "Rogue.h"

Rogue::Rogue(string name, int hp, int mp, int power, int defence)
	: Player(name, hp, mp, power, defence)
{
	job = "Rogue";
	this->power += 30;
	cout << "* You became a Rogue! (POWER +30)" << endl;
}

void Rogue::attack() {
	cout << "* Stabs with a dagger!" << endl;
}

ChooseJob.cpp

#include <iostream>
#include <string>
#include "Player.h"
#include "Warrior.h"
#include "Mage.h"
#include "Rogue.h"
#include "Archer.h"

using namespace std;

string name;
const int SIZE = 4;
int playerstat[SIZE] = { 0 };
// {HP, MP, 공격력, 방어력}
int PotionHP = 5;
int PotionMP = 5;
int choice;
bool isGameStart = false;

void printTitle()
{
	cout << "===========================================" << endl;
	cout << "	[ Dungeon Escape Text RPG ]" << endl;
	cout << "===========================================" << endl;

}

void statsMenu()
{
	cout << "===========================================" << endl;
	cout << "	" << name << "'s Stats" << endl;
	cout << "===========================================" << endl;
	cout << "HP: " << playerstat[0] << "		MP: " << playerstat[1] << endl;
	cout << "Attack: " << playerstat[2] << "		Defense: " << playerstat[3] << endl;
	cout << endl;
}

void statsCustom()
{
	while (!isGameStart) {
		cout << "===========================================" << endl;
		cout << "	< Character Upgrade >" << endl;
		cout << "1. HP UP    2. MP UP    3. Attack x2" << endl;
		cout << "4. Defense x2  5. Show Stats  0. Start Game" << endl;
		cout << "===========================================" << endl;

		cout << "Choose : ";
		cin >> choice;
		cout << endl;

		switch (choice)
		{
		case 0:
			system("cls");
			printTitle();
			cout << "Starting the game!" << endl;
			cout << endl;
			cout << "      /| ________________" << endl;
			cout << " O|===|* >________________>" << endl;
			cout << "      ||" << endl;
			cout << endl;
			isGameStart = true;
			break;

		case 1:
			if (PotionHP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* HP increased by 20. (HP Potion used: " << PotionHP - 1 << " left)" << endl;
			PotionHP -= 1;
			playerstat[0] += 20;
			cout << endl;
			break;

		case 2:
			if (PotionMP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* MP increased by 20. (MP Potion used: " << PotionMP - 1 << " left)" << endl;
			PotionMP -= 1;
			playerstat[1] += 20;
			cout << endl;
			break;

		case 3:
			cout << "* Attack multiplied by 2." << endl;
			playerstat[2] *= 2;
			cout << endl;

			break;

		case 4:
			cout << "* Defense multiplied by 2." << endl;
			playerstat[3] *= 2;
			cout << endl;

			break;

		case 5:
			system("cls");
			printTitle();
			cout << endl;
			statsMenu();
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
}

void enterStats()
{
	while (true)
	{
		cout << "Enter HP and MP: ";
		cin >> playerstat[0];
		cin >> playerstat[1];

		if (playerstat[0] < 50 || playerstat[1] < 50)
		{
			cout << "HP or MP is too low. Try again." << endl;
		}

		else {
			break;
		}
	}

	while (true)
	{
		cout << "Enter Attack and Defense: ";
		cin >> playerstat[2];
		cin >> playerstat[3];

		if (playerstat[2] < 50 || playerstat[3] < 50)
		{
			cout << "Attack or Defense is too low. Try again." << endl;
		}

		else {
			break;
		}
	}
}

Player* createCharacter(string name, int playerstat[]) {
	cout << "< Job Selection >" << endl;
	cout << name << ", choose your job!" << endl;
	cout << "1. Warrior   2. Mage   3. Rogue   4. Archer" << endl;
	cout << "Choose: ";


	int jobChoice;
	cin >> jobChoice;

	Player* player = nullptr;

	switch (jobChoice) {
	case 1:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 2:
		cout << endl;
		player = new Mage(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 3:
		cout << endl;
		player = new Rogue(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 4:
		cout << endl;
		player = new Archer(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	default:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	}
	return player;
}

int main() {
	printTitle();

	cout << "Enter your hero's name: ";
	cin >> name;
	cout << endl;

	enterStats();

	system("cls");
	printTitle();

	statsMenu();
	
	cout << "* You received " << PotionHP << " HP Potions and " << PotionMP << " MP Potions." << endl;

	statsCustom();

	Player* player = createCharacter(name, playerstat);

	player->attack();
	player->printPlayerStatus();

	delete player;
	return 0;

}

# STEP 5 - Monster 클래스 + 1:1 전투 (클래스 설계, 전투 루프)

monter.h

#pragma once
#include <iostream>
#include <string>
#include "Player.h" // attack 함수에서 Player 포인터를 쓰기 위해 포함

using namespace std;

class Monster {
private:
    string name;
    int hp;
    int power;
    int defence;
    string dropItemName;
    int dropItemPrice;

public:
    Monster(string name, int hp, int power, int defence, string dropItemName, int dropItemPrice);

    string getName() { return name; }
    int getHp() { return hp; }
    void setHp(int hp) { this->hp = hp; }
    int getPower() { return power; }
    int getDefence() { return defence; }
    string getDropItemName() { return dropItemName; }

    void attack(Player* player);
};

monter.cpp

#include "Monster.h"

Monster::Monster(string name, int hp, int power, int defence, string dropItemName, int dropItemPrice) : name(name), hp(hp), power(power), defence(defence), dropItemName(dropItemName), dropItemPrice(dropItemPrice) {}

void Monster::attack(Player* player) {
	cout << name << " attacks " << player->getName() << "!" << endl;
}

RPG.cpp (게임 스타트 하기 전에 직업 선택하는 걸로 바꿈)

#include <iostream>
#include <string>
#include "Player.h"
#include "Warrior.h"
#include "Mage.h"
#include "Rogue.h"
#include "Archer.h"
#include "Monster.h"

using namespace std;

string name;
const int SIZE = 4;
int playerstat[SIZE] = { 0 };
// {HP, MP, 공격력, 방어력}
int PotionHP = 5;
int PotionMP = 5;
int choice;
bool isGameStart = false;


void printTitle()
{
	cout << "===========================================" << endl;
	cout << "	[ Dungeon Escape Text RPG ]" << endl;
	cout << "===========================================" << endl;

}

void statsMenu()
{
	cout << "===========================================" << endl;
	cout << "	" << name << "'s Stats" << endl;
	cout << "===========================================" << endl;
	cout << "HP: " << playerstat[0] << "		MP: " << playerstat[1] << endl;
	cout << "Attack: " << playerstat[2] << "		Defense: " << playerstat[3] << endl;
	cout << endl;
}
Player* createCharacter(string name, int playerstat[]) {
	cout << "< Job Selection >" << endl;
	cout << name << ", choose your job!" << endl;
	cout << "1. Warrior   2. Mage   3. Rogue   4. Archer" << endl;
	cout << "Choose: ";


	int jobChoice;
	cin >> jobChoice;

	Player* player = nullptr;

	switch (jobChoice) {
	case 1:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 2:
		cout << endl;
		player = new Mage(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 3:
		cout << endl;
		player = new Rogue(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 4:
		cout << endl;
		player = new Archer(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	default:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	}
	return player;
}

Player* statsCustom()
{
	Player* player = nullptr;

	while (!isGameStart) {
		cout << "===========================================" << endl;
		cout << "	< Character Upgrade >" << endl;
		cout << "1. HP UP    2. MP UP    3. Attack x2" << endl;
		cout << "4. Defense x2  5. Show Stats  0. Jop Select & Start Game" << endl;
		cout << "===========================================" << endl;

		cout << "Choose : ";
		cin >> choice;
		cout << endl;

		switch (choice) {
		case 0:
			system("cls");
			printTitle();
			cout << endl;

			player = createCharacter(name, playerstat);
			player->attack();
			cout << endl;

			cout << "Starting the game!" << endl;
			cout << endl;
			cout << "      /| ________________" << endl;
			cout << " O|===|* >________________>" << endl;
			cout << "      ||" << endl;
			cout << endl;

			return player;
			cout << endl;

			isGameStart = true;
			break;

		case 1:
			if (PotionHP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* HP increased by 20. (HP Potion used: " << PotionHP - 1 << " left)" << endl;
			PotionHP -= 1;
			playerstat[0] += 20;
			cout << endl;
			break;

		case 2:
			if (PotionMP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* MP increased by 20. (MP Potion used: " << PotionMP - 1 << " left)" << endl;
			PotionMP -= 1;
			playerstat[1] += 20;
			cout << endl;
			break;

		case 3:
			cout << "* Attack multiplied by 2." << endl;
			playerstat[2] *= 2;
			cout << endl;

			break;

		case 4:
			cout << "* Defense multiplied by 2." << endl;
			playerstat[3] *= 2;
			cout << endl;

			break;

		case 5:
			system("cls");
			printTitle();
			cout << endl;
			statsMenu();
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
	
}

void enterStats()
{
	while (true)
	{
		cout << "Enter HP and MP: ";
		cin >> playerstat[0];
		cin >> playerstat[1];

		if (playerstat[0] < 50 || playerstat[1] < 50)
		{
			cout << "HP or MP is too low. Try again." << endl;
		}

		else {
			break;
		}
	}

	while (true)
	{
		cout << "Enter Attack and Defense: ";
		cin >> playerstat[2];
		cin >> playerstat[3];

		if (playerstat[2] < 50 || playerstat[3] < 50)
		{
			cout << "Attack or Defense is too low. Try again." << endl;
		}

		else {
			break;
		}
	}
}



void startBattle(Player* player, Monster& monster) {
	cout << endl;
	cout << " [ Battle Start! ] " << player->getName() << "(" << player->getJob() << ") vs " << monster.getName() << endl;
	cout << endl;

	while (player->getHp() > 0 && monster.getHp() > 0) {
		cout << "--- Player Turn ---" << endl;
		player->attack();

		int playerDamage = player->getPower() - monster.getDefence();
		if (playerDamage <= 0) {
			playerDamage = 1;
		}
		int monsterOldHp = monster.getHp();
		monster.setHp(monsterOldHp - playerDamage);

		cout << playerDamage << " damage to " << monster.getName() << "!" << endl;
		cout << monster.getName() << " HP : " << monsterOldHp << " -> " << monster.getHp();
		if (monster.getHp() <= 0) {
			cout << " (Dead) " << endl;
			cout << endl;
			cout << "★ Victory!" << endl;
			cout << "  -> Got: " << monster.getDropItemName() << "!" << endl;
			cout << "  (Will be saved to inventory in the next STEP)" << endl;
			break;
		}

		cout << endl;
		cout << endl;
		cout << "--- Monster Turn ---" << endl;
		monster.attack(player);

		int monsterDamage = monster.getPower() - player->getDefence();
		if (monsterDamage <= 0) {
			monsterDamage = 1;
		}

		int playerOldHp = player->getHp();
		player->setHp(playerOldHp - monsterDamage);

		cout << monsterDamage << " damage to " << player->getName() << "!" << endl;
		cout << player->getName() << " HP : " << playerOldHp << " -> " << player->getHp();
		cout << endl;
		cout << endl;

		if (player->getHp() <= 0) {
			cout << " (Dead) " << endl;
			cout << endl;
			cout << " Game Over..." << endl;
			break;
		}
	}


}

int main() {
	printTitle();

	cout << "Enter your hero's name: ";
	cin >> name;
	cout << endl;

	enterStats();

	system("cls");
	printTitle();

	statsMenu();

	cout << "* You received " << PotionHP << " HP Potions and " << PotionMP << " MP Potions." << endl;

	Player* player = statsCustom();
	player->printPlayerStatus();

	Monster slime("Slime", 30, 20, 10, "Slime Jelly", 10);

	startBattle(player, slime);

	delete player;
	return 0;

}

# STEP 6 - 인벤토리 + 아이템 드롭 (STL vector)

Monster.h

int getDropItemPrice() { return dropItemPrice; } 추가해주기

RPG.cpp

#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Warrior.h"
#include "Mage.h"
#include "Rogue.h"
#include "Archer.h"
#include "Monster.h"

using namespace std;

string name;
const int SIZE = 4;
int playerstat[SIZE] = { 0 };
// {HP, MP, 공격력, 방어력}
int PotionHP = 5;
int PotionMP = 5;
int choice;
bool isGameStart = false;

struct Item {
	string name;
	int price;

	void PrintItem() const {
		cout << name << " (" << price << "G)" << endl;
	}

};
vector<Item> inventory;

void printTitle()
{
	cout << "===========================================" << endl;
	cout << "	[ Dungeon Escape Text RPG ]" << endl;
	cout << "===========================================" << endl;

}

void statsMenu()
{
	cout << "===========================================" << endl;
	cout << "	" << name << "'s Stats" << endl;
	cout << "===========================================" << endl;
	cout << "HP: " << playerstat[0] << "		MP: " << playerstat[1] << endl;
	cout << "Attack: " << playerstat[2] << "		Defense: " << playerstat[3] << endl;
	cout << endl;
}

Player* createCharacter(string name, int playerstat[]) {
	cout << "< Job Selection >" << endl;
	cout << name << ", choose your job!" << endl;
	cout << "1. Warrior   2. Mage   3. Rogue   4. Archer" << endl;
	cout << "Choose: ";

	int jobChoice;
	cin >> jobChoice;

	Player* player = nullptr;

	switch (jobChoice) {
	case 1:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 2:
		cout << endl;
		player = new Mage(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 3:
		cout << endl;
		player = new Rogue(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 4:
		cout << endl;
		player = new Archer(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	default:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	}
	return player;
}

Player* statsCustom()
{
	Player* player = nullptr;

	while (!isGameStart) {
		cout << "===========================================" << endl;
		cout << "	< Character Upgrade >" << endl;
		cout << "1. HP UP    2. MP UP    3. Attack x2" << endl;
		cout << "4. Defense x2  5. Show Stats  0. Jop Select & Start Game" << endl;
		cout << "===========================================" << endl;

		cout << "Choose : ";
		cin >> choice;
		cout << endl;

		switch (choice) {
		case 0:
			system("cls");
			printTitle();
			cout << endl;

			player = createCharacter(name, playerstat);
			player->attack();
			cout << endl;

			cout << "Starting the game!" << endl;
			cout << endl;
			cout << "      /| ________________" << endl;
			cout << " O|===|* >________________>" << endl;
			cout << "      ||" << endl;
			cout << endl << endl;

			isGameStart = true;
			break;

		case 1:
			if (PotionHP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* HP increased by 20. (HP Potion used: " << PotionHP - 1 << " left)" << endl;
			PotionHP -= 1;
			playerstat[0] += 20;
			cout << endl;
			break;

		case 2:
			if (PotionMP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* MP increased by 20. (MP Potion used: " << PotionMP - 1 << " left)" << endl;
			PotionMP -= 1;
			playerstat[1] += 20;
			cout << endl;
			break;

		case 3:
			cout << "* Attack multiplied by 2." << endl;
			playerstat[2] *= 2;
			cout << endl;

			break;

		case 4:
			cout << "* Defense multiplied by 2." << endl;
			playerstat[3] *= 2;
			cout << endl;

			break;

		case 5:
			system("cls");
			printTitle();
			cout << endl;
			statsMenu();
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
	return player;
}

void enterStats()
{
	while (true)
	{
		cout << "Enter HP and MP: ";
		cin >> playerstat[0];
		cin >> playerstat[1];

		if (playerstat[0] < 50 || playerstat[1] < 50)
		{
			cout << "HP or MP is too low. Try again." << endl;
		}

		else {
			break;
		}
	}

	while (true)
	{
		cout << "Enter Attack and Defense: ";
		cin >> playerstat[2];
		cin >> playerstat[3];

		if (playerstat[2] < 50 || playerstat[3] < 50)
		{
			cout << "Attack or Defense is too low. Try again." << endl;
		}

		else {
			break;
		}
	}
}

void startBattle(Player* player, Monster& monster) {
	cout << endl;
	cout << " [ Battle Start! ] " << player->getName() << "(" << player->getJob() << ") vs " << monster.getName() << endl;
	cout << endl;

	while (player->getHp() > 0 && monster.getHp() > 0) {
		cout << "--- Player Turn ---" << endl;
		player->attack();

		int playerDamage = player->getPower() - monster.getDefence();
		if (playerDamage <= 0) {
			playerDamage = 1;
		}
		int monsterOldHp = monster.getHp();
		monster.setHp(monsterOldHp - playerDamage);

		cout << playerDamage << " damage to " << monster.getName() << "!" << endl;
		cout << monster.getName() << " HP : " << monsterOldHp << " -> " << monster.getHp();
		if (monster.getHp() <= 0) {
			cout << " (Dead) ";
			cout << endl << endl;
			cout << "★ Victory!" << endl;
			cout << "  -> Got: " << monster.getDropItemName() << "!" << endl;
			cout << "  -> Saved to inventory." << endl << endl;


			Item droppedItem;
			droppedItem.name = monster.getDropItemName();
			droppedItem.price = monster.getDropItemPrice();
			inventory.push_back(droppedItem);

			break;
		}

		cout << endl << endl;
		cout << "--- Monster Turn ---" << endl;
		monster.attack(player);

		int monsterDamage = monster.getPower() - player->getDefence();
		if (monsterDamage <= 0) {
			monsterDamage = 1;
		}

		int playerOldHp = player->getHp();
		player->setHp(playerOldHp - monsterDamage);

		cout << monsterDamage << " damage to " << player->getName() << "!" << endl;
		cout << player->getName() << " HP : " << playerOldHp << " -> " << player->getHp();
		cout << endl << endl;

		if (player->getHp() <= 0) {
			cout << " (Dead) " << endl;
			cout << endl;
			cout << " Game Over..." << endl;
			break;
		}
	}


}

void mainMenu(Player* player)
{
	int choiceMenu;

	while (true) {
		cout << "=== Main Menu ===" << endl;
		cout << "1. Enter Dungeon" << endl;
		cout << "2. Check Inventory" << endl;
		cout << "0. Quit" << endl;
		cout << endl;

		cout << "Choose : ";
		cin >> choiceMenu;
		cout << endl;

		switch (choiceMenu) {
		case 0:
			system("cls");
			printTitle();
			cout << "Exit Game.." << endl;
			return;

		case 1:
		{
			Monster slime("Slime", 30, 20, 10, "Slime Jelly", 30);
			startBattle(player, slime);

			if (player->getHp() <= 0) {
				return;
			}
			break;
		}

		case 2:
			cout << "[ Inventory (" << inventory.size() << "/10) ]" << endl;
			if (inventory.empty()) {
				cout << "The inventory is empty." << endl;
			}
			else {
				int number = 1;
				for (const Item& item : inventory) {
					cout << number << ". ";
					item.PrintItem();
					number++;
				}
			}
			cout << endl;
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
}

int main() {
	printTitle();

	cout << "Enter your hero's name: ";
	cin >> name;
	cout << endl;

	enterStats();

	system("cls");
	printTitle();
	statsMenu();

	cout << "* You received " << PotionHP << " HP Potions and " << PotionMP << " MP Potions." << endl;

	Player* player = statsCustom();
	player->printPlayerStatus();

	mainMenu(player);

	delete player;
	return 0;

}

# STEP 7 - 포션 제작소 기본 (vector 탐색, 코드 분석)

RPG.cpp

#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Warrior.h"
#include "Mage.h"
#include "Rogue.h"
#include "Archer.h"
#include "Monster.h"

using namespace std;

string name;
const int SIZE = 4;
int playerstat[SIZE] = { 0 };
// {HP, MP, 공격력, 방어력}
int PotionHP = 5;
int PotionMP = 5;
int choice;
bool isGameStart = false;

struct Item {
	string name;
	int price;

	void PrintItem() const {
		cout << name << " (" << price << "G)" << endl;
	}

};
vector<Item> inventory;

struct PotionRecipe {
	string potionName;
	string ingredient1;
	string ingredient2;

	void PrintRecipe() const {
		cout << "-> " << potionName << " : " << ingredient1 << " x1, " << ingredient2 << " x1" << endl;

	}
};

vector<PotionRecipe> recipes = {
	{"HPPotion", "Herb", "Clear Water"},
	{"MPPotion", "Slime Jelly", "Clear Water"},
	{"StaminaPotioin", "Herb", "Berry"}
};

void printTitle()
{
	cout << "===========================================" << endl;
	cout << "	[ Dungeon Escape Text RPG ]" << endl;
	cout << "===========================================" << endl;

}

void statsMenu()
{
	cout << "===========================================" << endl;
	cout << "	" << name << "'s Stats" << endl;
	cout << "===========================================" << endl;
	cout << "HP: " << playerstat[0] << "		MP: " << playerstat[1] << endl;
	cout << "Attack: " << playerstat[2] << "		Defense: " << playerstat[3] << endl;
	cout << endl;
}

Player* createCharacter(string name, int playerstat[]) {
	cout << "< Job Selection >" << endl;
	cout << name << ", choose your job!" << endl;
	cout << "1. Warrior   2. Mage   3. Rogue   4. Archer" << endl;
	cout << "Choose: ";

	int jobChoice;
	cin >> jobChoice;

	Player* player = nullptr;

	switch (jobChoice) {
	case 1:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 2:
		cout << endl;
		player = new Mage(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 3:
		cout << endl;
		player = new Rogue(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	case 4:
		cout << endl;
		player = new Archer(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	default:
		cout << endl;
		player = new Warrior(name, playerstat[0], playerstat[1], playerstat[2], playerstat[3]);
		break;
	}
	return player;
}

Player* statsCustom()
{
	Player* player = nullptr;

	while (!isGameStart) {
		cout << "===========================================" << endl;
		cout << "	< Character Upgrade >" << endl;
		cout << "1. HP UP    2. MP UP    3. Attack x2" << endl;
		cout << "4. Defense x2  5. Show Stats  0. Jop Select & Start Game" << endl;
		cout << "===========================================" << endl;

		cout << "Choose : ";
		cin >> choice;
		cout << endl;

		switch (choice) {
		case 0:
			system("cls");
			printTitle();
			cout << endl;

			player = createCharacter(name, playerstat);
			player->attack();
			cout << endl;

			cout << "Starting the game!" << endl;
			cout << endl;
			cout << "      /| ________________" << endl;
			cout << " O|===|* >________________>" << endl;
			cout << "      ||" << endl;
			cout << endl << endl;

			isGameStart = true;
			break;

		case 1:
			if (PotionHP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* HP increased by 20. (HP Potion used: " << PotionHP - 1 << " left)" << endl;
			PotionHP -= 1;
			playerstat[0] += 20;
			cout << endl;
			break;

		case 2:
			if (PotionMP == 0)
			{
				cout << "No potions left!" << endl;
				cout << endl;
				break;
			}
			cout << "* MP increased by 20. (MP Potion used: " << PotionMP - 1 << " left)" << endl;
			PotionMP -= 1;
			playerstat[1] += 20;
			cout << endl;
			break;

		case 3:
			cout << "* Attack multiplied by 2." << endl;
			playerstat[2] *= 2;
			cout << endl;

			break;

		case 4:
			cout << "* Defense multiplied by 2." << endl;
			playerstat[3] *= 2;
			cout << endl;

			break;

		case 5:
			system("cls");
			printTitle();
			cout << endl;
			statsMenu();
			break;

		default:
			cout << "Please choose another number." << endl;
			cout << endl;

			break;
		}

	}
	return player;
}

void enterStats()
{
	while (true)
	{
		cout << "Enter HP and MP: ";
		cin >> playerstat[0];
		cin >> playerstat[1];

		if (playerstat[0] < 50 || playerstat[1] < 50)
		{
			cout << "HP or MP is too low. Try again." << endl;
		}

		else {
			break;
		}
	}

	while (true)
	{
		cout << "Enter Attack and Defense: ";
		cin >> playerstat[2];
		cin >> playerstat[3];

		if (playerstat[2] < 50 || playerstat[3] < 50)
		{
			cout << "Attack or Defense is too low. Try again." << endl;
		}

		else {
			break;
		}
	}
}

void startBattle(Player* player, Monster& monster) {
	cout << endl;
	cout << " [ Battle Start! ] " << player->getName() << "(" << player->getJob() << ") vs " << monster.getName() << endl;
	cout << endl;

	while (player->getHp() > 0 && monster.getHp() > 0) {
		cout << "--- Player Turn ---" << endl;
		player->attack();

		int playerDamage = player->getPower() - monster.getDefence();
		if (playerDamage <= 0) {
			playerDamage = 1;
		}
		int monsterOldHp = monster.getHp();
		monster.setHp(monsterOldHp - playerDamage);

		cout << playerDamage << " damage to " << monster.getName() << "!" << endl;
		cout << monster.getName() << " HP : " << monsterOldHp << " -> " << monster.getHp();
		if (monster.getHp() <= 0) {
			cout << " (Dead) ";
			cout << endl << endl;
			cout << "★ Victory!" << endl;
			cout << "  -> Got: " << monster.getDropItemName() << "!" << endl;
			cout << "  -> Saved to inventory." << endl << endl;


			Item droppedItem;
			droppedItem.name = monster.getDropItemName();
			droppedItem.price = monster.getDropItemPrice();
			inventory.push_back(droppedItem);

			break;
		}

		cout << endl << endl;
		cout << "--- Monster Turn ---" << endl;
		monster.attack(player);

		int monsterDamage = monster.getPower() - player->getDefence();
		if (monsterDamage <= 0) {
			monsterDamage = 1;
		}

		int playerOldHp = player->getHp();
		player->setHp(playerOldHp - monsterDamage);

		cout << monsterDamage << " damage to " << player->getName() << "!" << endl;
		cout << player->getName() << " HP : " << playerOldHp << " -> " << player->getHp();
		cout << endl << endl;

		if (player->getHp() <= 0) {
			cout << " (Dead) " << endl;
			cout << endl;
			cout << " Game Over..." << endl;
			break;
		}
	}


}

void AlchemyWorkshop() {
	int ChoiceShop;

	while (true) {
		cout << "=== Potion Shop ===" << endl;
		cout << "1. Show all recipes" << endl;
		cout << "2. Search by potion name" << endl;
		cout << "3. Search by ingredient" << endl;
		cout << "0. Go back" << endl;
		cout << endl;

		cout << "Choose : ";
		cin >> ChoiceShop;
		cout << endl;

		switch (ChoiceShop) {
		case 0:
			system("cls");
			return;

		case 1:
			for (const PotionRecipe& PR : recipes) {
				PR.PrintRecipe();
			}
			cout << endl;
			break;

		case 2:
		{
			string searchName;
			cout << "Search potion name: ";
			cin >> searchName;

			bool isFound = false;
			for (const PotionRecipe& PR : recipes) {
				if (PR.potionName == searchName) {
					PR.PrintRecipe();
					isFound = true;
					break;
				}
			}

			if (!isFound) {
				cout << "It cannot be found." << endl;
			}
			cout << endl;
			break;
		}

		case 3: {
			string searchIngredient;
			cout << "Search ingredient: ";
			cin >> searchIngredient;

			int count = 0;
			for (const PotionRecipe& PR : recipes) {
				if (PR.ingredient1 == searchIngredient || PR.ingredient2 == searchIngredient)
				{
					PR.PrintRecipe();
					count++;
				}
			}

			if (count == 0) {
				cout << "It cannot be found." << endl;
			}
			else {
				cout << "Found " << count << " recipes." << endl;
			}
			cout << endl;
			break;
        }

		default:
			cout << "Please choose another number." << endl << endl;
			break;
		}
	}
}

void mainMenu(Player* player)
{
	int choiceMenu;

	while (true) {
		cout << "=== Main Menu ===" << endl;
		cout << "1. Enter Dungeon" << endl;
		cout << "2. Check Inventory" << endl;
		cout << "0. Quit" << endl;
		cout << endl;

		cout << "Choose : ";
		cin >> choiceMenu;
		cout << endl;

		switch (choiceMenu) {
		case 0:
			system("cls");
			printTitle();
			cout << "Exit Game.." << endl;
			return;

		case 1:
		{
			Monster slime("Slime", 30, 20, 10, "Slime Jelly", 30);
			startBattle(player, slime);

			if (player->getHp() <= 0) {
				return;
			}
			break;
		}

		case 2:
			cout << "[ Inventory (" << inventory.size() << "/10) ]" << endl;
			if (inventory.empty()) {
				cout << "The inventory is empty." << endl;
			}
			else {
				int number = 1;
				for (const Item& item : inventory) {
					cout << number << ". ";
					item.PrintItem();
					number++;
				}
			}
			cout << endl;
			break;

		case 3:
			system("cls");
			AlchemyWorkshop();
			break;

		default:
			cout << "Please choose another number." << endl << endl;

			break;
		}

	}
}

int main() {
	printTitle();

	cout << "Enter your hero's name: ";
	cin >> name;
	cout << endl;

	enterStats();

	system("cls");
	printTitle();
	statsMenu();

	cout << "* You received " << PotionHP << " HP Potions and " << PotionMP << " MP Potions." << endl;

	Player* player = statsCustom();
	player->printPlayerStatus();

	mainMenu(player);

	delete player;
	return 0;

}

궁금증 해결하기

void startBattle(Player player, Monster& monster)
여기서 왜 Player
player는 포인터고 Monster& monster는 레퍼런스야?

🔺 2. Monster* monster (포인터)로 넘길 경우
startBattle(player, &slime) 처럼 슬라임의 주소(포인터)를 넘겨도 원본을 때릴 수 있어서 정답이야! 하지만 포인터를 쓰면 함수 안에서 monster->getHp() 처럼 화살표(->)를 써야 하고, 혹시라도 빈 주소(nullptr)가 넘어올까 봐 불안해져.

✅ 3. Monster& monster (레퍼런스)로 넘길 경우 (C++의 꽃!)
&를 붙이면 복사본을 만들지 않고 "원본 몬스터에 또 다른 별명표만 하나 딱 붙여서" 함수로 넘겨줘.
복사도 안 하니까 빠르고, 포인터처럼 화살표(->) 대신 점(.)을 그대로 쓸 수 있어서(monster.getHp()) 코드도 훨씬 깔끔해져! C++ 창시자가 "일반 변수의 원본을 함수로 넘길 때는 웬만하면 포인터 대신 참조자(&)를 쓰세요!"라고 권장하기도 했어.


예습

죽었을 때 try again? 이라는 거 만들기

profile
초보 개발자

0개의 댓글