# 작성 코드
// Text RPG 만들기
#include <iostream>
#include <ctime>
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
using namespace std;
enum PlayerState { ENTRANCE, MAIN, SKILL, INVENTORY, STORE, HUNTINGGROUND, BATTLE };
struct PlayerInfo
{
string sName = "";
string sGender = "";
string sSpecies = "";
string sJob = "";
int iLv = 0;
int iHp = 0;
int iCurrHp = 0;
int iAttack = 0;
int iDefense = 0;
int iEx = 0;
int iCoin = 0;
};
struct MonsterInfo
{
string sName = "";
string sProperty = "";
int iLv = 0;
int iHp = 0;
int iAttack = 0;
int iEx = 0;
int iCoin = 0;
};
struct SkillInfo
{
string sName = "미보유";
int iSkillLv = 0;
int iDamage = 0;
int iDefense = 0;
int iRecovery = 0;
int iUseCoint = 0;
};
struct PlayerInvenInfo
{
string sName = "미장착";
string sItemEffect = "";
int iEffectNum = 0;
int iCoin = 0;
int iNum = 0;
int iCount = 0;
};
#pragma region 선언한 함수 목록
void SavePlayerInfo(PlayerInfo _pplayerInfo, SkillInfo _tplayerSkill[], PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[], FILE* _fPlayerSave);
PlayerInfo* EntranceState(PlayerState* _pplayerstate, FILE* _fPlayerSave, SkillInfo _tplayerSkill[], PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[]);
void MainState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, bool* _pgameover);
void SkillState(PlayerState* _pplayerstate, PlayerInfo* _tplayerInfo, SkillInfo _tplayerSkill[]);
void PlayerInvenTory(PlayerState* _pplayerstate, PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[], PlayerInfo* _tplayerInfo);
void ArrSort(int _iInputNum, PlayerInvenInfo _tlocation[], PlayerInvenInfo _tDatamove[]);
void StoreState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, PlayerInvenInfo _tHaveInven[]);
void HuntingGround(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, MonsterInfo** _ppMonsterInfo);
void BattlwState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, MonsterInfo* _pmonsterInfo, SkillInfo _tplayerSkill[]);
MonsterInfo MonsterCreat(int _iLvMons);
void PlayerStatsUpdate(PlayerInfo* _tplayerInfo, PlayerInvenInfo _pequipInven[], int iNum, bool _btrue);
void PlayerLvUp(PlayerInfo* _tplayerInfo, SkillInfo _tplayerSkill[]);
void PlayerInfoPrint(PlayerInfo _tplayerInfo);
void PlayerSkillInfoPrint(SkillInfo _tplayerSkill[]);
void MonsterInfoPrint(MonsterInfo _tmonsterInfo);
#pragma endregion 선언한 함수 목록
void main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
srand(unsigned(time(nullptr)));
FILE* fPlayerSave = nullptr;
PlayerState tPlayerstate = ENTRANCE;
PlayerInfo* pPlayer = nullptr;
MonsterInfo* pMonster = nullptr;
SkillInfo tPlayerSkill[3]{};
PlayerInvenInfo pEquipInven[3]{};
PlayerInvenInfo pHaveInven[3]{};
bool bGameOver(false);
while (bGameOver != true)
{
switch (tPlayerstate)
{
case ENTRANCE:
pPlayer = EntranceState(&tPlayerstate, fPlayerSave, tPlayerSkill, pEquipInven, pHaveInven);
SavePlayerInfo(*pPlayer, tPlayerSkill, pEquipInven, pHaveInven, fPlayerSave);
break;
case MAIN:
MainState(&tPlayerstate, pPlayer, &bGameOver);
break;
case SKILL:
SkillState(&tPlayerstate, pPlayer, tPlayerSkill);
SavePlayerInfo(*pPlayer, tPlayerSkill, pEquipInven, pHaveInven, fPlayerSave);
break;
case INVENTORY:
PlayerInvenTory(&tPlayerstate, pEquipInven, pHaveInven, pPlayer);
SavePlayerInfo(*pPlayer, tPlayerSkill, pEquipInven, pHaveInven, fPlayerSave);
break;
case STORE:
StoreState(&tPlayerstate, pPlayer, pHaveInven);
SavePlayerInfo(*pPlayer, tPlayerSkill, pEquipInven, pHaveInven, fPlayerSave);
break;
case HUNTINGGROUND:
HuntingGround(&tPlayerstate, pPlayer, &pMonster);
break;
case BATTLE:
BattlwState(&tPlayerstate, pPlayer, pMonster, tPlayerSkill);
delete pMonster;
pMonster = nullptr;
SavePlayerInfo(*pPlayer, tPlayerSkill, pEquipInven, pHaveInven, fPlayerSave);
break;
default:
break;
}
}
if (pPlayer != nullptr)
{
delete pPlayer;
pPlayer = nullptr;
}
}
void SavePlayerInfo(PlayerInfo _pplayerInfo, SkillInfo _tplayerSkill[], PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[], FILE* _fPlayerSave)
{
int itrue = fopen_s(&_fPlayerSave, "../JS_230303_H(TextRPG_3)_2/PlayerSaveInfo.txt", "wb");
if (0 == itrue)
{
fwrite(&_pplayerInfo, sizeof(_pplayerInfo), 1, _fPlayerSave);
fwrite(_tplayerSkill, sizeof(SkillInfo), 3, _fPlayerSave);
fwrite(_tEquipInven, sizeof(PlayerInvenInfo), 3, _fPlayerSave);
fwrite(_tHaveInven, sizeof(PlayerInvenInfo), 3, _fPlayerSave);
fclose(_fPlayerSave);
}
else
{
cout << "플레이어 정보 저장 실패" << endl;
system("pause");
}
}
PlayerInfo* EntranceState(PlayerState* _pplayerstate, FILE* _fPlayerSave, SkillInfo _tplayerSkill[], PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[])
{
PlayerInfo* tPlayer = new PlayerInfo;
string sNameStr("");
int iInput(0), itrue(0);
bool bStart(false);
while (!bStart)
{
// 입구 시작 ------------------------------------------
cout << "Text RPG에 오신 것을 환영합니다." << endl << endl;
cout << "1) 게임시작. 2) 불러오기 : ";
cin >> iInput;
system("cls");
if (iInput == 1)
{
// 종족 선택 ------------------------------------------
cout << "원하시는 종족을 선택해주세요." << endl;
cout << "1) 인간. 2) 엘프. 3) 수인 : ";
cin >> iInput;
system("cls");
switch (iInput)
{
case 1:
(*tPlayer).sSpecies = "인간";
(*tPlayer).iHp = 100;
(*tPlayer).iCurrHp = 100;
break;
case 2:
(*tPlayer).sSpecies = "엘프";
(*tPlayer).iHp = 120;
(*tPlayer).iCurrHp = 120;
break;
case 3:
(*tPlayer).sSpecies = "수인";
(*tPlayer).iHp = 150;
(*tPlayer).iCurrHp = 150;
break;
default:
cout << "지원하지 않는 입력 값 입니다." << endl;
break;
}
// 성별 선택 ------------------------------------------
cout << "원하시는 성별을 선택해주세요." << endl;
cout << "1) 여자. 2) 남자 : ";
cin >> iInput;
system("cls");
if (iInput == 1)
{
(*tPlayer).sGender = "여자";
(*tPlayer).iDefense = 10;
}
else if (iInput == 2)
{
(*tPlayer).sGender = "남자";
(*tPlayer).iDefense = 20;
}
// 직업 선택 ------------------------------------------
cout << "원하시는 직업을 선택해주세요." << endl;
cout << "1) 전사. 2) 마법사. 3) 도적 : ";
cin >> iInput;
system("cls");
switch (iInput)
{
case 1:
(*tPlayer).sJob = "전사";
(*tPlayer).iAttack = 10;
break;
case 2:
(*tPlayer).sJob = "마법사";
(*tPlayer).iAttack = 20;
break;
case 3:
(*tPlayer).sJob = "도적";
(*tPlayer).iAttack = 15;
break;
default:
cout << "지원하지 않는 입력 값 입니다." << endl;
break;
}
// 이름 입력 ------------------------------------------
cout << "사용할 플레이어 이름을 입력하세요 : ";
cin >> sNameStr;
system("cls");
(*tPlayer).sName = sNameStr;
// 캐릭터 생성 기본 값 할당
(*tPlayer).iLv = 1;
(*tPlayer).iEx = 0;
(*tPlayer).iCoin = 1000;
bStart = true;
}
else if (iInput == 2)
{
itrue = fopen_s(&_fPlayerSave, "../JS_230303_H(TextRPG_3)_2/PlayerSaveInfo.txt", "rb");
if (itrue == 0)
{
cout << "저장된 정보를 불러옵니다." << endl;
fread(tPlayer, sizeof(*tPlayer), 1, _fPlayerSave);
fread(_tplayerSkill, sizeof(SkillInfo), 3, _fPlayerSave);
fread(_tEquipInven, sizeof(PlayerInvenInfo), 3, _fPlayerSave);
fread(_tHaveInven, sizeof(PlayerInvenInfo), 3, _fPlayerSave);
system("pause");
system("cls");
fclose(_fPlayerSave);
bStart = true;
}
else
{
cout << "저장된 정보가 없습니다." << endl;
system("pause");
system("cls");
}
}
if (iInput == 1 || (iInput == 2 && itrue == 0))
{
cout << "[SYSTEM] 선택하신 프로필 정보입니다." << endl << endl;
PlayerInfoPrint(*tPlayer);
system("pause");
system("cls");
*_pplayerstate = MAIN;
return tPlayer;
}
}
}
void MainState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, bool* _pgameover)
{
int iInput(0);
// 메인화면 ------------------------------------------
cout << "[메인화면]" << endl;
cout << "---------------------------------------------------------------" << endl;
cout << "1) 프로필. 2) 보유스킬. 3) 소지품. 4) 상점. 5) 사냥터. 6) 종료 : ";
cin >> iInput;
system("cls");
switch (iInput)
{
case 1:
PlayerInfoPrint(*_pplayerInfo);
system("pause");
break;
case 2:
*_pplayerstate = SKILL;
break;
case 3:
*_pplayerstate = INVENTORY;
break;
case 4:
*_pplayerstate = STORE;
break;
case 5:
*_pplayerstate = HUNTINGGROUND;
break;
case 6:
*_pgameover = true;
break;
default:
cout << "지원하지 않는 입력 값 입니다." << endl;
break;
}
system("cls");
}
void SkillState(PlayerState* _pplayerstate, PlayerInfo* _tplayerInfo, SkillInfo _tplayerSkill[])
{
int iInput(0);
// 스킬 강화 및 메인화면 이동
while (true)
{
PlayerSkillInfoPrint(_tplayerSkill);
cout << "보유 코인 : " << (*_tplayerInfo).iCoin << endl << endl;
cout << "1) 스킬강화. 2) 메인화면 : ";
cin >> iInput;
if (iInput == 1)
{
cout << "강화하고 싶은 스킬 번호 선택 : ";
cin >> iInput;
if (iInput == 1)
{
if ((*_tplayerInfo).iCoin >= 200)
{
(*_tplayerInfo).iCoin -= 200;
(_tplayerSkill[0]).iSkillLv += 1;
(_tplayerSkill[0]).iDamage += 3;
}
else
{
cout << "코인이 부족합니다." << endl;
system("pause");
}
}
else if (iInput == 2)
{
if ((*_tplayerInfo).iCoin >= 200)
{
(*_tplayerInfo).iCoin -= 200;
_tplayerSkill[1].iSkillLv += 1;
_tplayerSkill[1].iDamage += 10;
_tplayerSkill[1].iDefense += 5;
}
else
{
cout << "코인이 부족합니다." << endl;
system("pause");
}
}
else if (iInput == 3)
{
if ((*_tplayerInfo).iCoin >= 200)
{
(*_tplayerInfo).iCoin -= 200;
(_tplayerSkill[2]).iSkillLv += 1;
_tplayerSkill[2].iRecovery += 10;
}
else
{
cout << "코인이 부족합니다." << endl;
system("pause");
}
}
else
cout << "지원하지 않는 입력 값 입니다." << endl;
system("cls");
}
else if (iInput == 2)
{
system("cls");
*_pplayerstate = MAIN;
break;
}
}
}
void PlayerInvenTory(PlayerState* _pplayerstate, PlayerInvenInfo _tEquipInven[], PlayerInvenInfo _tHaveInven[], PlayerInfo* _tplayerInfo)
{
int iInput(0), i_Input(0);
while (true)
{
cout << "=============================================" << endl;
cout << "[장착된 아이템]" << endl;
cout << "---------------------------------------------" << endl;
for (int i = 0; i < _tEquipInven[0].iCount; ++i)
{
cout << "장착된 아이템: " << i + 1 << " 번" << endl;
cout << "아이템 이름 : " << _tEquipInven[i].sName << endl;
cout << "아이템 효과 : " << _tEquipInven[i].sItemEffect << _tEquipInven[i].iEffectNum << "증가" << endl;
cout << "---------------------------------------------" << endl;
}
cout << "=============================================" << endl;
cout << "[보유중인 아이템]" << endl;
cout << "---------------------------------------------" << endl;
for (int i = 0; i < _tHaveInven[0].iCount; ++i)
{
cout << "보유중인 아이템: " << i + 1 << " 번" << endl;
cout << "아이템 이름 : " << _tHaveInven[i].sName << endl;
cout << "아이템 효과 : " << _tHaveInven[i].sItemEffect << _tHaveInven[i].iEffectNum << "증가" << endl;
cout << "---------------------------------------------" << endl;
}
cout << "보유코인 : " << (*_tplayerInfo).iCoin << endl;
cout << "=============================================" << endl;
cout << "1) 아이템 장착. 2) 아이템 장착 해제. 3) 아이템 판매. 4) 메인화면 : ";
cin >> iInput;
switch (iInput)
{
case 1: // 아이템 장착 : 가지고 있는 배열 -> 장착 배열
cout << "장착할 아이템 번호 입력: ";
cin >> i_Input;
switch (i_Input)
{
case 1:
if (_tHaveInven[0].iCount > 0 && _tEquipInven[0].iCount < 3)
{
// 장착한 아이템 효과 플레이어에게 업데이트
PlayerStatsUpdate(_tplayerInfo, _tHaveInven, 0, true);
// 이동한 배열 초기화 및 정렬
ArrSort(1, _tEquipInven, _tHaveInven);
}
break;
case 2:
if (_tHaveInven[0].iCount > 1 && _tEquipInven[0].iCount < 3)
{
PlayerStatsUpdate(_tplayerInfo, _tHaveInven, 1, true);
ArrSort(2, _tEquipInven, _tHaveInven);
}
break;
case 3:
if (_tHaveInven[0].iCount > 2 && _tEquipInven[0].iCount < 3)
{
PlayerStatsUpdate(_tplayerInfo, _tHaveInven, 2, true);
ArrSort(3, _tEquipInven, _tHaveInven);
}
break;
default:
break;
}
break;
case 2:
cout << "장착 해제할 아이템 번호 입력: ";
cin >> i_Input;
switch (i_Input)
{
case 1:
if (_tHaveInven[0].iCount < 3 && _tEquipInven[0].iCount > 0)
{
PlayerStatsUpdate(_tplayerInfo, _tEquipInven, 0, false);
ArrSort(1, _tHaveInven, _tEquipInven);
}
break;
case 2:
if (_tHaveInven[0].iCount < 3 && _tEquipInven[0].iCount > 1)
{
PlayerStatsUpdate(_tplayerInfo, _tEquipInven, 1, false);
ArrSort(2, _tHaveInven, _tEquipInven);
}
break;
case 3:
if (_tHaveInven[0].iCount < 3 && _tEquipInven[0].iCount > 2)
{
PlayerStatsUpdate(_tplayerInfo, _tEquipInven, 2, false);
ArrSort(3, _tHaveInven, _tEquipInven);
}
break;
default:
break;
}
break;
case 3:
cout << "판매할 아이템 번호 입력: ";
cin >> i_Input;
switch (i_Input)
{
case 1:
if (_tHaveInven[0].iCount > 0)
{
_tplayerInfo->iCoin += _tHaveInven[0].iCoin;
// 보유중인 아이템 배열 초기화 및 배열 당기기
if (_tHaveInven[0].iCount == 1)
{
_tHaveInven[0].sName = "미장착";
_tHaveInven[0].sItemEffect = "";
_tHaveInven[0].iEffectNum = 0;
_tHaveInven[0].iNum = 0;
_tHaveInven[0].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
else if (_tHaveInven[0].iCount == 2)
{
_tHaveInven[0].sName = _tHaveInven[1].sName;
_tHaveInven[0].sItemEffect = _tHaveInven[1].sItemEffect;
_tHaveInven[0].iEffectNum = _tHaveInven[1].iEffectNum;
_tHaveInven[0].iNum = _tHaveInven[1].iNum;
_tHaveInven[0].iCoin = _tHaveInven[1].iCoin;
_tHaveInven[1].sName = "미장착";
_tHaveInven[1].sItemEffect = "";
_tHaveInven[1].iEffectNum = 0;
_tHaveInven[1].iNum = 0;
_tHaveInven[1].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
else if (_tHaveInven[0].iCount == 3)
{
_tHaveInven[0].sName = _tHaveInven[1].sName;
_tHaveInven[0].sItemEffect = _tHaveInven[1].sItemEffect;
_tHaveInven[0].iEffectNum = _tHaveInven[1].iEffectNum;
_tHaveInven[0].iNum = _tHaveInven[1].iNum;
_tHaveInven[0].iCoin = _tHaveInven[1].iCoin;
_tHaveInven[1].sName = _tHaveInven[2].sName;
_tHaveInven[1].sItemEffect = _tHaveInven[2].sItemEffect;
_tHaveInven[1].iEffectNum = _tHaveInven[2].iEffectNum;
_tHaveInven[1].iNum = _tHaveInven[2].iNum;
_tHaveInven[1].iCoin = _tHaveInven[2].iCoin;
_tHaveInven[2].sName = "미장착";
_tHaveInven[2].sItemEffect = "";
_tHaveInven[2].iEffectNum = 0;
_tHaveInven[2].iNum = 0;
_tHaveInven[2].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
}
break;
case 2:
if (_tHaveInven[0].iCount > 1)
{
_tplayerInfo->iCoin += _tHaveInven[1].iCoin;
if (_tHaveInven[0].iCount == 2)
{
_tHaveInven[1].sName = "미장착";
_tHaveInven[1].sItemEffect = "";
_tHaveInven[1].iEffectNum = 0;
_tHaveInven[1].iNum = 0;
_tHaveInven[1].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
else if (_tHaveInven[0].iCount == 3)
{
_tHaveInven[1].sName = _tHaveInven[2].sName;
_tHaveInven[1].sItemEffect = _tHaveInven[2].sItemEffect;
_tHaveInven[1].iEffectNum = _tHaveInven[2].iEffectNum;
_tHaveInven[1].iNum = _tHaveInven[2].iNum;
_tHaveInven[1].iCoin = _tHaveInven[2].iCoin;
_tHaveInven[2].sName = "미장착";
_tHaveInven[2].sItemEffect = "";
_tHaveInven[2].iEffectNum = 0;
_tHaveInven[2].iNum = 0;
_tHaveInven[2].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
}
break;
case 3:
if (_tHaveInven[0].iCount > 2)
{
_tplayerInfo->iCoin += _tHaveInven[2].iCoin;
_tHaveInven[2].sName = "미장착";
_tHaveInven[2].sItemEffect = "";
_tHaveInven[2].iEffectNum = 0;
_tHaveInven[2].iNum = 0;
_tHaveInven[2].iCoin = 0;
_tHaveInven[0].iCount -= 1;
}
break;
default:
break;
}
break;
case 4:
system("cls");
*_pplayerstate = MAIN;
return;
default:
break;
}
system("cls");
}
}
void ArrSort(int _iInputNum, PlayerInvenInfo _tlocation[], PlayerInvenInfo _tDatamove[])
{
switch (_iInputNum)
{
case 1:
// 원하는 배열로 이동
_tlocation[_tlocation[0].iCount].sName = _tDatamove[0].sName;
_tlocation[_tlocation[0].iCount].sItemEffect = _tDatamove[0].sItemEffect;
_tlocation[_tlocation[0].iCount].iEffectNum = _tDatamove[0].iEffectNum;
_tlocation[_tlocation[0].iCount].iNum = _tDatamove[0].iNum;
_tlocation[_tlocation[0].iCount].iCoin = _tDatamove[0].iCoin;
_tlocation[0].iCount++;
// 이동한 아이템 배열 초기화 및 배열 당기기
if (_tDatamove[0].iCount == 1)
{
_tDatamove[0].sName = "미장착";
_tDatamove[0].sItemEffect = "";
_tDatamove[0].iEffectNum = 0;
_tDatamove[0].iNum = 0;
_tDatamove[0].iCoin = 0;
_tDatamove[0].iCount -= 1;
}
else if (_tDatamove[0].iCount == 2)
{
_tDatamove[0].sName = _tDatamove[1].sName;
_tDatamove[0].sItemEffect = _tDatamove[1].sItemEffect;
_tDatamove[0].iEffectNum = _tDatamove[1].iEffectNum;
_tDatamove[0].iNum = _tDatamove[1].iNum;
_tDatamove[0].iCoin = _tDatamove[1].iCoin;
_tDatamove[1].sName = "미장착";
_tDatamove[1].sItemEffect = "";
_tDatamove[1].iEffectNum = 0;
_tDatamove[1].iNum = 0;
_tDatamove[1].iCoin = 0;
_tDatamove[0].iCount -= 1;
}
else if (_tDatamove[0].iCount == 3)
{
_tDatamove[0].sName = _tDatamove[1].sName;
_tDatamove[0].sItemEffect = _tDatamove[1].sItemEffect;
_tDatamove[0].iEffectNum = _tDatamove[1].iEffectNum;
_tDatamove[0].iNum = _tDatamove[1].iNum;
_tDatamove[0].iCoin = _tDatamove[1].iCoin;
_tDatamove[1].sName = _tDatamove[2].sName;
_tDatamove[1].sItemEffect = _tDatamove[2].sItemEffect;
_tDatamove[1].iEffectNum = _tDatamove[2].iEffectNum;
_tDatamove[1].iNum = _tDatamove[2].iNum;
_tDatamove[1].iCoin = _tDatamove[2].iCoin;
_tDatamove[2].sName = "미장착";
_tDatamove[2].sItemEffect = "";
_tDatamove[2].iEffectNum = 0;
_tDatamove[2].iNum = 0;
_tDatamove[2].iCoin = 0;
_tDatamove[0].iCount -= 1;
}
break;
case 2:
_tlocation[_tlocation[0].iCount].sName = _tDatamove[1].sName;
_tlocation[_tlocation[0].iCount].sItemEffect = _tDatamove[1].sItemEffect;
_tlocation[_tlocation[0].iCount].iEffectNum = _tDatamove[1].iEffectNum;
_tlocation[_tlocation[0].iCount].iNum = _tDatamove[1].iNum;
_tlocation[_tlocation[0].iCount].iCoin = _tDatamove[1].iCoin;
_tlocation[0].iCount++;
if (_tDatamove[0].iCount == 2)
{
_tDatamove[1].sName = "미장착";
_tDatamove[1].sItemEffect = "";
_tDatamove[1].iEffectNum = 0;
_tDatamove[1].iNum = 0;
_tDatamove[1].iCoin = 0;
_tDatamove[0].iCount -= 1;
}
else if (_tDatamove[0].iCount == 3)
{
_tDatamove[1].sName = _tDatamove[2].sName;
_tDatamove[1].sItemEffect = _tDatamove[2].sItemEffect;
_tDatamove[1].iEffectNum = _tDatamove[2].iEffectNum;
_tDatamove[1].iNum = _tDatamove[2].iNum;
_tDatamove[1].iCoin = _tDatamove[2].iCoin;
_tDatamove[2].sName = "미장착";
_tDatamove[2].sItemEffect = "";
_tDatamove[2].iEffectNum = 0;
_tDatamove[2].iNum = 0;
_tDatamove[2].iCoin = 0;
_tDatamove[0].iCount -= 1;
}
break;
case 3:
_tlocation[_tlocation[0].iCount].sName = _tDatamove[2].sName;
_tlocation[_tlocation[0].iCount].sItemEffect = _tDatamove[2].sItemEffect;
_tlocation[_tlocation[0].iCount].iEffectNum = _tDatamove[2].iEffectNum;
_tlocation[_tlocation[0].iCount].iNum = _tDatamove[2].iNum;
_tlocation[_tlocation[0].iCount].iCoin = _tDatamove[2].iCoin;
_tlocation[0].iCount++;
_tDatamove[2].sName = "미장착";
_tDatamove[2].sItemEffect = "";
_tDatamove[2].iEffectNum = 0;
_tDatamove[2].iNum = 0;
_tDatamove[2].iCoin = 0;
_tDatamove[0].iCount -= 1;
break;
default:
break;
}
}
void StoreState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, PlayerInvenInfo _tHaveInven[])
{
int iInput(0);
system("cls");
cout << "=====================================" << endl;
cout << "[아이템 상점]" << endl;
cout << "-------------------------------------" << endl;
cout << "1번. 멋진 검 ( 300 코인 )" << endl;
cout << " - 공격력 30 증가 ! " << endl << endl;
cout << "2번. 멋진 방패 ( 500 코인 )" << endl;
cout << " - 방어력 20 증가 ! " << endl << endl;
cout << "3번. 체력 회복_1회용 ( 1000 코인 )" << endl;
cout << " - 체력회복 100 증가 ! _1회 " << endl;
cout << "-------------------------------------" << endl;
cout << "보유코인 : " << _pplayerInfo->iCoin << endl;
cout << "=====================================" << endl;
cout << "1) 아이템 구매. 2) 메인화면 : ";
cin >> iInput;
if (iInput == 1)
{
cout << "구매할 아이템 번호 입력: ";
cin >> iInput;
switch (iInput)
{
case 1:
if (_pplayerInfo->iCoin >= 300 && _tHaveInven[0].iCount < 3)
{
_tHaveInven[_tHaveInven[0].iCount].iNum = 1;
_tHaveInven[_tHaveInven[0].iCount].sName = "멋진 검";
_tHaveInven[_tHaveInven[0].iCount].sItemEffect = "공격력";
_tHaveInven[_tHaveInven[0].iCount].iEffectNum = 30;
_tHaveInven[_tHaveInven[0].iCount].iCoin = 300;
_tHaveInven[0].iCount++;
_pplayerInfo->iCoin -= 300;
cout << "구매 성공!" << endl;
}
else
{
cout << "구매 실패!" << endl;
}
break;
case 2:
if (_pplayerInfo->iCoin >= 500 && _tHaveInven[0].iCount < 3)
{
_tHaveInven[_tHaveInven[0].iCount].iNum = 2;
_tHaveInven[_tHaveInven[0].iCount].sName = "멋진 방패";
_tHaveInven[_tHaveInven[0].iCount].sItemEffect = "방어력";
_tHaveInven[_tHaveInven[0].iCount].iEffectNum = 20;
_tHaveInven[_tHaveInven[0].iCount].iCoin = 500;
_tHaveInven[0].iCount++;
_pplayerInfo->iCoin -= 500;
cout << "구매 성공!" << endl;
}
else
{
cout << "구매 실패!" << endl;
}
break;
case 3:
if (_pplayerInfo->iCoin >= 1000 && _tHaveInven[0].iCount < 3)
{
_tHaveInven[_tHaveInven[0].iCount].iNum = 3;
_tHaveInven[_tHaveInven[0].iCount].sName = "체력 회복_1회용";
_tHaveInven[_tHaveInven[0].iCount].sItemEffect = "체력";
_tHaveInven[_tHaveInven[0].iCount].iEffectNum = 100;
_tHaveInven[_tHaveInven[0].iCount].iCoin = 1000;
_tHaveInven[0].iCount++;
_pplayerInfo->iCoin -= 1000;
cout << "구매 성공!" << endl;
}
else
{
cout << "구매 실패!" << endl;
}
break;
default:
break;
}
system("pause");
}
else if (iInput == 2)
{
system("cls");
*_pplayerstate = MAIN;
}
}
void HuntingGround(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, MonsterInfo** _ppMonsterInfo)
{
int iInput(0);
PlayerInfoPrint(*_pplayerInfo);
cout << endl;
cout << "===========================================================" << endl;
cout << "사냥터 입구]" << endl;
cout << "-----------------------------------------------------------" << endl;
cout << "1) 초급 사냥터. 2) 중급 사냥터. 3) 고급 사냥터. 4) 메인화면: ";
cin >> iInput;
system("cls");
switch (iInput)
{
case 1:
*_ppMonsterInfo = new MonsterInfo{};
**_ppMonsterInfo = MonsterCreat(1);
*_pplayerstate = BATTLE;
break;
case 2:
*_ppMonsterInfo = new MonsterInfo{};
**_ppMonsterInfo = MonsterCreat(2);
*_pplayerstate = BATTLE;
break;
case 3:
*_ppMonsterInfo = new MonsterInfo{};
**_ppMonsterInfo = MonsterCreat(3);
*_pplayerstate = BATTLE;
break;
case 4:
*_pplayerstate = MAIN;
break;
default:
break;
}
}
MonsterInfo MonsterCreat(int _iLvMons)
{
MonsterInfo tMonster{};
int iMonsLv = rand() % 10 + 1;
if (_iLvMons == 1)
{
tMonster.sName = "슬라임";
tMonster.sProperty = "물속성";
tMonster.iLv = iMonsLv;
tMonster.iHp = 2 * iMonsLv;
tMonster.iAttack = 2 * iMonsLv;
tMonster.iEx = 10 * iMonsLv;
tMonster.iCoin = 10 * iMonsLv;
}
else if (_iLvMons == 2)
{
tMonster.sName = "고블린";
tMonster.sProperty = "풀속성";
tMonster.iLv = iMonsLv + 10;
tMonster.iHp = 10 * iMonsLv;
tMonster.iAttack = 10 * iMonsLv;
tMonster.iEx = 30 * iMonsLv;
tMonster.iCoin = 20 * iMonsLv;
}
else if (_iLvMons == 3)
{
tMonster.sName = "드래곤";
tMonster.sProperty = "불속성";
tMonster.iLv = iMonsLv + 20;
tMonster.iHp = 200 * iMonsLv;
tMonster.iAttack = 15 * iMonsLv;
tMonster.iEx = 100 * iMonsLv;
tMonster.iCoin = 50 * iMonsLv;
}
return tMonster;
}
void MonsterInfoPrint(MonsterInfo _tmonsterInfo)
{
if (_tmonsterInfo.iHp < 0)
{
_tmonsterInfo.iHp = 0;
}
cout << "=============================================" << endl;
cout << "[생성된 몬스터]" << endl;
cout << "---------------------------------------------" << endl;
cout << "이름 : " << _tmonsterInfo.sName << "\t" << "속성 : " << _tmonsterInfo.sProperty << "\t" << "레벨 : " << _tmonsterInfo.iLv << endl;
cout << "체력 : " << _tmonsterInfo.iHp << "\t" << "공격력 : " << _tmonsterInfo.iAttack << endl;
cout << "=============================================" << endl;
}
void BattlwState(PlayerState* _pplayerstate, PlayerInfo* _pplayerInfo, MonsterInfo* _pmonsterInfo, SkillInfo _tplayerSkill[])
{
int iInput(0), i_Input(0), iCount(0), iRan(0), iRanTrue(0);
while (true)
{
system("cls");
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "1) 공격. 2) 도망 : ";
cin >> iInput;
iRan = rand() % 2 + 1;
// 공격
if (iInput == 1)
{
iCount++;
// 보유 스킬 목록 출력 및 사용
if (iCount % 5 == 0 && _tplayerSkill[0].iUseCoint >= 1)
{
PlayerSkillInfoPrint(_tplayerSkill);
cout << "1) 사용할 스킬 선택: ";
cin >> i_Input;
system("cls");
switch (i_Input)
{
case 1:
if (_tplayerSkill[0].iUseCoint == 1)
{
(*_pmonsterInfo).iHp -= (*_pplayerInfo).iAttack + _tplayerSkill[0].iDamage;
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "회심의 공격 성공!" << endl;
}
break;
case 2:
if (_tplayerSkill[0].iUseCoint == 2)
{
(*_pmonsterInfo).iHp -= (*_pplayerInfo).iAttack + _tplayerSkill[1].iDamage;
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "스페셜 어택 성공!" << endl;
}
break;
case 3:
if (_tplayerSkill[0].iUseCoint == 3)
{
(*_pplayerInfo).iCurrHp += _tplayerSkill[2].iRecovery;
if ((*_pplayerInfo).iCurrHp > (*_pplayerInfo).iHp)
(*_pplayerInfo).iCurrHp = (*_pplayerInfo).iHp;
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "플레이어 생명력 회복 성공!" << endl;
}
break;
default:
cout << "지원하지 않는 입력 값 입니다." << endl;
break;
}
system("pause");
}
else
{
system("cls");
if (iRan == 1) // 플레이어가 몬스터 공격
{
(*_pmonsterInfo).iHp -= (*_pplayerInfo).iAttack;
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "플레이어 -> 몬스터 공격 성공!" << endl;
cout << "몬스터 -> 플레이어 공격 실패!" << endl;
}
else // 몬스터가 플레이어 공격
{
iRanTrue = rand() % 10 + 1;
if (iRanTrue < 3) // 공격 방어
{
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "몬스터의 공격 방어 성공!" << endl;
}
else // 방어 실패
{
(*_pplayerInfo).iCurrHp -= (*_pmonsterInfo).iAttack;
PlayerInfoPrint(*_pplayerInfo);
MonsterInfoPrint(*_pmonsterInfo);
cout << "플레이어 -> 몬스터 공격 실패!" << endl;
cout << "몬스터 -> 플레이어 공격 성공!" << endl;
}
}
system("pause");
}
if ((*_pmonsterInfo).iHp <= 0)
{
cout << "몬스터 사망" << endl;
(*_pplayerInfo).iEx += (*_pmonsterInfo).iEx;
(*_pplayerInfo).iCoin += (*_pmonsterInfo).iCoin;
PlayerLvUp(_pplayerInfo, _tplayerSkill);
*_pplayerstate = HUNTINGGROUND;
system("pause");
system("cls");
return;
}
if ((*_pplayerInfo).iCurrHp <= 0)
{
cout << "플레이어 사망" << endl;
(*_pplayerInfo).iCurrHp = (*_pplayerInfo).iHp;
*_pplayerstate = HUNTINGGROUND;
system("pause");
system("cls");
return;
}
}
// 도망
else if (iInput == 2)
{
if (iRan == 1)
{
cout << "도망 성공!" << endl;
*_pplayerstate = HUNTINGGROUND;
system("pause");
system("cls");
return;
}
else
{
cout << "도망 실패!" << endl;
system("pause");
}
}
system("cls");
}
}
void PlayerLvUp(PlayerInfo* _tplayerInfo, SkillInfo _tplayerSkill[])
{
switch ((*_tplayerInfo).iLv)
{
case 1:
if ((*_tplayerInfo).iEx >= 500)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 50;
(*_tplayerInfo).iCurrHp += 50;
(*_tplayerInfo).iAttack += 20;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
}
break;
case 2:
if ((*_tplayerInfo).iEx >= 1000)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 50;
(*_tplayerInfo).iCurrHp += 50;
(*_tplayerInfo).iAttack += 20;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
_tplayerSkill[0].sName = "[ 회심의 공격 ]";
_tplayerSkill[0].iSkillLv = 1;
_tplayerSkill[0].iDamage = 5;
_tplayerSkill[0].iDefense = 2;
_tplayerSkill[0].iRecovery = 0;
_tplayerSkill[0].iUseCoint = 1;
}
break;
case 3:
if ((*_tplayerInfo).iEx >= 1500)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 50;
(*_tplayerInfo).iCurrHp += 50;
(*_tplayerInfo).iAttack += 20;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
}
break;
case 4:
if ((*_tplayerInfo).iEx >= 2000)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 50;
(*_tplayerInfo).iCurrHp += 50;
(*_tplayerInfo).iAttack += 20;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
}
break;
case 5:
if ((*_tplayerInfo).iEx >= 2500)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 100;
(*_tplayerInfo).iCurrHp += 100;
(*_tplayerInfo).iAttack += 25;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
_tplayerSkill[1].sName = "[ 스패셜 어택 ]";
_tplayerSkill[1].iSkillLv = 1;
_tplayerSkill[1].iDamage = 10;
_tplayerSkill[1].iDefense = 5;
_tplayerSkill[1].iRecovery = 0;
_tplayerSkill[0].iUseCoint = 2;
}
break;
case 6:
if ((*_tplayerInfo).iEx >= 3000)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 100;
(*_tplayerInfo).iCurrHp += 100;
(*_tplayerInfo).iAttack += 30;
(*_tplayerInfo).iDefense += 10;
(*_tplayerInfo).iCoin += 500;
}
break;
case 7:
if ((*_tplayerInfo).iEx >= 3500)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 100;
(*_tplayerInfo).iCurrHp += 100;
(*_tplayerInfo).iAttack += 30;
(*_tplayerInfo).iDefense += 20;
(*_tplayerInfo).iCoin += 500;
}
break;
case 8:
if ((*_tplayerInfo).iEx >= 4000)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 100;
(*_tplayerInfo).iCurrHp += 100;
(*_tplayerInfo).iAttack += 30;
(*_tplayerInfo).iDefense += 20;
(*_tplayerInfo).iCoin += 500;
_tplayerSkill[2].sName = "[ 생명력 회복 ]";
_tplayerSkill[2].iSkillLv = 1;
_tplayerSkill[2].iDamage = 0;
_tplayerSkill[2].iDefense = 0;
_tplayerSkill[2].iRecovery = 50;
_tplayerSkill[0].iUseCoint = 3;
}
break;
case 9:
if ((*_tplayerInfo).iEx >= 5000)
{
(*_tplayerInfo).iLv += 1;
(*_tplayerInfo).iHp += 100;
(*_tplayerInfo).iCurrHp += 100;
(*_tplayerInfo).iAttack += 50;
(*_tplayerInfo).iDefense += 30;
(*_tplayerInfo).iCoin += 1000;
}
break;
default:
break;
}
}
void PlayerStatsUpdate(PlayerInfo* _tplayerInfo, PlayerInvenInfo _pequipInven[], int iNum, bool _btrue)
{
if (_btrue)
{
// 장착할때마다 스탯 업데이트
if (_pequipInven[iNum].iNum == 1)
{
_tplayerInfo->iAttack += _pequipInven[iNum].iEffectNum;
}
else if (_pequipInven[iNum].iNum == 2)
{
_tplayerInfo->iDefense += _pequipInven[iNum].iEffectNum;
}
else if (_pequipInven[iNum].iNum == 3)
{
_tplayerInfo->iCurrHp += _pequipInven[iNum].iEffectNum;
if (_tplayerInfo->iCurrHp > _tplayerInfo->iHp)
_tplayerInfo->iCurrHp = _tplayerInfo->iHp;
}
}
else if (!_btrue)
{
// 장착해제할때마다 스탯 업데이트
if (_pequipInven[iNum].iNum == 1)
{
_tplayerInfo->iAttack -= _pequipInven[iNum].iEffectNum;
}
else if (_pequipInven[iNum].iNum == 2)
{
_tplayerInfo->iDefense -= _pequipInven[iNum].iEffectNum;
}
}
}
void PlayerInfoPrint(PlayerInfo _tplayerInfo)
{
if (_tplayerInfo.iCurrHp < 0)
{
_tplayerInfo.iCurrHp = 0;
}
cout << "=============================================" << endl;
cout << "[플레이어 프로필]" << endl;
cout << "---------------------------------------------" << endl;
cout << "이름 : " << _tplayerInfo.sName << "\t" << "성별 : " << _tplayerInfo.sGender << endl;
cout << "레벨 : " << _tplayerInfo.iLv << "\t" << "경험치 : " << _tplayerInfo.iEx << endl;
cout << "종족 : " << _tplayerInfo.sSpecies << "\t" << "직업 : " << _tplayerInfo.sJob << endl;
cout << "체력 : " << _tplayerInfo.iCurrHp << "\t" << "공격력 : " << _tplayerInfo.iAttack << "\t" << "방어력 : " << _tplayerInfo.iDefense << endl;
cout << "---------------------------------------------" << endl;
cout << "보유코인 : " << _tplayerInfo.iCoin << endl;
cout << "=============================================" << endl;
}
void PlayerSkillInfoPrint(SkillInfo _tplayerSkill[])
{
cout << "[보유 스킬]" << endl;
cout << "---------------------------" << endl;
for (int i = 0; i < _tplayerSkill[0].iUseCoint; ++i)
{
cout << "스킬 번호 : " << i + 1 << " 번" << endl;
cout << "스킬 이름 : " << _tplayerSkill[i].sName << endl;
cout << "스킬 레벨 : " << _tplayerSkill[i].iSkillLv << " 레벨" << endl;
cout << "스킬 효과 : 공격력 " << _tplayerSkill[i].iDamage << " 증가" << endl;
cout << "스킬 효과 : 방어력 " << _tplayerSkill[i].iDefense << " 증가" << endl;
cout << "스킬 효과 : 생명력 " << _tplayerSkill[i].iRecovery << " 증가" << endl;
cout << "---------------------------" << endl;
}
}
# 알게된 점
- 파일에 값을 저장할 때에 주소값을 저장하는 것이 아니라 값 자체를 전달하여 저장하기
- 보유한 스킬, 장착과 보유 아이템 저장 & 불러오기 구현 완료
- -> 얕은 복사 주의하기 : https://blog.naver.com/letsreadbook27/223027190148
- 파일 입출력 시에는 주소(포인터 등)를 이용해야 함.
- -> 저장할 땐 &로 주소값 전달 및 읽어들일 땐 포인터에 저장하는 등.
- 포인터값에 동적할당을 하고싶을 때에는 이중 포인터로 포인터값을 받아와 동적할당하여 사용 가능함.
# 의문점 / 추가 구현해볼 좋을 내용
- Class를 사용하여 Text RPG 수정.
- 동적 할당으로 스킬 배열 추가해보기 -> 실패 시 질문하거나 해결
- 마무리 시 선택화면 오선택 값 막기
'Programming I > C. C++' 카테고리의 다른 글
23.03.09.목_2개월.01_Class (0) | 2023.03.09 |
---|---|
23.03.08.수_1개월.17_미리컴파일된헤더.레퍼런스.string.절차지향.객체지향 (0) | 2023.03.09 |
23.03.06.월_1개월.16_파일함수.매크로.조건부컴파일.레퍼런스 (0) | 2023.03.06 |
23.03.03.금_1개월.15_파일입출력.텍스트모드.바이너리모드 (0) | 2023.03.04 |
23.02.28.화_1개월.14_동적할당.메모리함수 (0) | 2023.03.01 |