본문 바로가기
공부

C++ 샵&인벤토리 아이템 수량 추가

by MY블로그 2022. 11. 29.

지난번 과제에 아이템구매시 인벤토리가 계속 늘어나지않고

아이템의 종류별로 수량이 증가하도록 만들었다.

수량이 0개가되몇 인벤토리에서 아이템의 배열이 제거 된다.

 

아이템 구매시 아이템정보와 같은 함수가 프린트되면 갯수가 1개로 나오기때문에

별도로 상점 프린트함수를 만들었다.

추가적으로 플레이어의 돈은 랜덤으로 받아볼수있게 간단히 만들어봤다.

 

Item.h
#pragma once
class Item
{
private: //자식한테도 비공개
	
protected: //자식한테만 공개

public:
	string name;
	int price;
	int num; // 아이템 갯수

	Item();
	//추상화로 생성했다면 가상함수로 소멸
	virtual ~Item();

	//생성자 오버로딩
	//Item(string _name);
	Item(string _name, int _price);
	Item(const Item& src);

	//가상함수 : 자식클래스에서 재정의가 이루어질거라고 예상될 때
	virtual void SPrint();
	virtual void Print();
	virtual Item* Create(const Item* src);
};

class Weapon : public Item //상속
{
public:
	int att;

	Weapon();
	~Weapon();
	Weapon(string _name, int _price, int _att);
	Weapon(const Weapon& src);// 다운캐스팅 Weapon& 이라고 명시해둠

	void SPrint() override; //재정의
	void Print() override; //재정의
	Item* Create(const Item* src) override; //재정의
};

class Armor : public Item //상속
{
public:
	Armor();
	~Armor();
	Armor(string _name, int _price, int _def);
	Armor(const Armor& src);// 다운캐스팅 Armor& 이라고 명시해둠

	int def;
	void SPrint() override; //재정의
	void Print() override; //재정의
	Item* Create(const Item* src) override; //재정의
};
Item.cpp
#include "stdafx.h"

Item::Item()
{
	//cout << "아이템 생성" << endl;
}

Item::~Item()
{
	//cout << "아이템 소멸" << endl;
}

Item::Item(string _name, int _price) 
	: name(_name), price(_price), num(1)
{
}

Item::Item(const Item& src)
{
	name = src.name;
	price = src.price;
	num = src.num;
}

void Item::SPrint()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << endl;
}

void Item::Print()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << "\t"
		<< "수량 : " << num << endl;
}

Item* Item::Create(const Item* src)
{
	return new Item(*src);
}

Weapon::Weapon()
{
	//cout << "무기 생성" << endl;
}

Weapon::~Weapon()
{
	//cout << "무기 소멸" << endl;
}

Weapon::Weapon(string _name, int _price, int _att)
	: att(_att), Item(_name, _price)
{
}

Weapon::Weapon(const Weapon& src)
	: Item(src), att(src.att)
{
}

void Weapon::SPrint()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << "\t"
		<< "공격력 : " << att << endl;
}

void Weapon::Print()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << "\t"
		<< "공격력 : " << att << "\t"
		<< "수량 : " << num << endl;
}

Item* Weapon::Create(const Item* src)
{
	return new Weapon(*(Weapon*)src);
}

Armor::~Armor()
{
	//cout << "방어구 소멸" << endl;
}

Armor::Armor(string _name, int _price, int _def)
	: def(_def), Item(_name, _price)
{
}

Armor::Armor(const Armor& src)
	: Item(src), def(src.def)
{
}

void Armor::SPrint()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << "\t"
		<< "방어력 : " << def << endl;
}

void Armor::Print()
{
	cout << "아이템 : " << name << "\t"
		<< "가격 : " << price << "\t"
		<< "방어력 : " << def << "\t"
		<< "수량 : " << num << endl;
}

Item* Armor::Create(const Item* src)
{
	return new Armor(*(Armor*)src);
}
Shop.h
#pragma once
class Shop
{
public:

	Item* items[6]; //추상화
	//추상화 <-> 구체화

	vector<Item*> inven; // 벡터로 만든다.

public:
	void GoShop();
};
Shop.cpp
#include "stdafx.h"

void Shop::GoShop()
{

	items[0] = new Item("도토리", 100);
	items[1] = new Item("돌맹이", 200);
	items[2] = new Weapon("나뭇가지", 100, 10);
	items[3] = new Weapon("나무몽둥이", 200, 30);
	items[4] = new Armor("냄비뚜껑", 100, 10);
	items[5] = new Armor("롱패딩", 300, 30);

	int money;

	while (true)
	{
		int moneychoice;
		int randomnum;

		system("cls"); // 화면깔끔하게
		cout << "[ 심심해서 만들어본 용돈뽑기! ]" << endl;
		cout << endl;
		cout << "숫자 777 을 입력해 주세요 !!! " << endl;
		cin >> moneychoice;
		if (moneychoice == 777)
		{
			randomnum = rand() % 3;
			switch (randomnum)
			{
			case 0:
				money = 50000;
				cout << "조금 운이 좋았다!" << endl;
				cout << endl;
				cout << "[" << money << "]" << "의 용돈을 받았습니다." << endl;
				Sleep(1500);
				break;
			case 1:
				money = 100000;
				cout << "오늘은 운이 좋은 것 같다!" << endl;
				cout << endl;
				cout << "[" << money << "]" << "의 용돈을 받았습니다." << endl;
				Sleep(1500);
				break;
			case 2:
				money = 9999999;
				cout << "와 이게 떠버리네..." << endl;
				cout << endl;
				cout << "[" << money << "]" << "의 용돈을 받았습니다." << endl;
				Sleep(1500);
				break;
			}
		}
		else
		{
			cout << "플레이어는 용돈을 받고 싶지 않은 것 같습니다." << endl;
			cout << endl;
			cout << "1000 원만 가져가세요." << endl;
			money = 1000;
			Sleep(1500);
			break;
		}
		break;
	}

	while (true)
	{

		int shopmainselect; // 메인 선택 변수

		system("cls"); // 화면깔끔하게
		cout << "[1].상점 [2].인벤토리 [그외].나가기" << "\t" << "현재소지금 : " << money << " $ " << endl;
		cin >> shopmainselect;

		if (shopmainselect == 1)
		{
			cout << endl;
			cout << "[아이템목록]" << endl;
			cout << endl;
			for (int i = 0; i < 6; i++)
			{
				cout << "[" << i << "]";
				items[i]->SPrint(); // 샵에서는 아이템 수량이 보이지 않도록 프린트함수 새로 만듬
			}
			cout << endl;
			int choice;
			cout << "구매할 아이템을 선택해주세요 : ";
			cin >> choice;
			if (choice > 5) // 현재 아이템의 갯수는 0~5 까지 이다. 6번은 없으니 예외처리.
			{
				cout << "잘못선택하셨습니다. 다시 선택해 주세요." << endl;
				Sleep(1500);
				continue;
			}
			bool isCheck = 0; // 불값을 이용한 인벤 아이템 종류 체크 (초기값 : 거짓)
			int index;
			for (index = 0; index < inven.size(); index++)
			{
				if (inven[index]->name == items[choice]->name)
				{ // 인벤토리내역에 아이템이름과 구매로선택안 아이템이름이같다면
					isCheck = true; // 불값을 참(1)으로 바꾸고
					break;
				}
			}
			if (isCheck) // 불값이 참(1)이면 if 문으로 들어와서
			{
				inven[index]->num++; // 인벤에있는 아이템의 카운트를 증가시킨다.
			}
			else // 그렇지않다면(구매한아이템이 인벤에 없는 아이템이라면) 푸시백으로 아이템배열추가
			{
				inven.push_back(items[choice]->Create(items[choice]));
			}

			money -= items[choice]->price;
			cout << endl;
			cout << "[ " << items[choice]->name << " ]" << " 을 획득했다!";
			cout << endl;
			cout << endl;
			cout << "구매완료 " << items[choice]->price << " $ 사용" << endl;
			Sleep(1500);

		} ////////////////////////////////////////////////////////상점 끝 인벤토리시작
		if (shopmainselect == 2)
		{
			//system("cls");
			cout << endl;
			cout << "[인벤토리]" << endl;
			cout << endl;

			for (int i = 0; i < inven.size(); i++) // 인벤토리 크기만큼 포문으로 출력
			{
				cout << "[" << i << "]"; inven[i]->Print();
			}

			int invenchoice;
			cout << endl;
			cout << "[1].판매하기 [2].나가기"; cin >> invenchoice;
			if (invenchoice == 1)
			{
				cout << endl;
				int sellchoice;
				cout << "판매할 아이템의 번호를 입력해 주세요 : "; cin >> sellchoice;

				if (sellchoice > inven.size()) // 판매선택이 목록에 없을경우
				{
					cout << "잘못 입력하였습니다. 다시 입력해 주세요." << endl;
					Sleep(1500);
					continue;
				}
				else if (inven[sellchoice]->num == 1) // 인벤의 아이템 수량이 1개일경우
				{

					money += inven[sellchoice]->price;
					cout << endl;
					cout << endl;
					cout << "판매완료 " << inven[sellchoice]->price << " $ 획득" << endl;
					cout << endl;
					cout << "마지막" << "[ " << inven[sellchoice]->name << " ]" << "가 판매되어"
						<< "목록에서 사라졌다!";
					delete inven[sellchoice]; // 메모리 누수없도록 할당 해제후에
					inven.erase(inven.begin() + sellchoice); // 배열 삭제
					Sleep(1500);
				}
				else
				{
					cout << endl;
					cout << "[ " << inven[sellchoice]->name << " ]" << " 의 수량 1 감소.";
					cout << endl;
					cout << endl;
					cout << "판매완료 " << inven[sellchoice]->price << " $ 획득" << endl;
					money += inven[sellchoice]->price;
					inven[sellchoice]->num--;
					Sleep(1500);
				}
			}
			else// 인벤에서 판매하지 않을 경우 탈출
			{
				continue;
			}
		} /////////////////////////////////////////////////////인벤토리 끝
		else // main에서 상점or인벤토리가 아닐경우 탈출.
		{
			continue;
		}
	}////////////////////////////////////////////////////////while 반복문 끝

	for (int i = 0; i < 6; i++)
	{
		delete items[i]; // 동적할당 해제
		//클론으로 만든 items도 같이 해제됨.
	}

	for (int i = 0; i < inven.size(); i++)
	{
		delete inven[i]; // 동적할당 해제
	}

	inven.clear(); // 배열 제거
	inven.shrink_to_fit(); // 내부 버퍼 제거
	// 위에서 인벤 배열은 삭제되었으나 안전하게 한번더 없애주고
	// 버퍼도 지워주면 좋다.
}

'공부' 카테고리의 다른 글

C++ 생성자(복사,이동,push_back,emplace_back)  (0) 2022.11.30
C++ 파라미터와 인자의 차이점  (1) 2022.11.30
C++ Lvalue & Rvalue  (0) 2022.11.29
C++ 인벤토리 판매기능 추가  (0) 2022.11.28
C++ 복사생성자 & 팩토리패턴  (0) 2022.11.28

댓글