본문 바로가기

숙제

C++ 3번 과제 테스트(인벤토리 시스템 구현)

어제 만들어 둔 Inventory 클래스

#pragma once
#include <iostream>
#include "Item.h"
#include <algorithm>

template<typename T>
class Inventory
{
private:	
	T* pItems; // 아이템을 받을 동적 배열
	int capacity; // 가방 최대 공간
	int size; // 아이템 개수

public:
	Inventory(int cap = 10) : capacity((cap <= 0) ? cap = 1 : cap), size(0)
	{
		pItems = new T[cap];
	}

	// 복사 생성자
	Inventory(const Inventory<T>& other) // other는 인벤토리 객체
	{
		capacity = other.capacity;
		size = other.size;
		pItems = new T[capacity];
		for (int i = 0; i < size; ++i) // size만큼
		{
			pItems[i] = other.pItems[i]; // 복사
		}
		cout << "인벤토리 복사 완료" << endl;
	}

	// 대입 역할 함수
	void Assign(const Inventory<T>& other)
	{
		delete[] pItems; // 객체가 원래 가지고있던 배열 삭제.

		capacity = other.capacity; // 값을 가지고 올 객체에서 멤버변수 값을 대입함.
		size = other.size;
		pItems = new T[capacity]; // 배열 새로 생성.
		for (int i = 0; i < size; ++i)
		{
			pItems[i] = other.pItems[i];
		}
	}
	
	void AddItem(const T& item)
	{
		if (size < capacity) // 필수 기능과 동일하게 item을 pItems의 원소로 받음
		{
			pItems[size] = item;
			++size;
		}
		else // size가 capacity 이상이면
		{
			capacity = capacity * 2; // capacity 공간 2배
			T* newItems = new T[capacity]; // 새로운 배열 생성
			for (int i = 0; i < size; ++i) // size만큼 새로운 배열에 원소 복사
			{
				newItems[i] = pItems[i];
			}
			
			newItems[size] = item;
			++size;

			delete[] pItems; // 원래 있던 배열 포인터 삭제.
			pItems = newItems; // 배열 포인터에 newItems의 주소 대입.
		}
	}

	void RemoveLastItem()
	{
		if (size > 0)
		{
			--size;
		}
		else
		{
			std::cout << "인벤토리가 비어있습니다." << std::endl;
		}
	}

	void Resize(int newCapacity)
	{
		if (newCapacity <= 0) // 새로운 공간이 0이하면 1로 보정
		{
			newCapacity = 1;
		}

		T* newItems = new T[newCapacity]; // 새로운 배열을 newCapacity 크기로 생성

		if (size > newCapacity) // 재할당된 공간이 기존 아이템 개수보다 작으면
		{
			size = newCapacity; // size를 재할당된 공간으로 맞춰서 그 뒤의 아이템 원소는 삭제
		}

		for (int i = 0; i < size; ++i) // size 만큼 새로운 배열로 원소 복사
		{
			newItems[i] = pItems[i];
		}

		delete[] pItems; // 복사 후 원래 있던 배열 주소 메모리에서 삭제

		pItems = newItems; // 새로운 배열 주소 대입
		capacity = newCapacity;
	}

	static bool compareItemsByPrice(const Item& a, const Item& b)
	{
		return a.GetPrice() < b.GetPrice(); // a가 앞에 오는 원소, 작은거에서 큰순으로 -> 오름차순
	}

	void SortItems()
	{
		std::sort(pItems, pItems + size, compareItemsByPrice); // 배열 시작주소부터 마지막 원소의 다음 주소까지
	}

	int GetSize() const
	{
		return size;
	}

	int GetCapacity() const
	{
		return capacity;
	}

	void PrintAllItems() const
	{
		for (int i = 0; i < size; ++i)
		{
			std::cout << "[이름: " << pItems[i].GetName() << ", 가격: " << pItems[i].GetPrice() << "G]" << std::endl;
		}
	}

	~Inventory()
	{
		delete[] pItems;
		pItems = nullptr;
	}
};

새로 아이템 클래스를 만들었다. 아이템 클래스에는 아이템의 이름 name과 가격 price가 멤버 변수로 있다.

#pragma once
#include <string>
using namespace std;

class Item
{
private:
    string name;
    int price;

public:
    Item(string n = "", int p = 0) : name(n), price(p)
    {
    }
    int GetPrice() const
    {
        return price;
    }
    string GetName() const
    {
        return name;
    }
};

 

 

이제 main 함수에서 어제 만든 함수들이 잘 작동하는지 테스트를 해볼것이다.

#include "Inventory.h"
#include "Item.h"

using namespace std;

int main()
{
	Item Sword("검", 70); // 아이템클래스 검 인스턴스화
	Item Shield("방패", 50); // 아이템클래스 방패 인스턴스화
	Item Bow("활", 100); // 아이템클래스 활 인스턴스화

	Inventory<Item> inv1(3); // 아이템 클래스를 원소로 받는 인벤토리 클래스 인스턴스화

	inv1.AddItem(Sword);
	inv1.AddItem(Shield);
	inv1.AddItem(Bow);

	cout << "아이템 목록" << endl;
	cout << "====================" << endl;
	inv1.PrintAllItems(); // 아이템을 추가 후 모든 아이템 출력

	inv1.RemoveLastItem(); // 마지막 아이템인 활 삭제

	inv1.AddItem(Sword); // 검 추가
	
	cout << "아이템 목록" << endl;
	cout << "====================" << endl;
	inv1.PrintAllItems(); // 활 삭제, 검 추가 후 모든 아이템 출력
	cout << "가방의 최대 크기: " << inv1.GetCapacity() << endl; // 현재 inv1의 capacity

	inv1.AddItem(Bow); // size = Capacity 일 때 아이템 추가

	cout << "활 추가 후 가방의 최대 크기: " << inv1.GetCapacity() << endl; // size > Capacity 일 때 inv1의 capacity

	inv1.AddItem(Sword); // size 6까지 아이템 채움
	inv1.AddItem(Shield); // size 6까지 아이템 채움

	cout << "아이템 목록" << endl;
	cout << "====================" << endl;
	inv1.PrintAllItems();
	cout << "가방의 최대 크기: " << inv1.GetCapacity() << endl; // 현재 capacity, size 둘다 6

	inv1.Resize(4); // capacity = 4로 조정 5,6번째 원소인 Sword와 Shield는 삭제

	cout << "아이템 목록" << endl;
	cout << "====================" << endl;
	inv1.PrintAllItems(); // capacity 4로 조정 후 아이템 출력
	cout << "가방의 최대 크기: " << inv1.GetCapacity() << endl;

	Inventory<Item> inv2(inv1); // inv2에 inv1을 복사하며 생성

	cout << "inv2 아이템 목록" << endl;
	cout << "====================" << endl;
	inv2.PrintAllItems(); // inv2의 아이템 출력
	cout << "현재 가방의 최대 크기: " << inv2.GetCapacity() << endl; // inv2의 capacity

	inv2.SortItems(); // inv2 아이템 가격기준 오름차순으로 정렬

	cout << "inv2 아이템 목록(정렬 후)" << endl;
	cout << "====================" << endl;
	inv2.PrintAllItems(); // 정렬 후 inv2의 아이템 출력

	cout << "inv1 아이템 목록(대입 후)" << endl;
	cout << "====================" << endl;
	inv1.Assign(inv2); // inv1에 가격순으로 정렬된 inv2 대입
	inv1.PrintAllItems(); // 대입 후 inv1 아이템 출력
}

구현한 함수들을 모두 호출해봤고 모두 잘 작동을 한다.