인벤토리 구현

게임을 하면서 인벤토리의 기능은 플레이어에게 자연스럽게 다가오는 기능이다.

이 기능의 기본적인 기능을 템플릿을 통해 구현해 보는 것이 목표이다.


 

요구사항

Inventory 템플릿 클래스 구현

Item 뿐만 아니라, Weapon, Potion 등 어떤 타입의 객체든 저장할 수 있도록 템플릿 클래스로 구현

  • 템플릿 : template<typename T>를 사용하여 어떤 타입(T)의 데이터든 처리할 수 있도록 한다.

멤버 변수 (private)

  • T* pItem : 아이템 객체들을 저장할 동적 배열을 가리키는 포인터
  • int capacity : 인벤토리가 최대로 저장할 수 있는 공간의 크기
  • int size : 현재 인벤토리에 저장된 아이템의 실제 개수

생성자 / 소멸자

  • 생성자 - Inventory(int capacity = 10)
    • 인벤토리 객체가 생성될 때 호출
    • 매개변수로 인벤토리의 용량(capacity)을 받으며, 값을 전달하지 않으면 기본값으로 10이 설정
    • 안정성을 위해, 만약 0이하의 capacity값이 들어오면 최소 용량을 1로 보정
    • new T[capacity]를 실행하여 아이템을 저장할 메모리 공간을 힙(Heap)에 할당
  • 소멸자 - ~Inventory()
    • 인벤토리 객체가 소멸될 때 자동으로 호출
    • delete[] pItem 를 실행하여 생성자에서 할당했던 메모리를 반드시 해제
    • 안전한 코드를 위해, 메모리를 해제 후 포인터를 nullptr로 초기화

멤버 함수 (public)

외부에서 인벤토리 객체를 조작하기 위해 사용하는 기능들입니다.

  • void AddItem(const T& item)
    • 새로운 아이템을 인벤토리에 추가합니다.
    • size_가 capacity_보다 작을 경우에만 아이템을 추가하고, size_를 1 증가시킵니다.
    • 인벤토리가 꽉 찼다면 "인벤토리가 꽉 찼습니다!" 메시지를 출력하고 아무 동작도 하지 않습니다.
  • void RemoveLastItem()
    • 인벤토리의 가장 마지막에 추가된 아이템을 제거합니다.
    • 실제로 메모리를 지우는 것이 아니라, 아이템의 개수를 나타내는 size_를 1 감소시켜 마지막 아이템에 접근할 수 없도록 만듭니다.
    • 인벤토리가 비어있다면 "인벤토리가 비어있습니다." 메시지를 출력합니다.
  • int GetSize() const
    • 현재 인벤토리에 저장된 아이템의 개수(size_)를 반환합니다.
  • int GetCapacity() const
    • 인벤토리의 최대 저장 용량(capacity_)을 반환합니다.
  • void PrintAllItems() const
    • 인벤토리에 있는 모든 아이템의 정보를 화면에 출력합니다.
    • for 반복문을 이용해 0번 인덱스부터 size_ - 1번 인덱스까지 순회하며, 각 아이템 객체의 PrintInfo() 멤버 함수를 호출합니다.

코드 구현

#include <iostream>
#include <string>

using namespace std;

class item
{
private:
	string type;
	string itemName;
	int price;

public:
	item(string name = "", int _price = 0) :
		type("기타"),
		itemName(std::move(name)),
		price(_price)
	{

	}

	void PrintType()	// 해당 인벤토리 카테고리 출력
	{
		cout << "[  " << type << "  ]" << endl;

	}

	void Print() const
	{
		cout << "[ 이름 : " << itemName << ", 가격 : " << price << "G ]" << endl;
	}
};

class Weapon 
{
private:
	string type;
	string weaponName;
	int price;

public:
	Weapon(string name = "", int _price = 0) :
		type("장비"),
		weaponName(name),
		price(_price)
	{

	}
	
	void PrintType()	// 해당 인벤토리 카테고리 출력
	{
		cout << "[  " << type << "  ]" << endl;

	}

	void Print() const
	{
		cout << "[ 이름 : " << weaponName << ", 가격 : " << price << "G ]" << endl;
	}
};

class Potion 
{
private:
	string type;
	string potionName;
	int price;

public:
	Potion(string name = "", int _price = 0) :
		type("포션"),
		potionName(name),
		price(_price)
	{

	}

	void PrintType()	// 해당 인벤토리 카테고리 출력
	{
		cout << "[  " << type << "  ]" << endl;

	}

	void Print() const
	{
		cout << "[ 이름 : " << potionName << ", 가격 : " << price << "G ]" << endl;
	}
};


template<typename T>
class Inventory
{
private:
	string invenType;
	T* pItem;
	int capacity;
	int size;

public:
	Inventory(int _capacity = 10) :	// 생성자에서 최대용량(capacity) 10 지정
		invenType(""),
		pItem(new T[_capacity]),
		capacity(_capacity),
		size(0)						// 초기화 리스트로 멤버 변수 초기화
	{

	}
	~Inventory()					// 소멸자에서 동적 메모리 해제 및 nullptr로 초기화
	{
		delete[] pItem;
		pItem = nullptr;
	}
	void AddItem(const T& item)		// 인벤토리에 아이템 추가
	{
		if(size < capacity) 
		{ 
			pItem[size] = item;
			size++;					// 아이템 추가 후현재용량(size) +1
		}
	}

	void removeLastItem()			// 제일 최근에 추가된 아이템 삭제
	{
		if (size > 0) { size--; }	// 아이템 삭제 후 현재용량(size) -1
	}

	int getSize() const { return size; }	// getter

	int getCapacity() const { return capacity; }	// getter

	void PrintInvenType() const				// 인벤토리 카테고리 출력함수 호출
	{
		pItem->PrintType();
	}

	void PrintItem() const					// 현재 보유 아이템 모두 출력
	{
		for (int i = 0; i < size; ++i)
		{
			pItem[i].Print();
		}
	}

};

int main()
{
	Inventory<item>* itemInventory = new Inventory<item>();
	Inventory<Weapon>* weaponInventory = new Inventory<Weapon>();
	Inventory<Potion>* potionInventory = new Inventory<Potion>();

	item _item = item("나무", 30);				// 기타 타입 아이템 추가
	itemInventory->AddItem(_item);
	
	Weapon _weapon = Weapon("롱소드", 350);		// 장비 타입 아이템 추가
	weaponInventory->AddItem(_weapon);
	
	Potion _potion = Potion("회복포션", 50);	// 포션 타입 아이템 추가
	potionInventory->AddItem(_potion);

	itemInventory->PrintInvenType();	// 인벤토리 타입 출력
	itemInventory->PrintItem();			// 기타 타입 아이템 모두 출력
	
	weaponInventory->PrintInvenType();	
	weaponInventory->PrintItem();		// 장비 타입 아이템 모두 출력
	
	potionInventory->PrintInvenType();	
	potionInventory->PrintItem();		// 포션 타입 아이템 모두 출력

	delete itemInventory;				// 메모리 할당 해제
	delete weaponInventory;
	delete potionInventory;

	itemInventory = nullptr;			// nullptr로 초기화

	return 0;
}

+ Recent posts