https://zerosik00.tistory.com/59
C++ 인벤토리, 제작시스템 구현해보기 4
https://zerosik00.tistory.com/58 C++ 인벤토리, 제작시스템 구현해보기 3https://zerosik00.tistory.com/57 C++ 인벤토리, 제작시스템 구현해보기 2https://zerosik00.tistory.com/56 C++ 인벤토리, 제작시스템 구현해보기 1목
zerosik00.tistory.com
오늘의 목표 : 아이템별 저장 상한치 구현하기
여러 게임에는 인벤토리 한칸당 어떤 아이템이 들어갈 수 있는 개수가 다르다.
예시로 마인크래프트를 보면 일반적으로 인벤토리 한칸에
블럭, 재료는 64개.
도구, 포션 등 사용 가능한 아이템은 1개가 들어간다.
그러나 예외가 있는데 엔더진주, 표지판, 계란등이 이에 속한다.

이는 아이템의 과도한 성능(엔더진주의 텔레포트기능)이 이유일수도 있고,
인벤토리 내 아이템 관리에 의미를 두는것일수도 있으나 우선 이를 구현해보려 한다.
우선 어떤 방법으로 추가할지를 생각해봐야하는데 현재 상황을 먼저 점검하면
Inventory에는 최대 스택을 제한할 int maxStack변수가 있긴하다. 다만 이는 현재 타입별, 아이템별 적용이 불가해 무의미하다.
그래서 생각한 방법이
1안. Inventory의 maxStack을 maxStackPotion, maxStackPotion등으로 분기
이 방식을 사용하면 위의 경우처럼 특수한 아이템이 생길경우 아이템별 분기를 설정해야해서 분기가 길어지고 유지보수가 어려워질것으로 생각된다.
2안. ItemDatabase클래스에 타입별 최대스택을 구성해두는 방안,
이 방식도 특별한 아이템이 생길 때 마다 분기가 추가될것이니 나중에 보기 힘들것같다.
3안. 아이템 자체에 maxStack값을 추가하기.
#include <string>
#include "ItemType.h"
class Item {
int id;
std::string name;
std::string description;
ItemType itemType;
public:
Item() :id(-1), name("NO DATA"), description("NO DATA"), itemType(ItemType::None){}
Item(int _id, const std::string& _name, const std::string& _desc, ItemType type, int _maxStack) :
id(_id), name(_name), description(_desc), itemType(type) {}
}
현재 Item구성은 위 코드처럼 id, 이름, 설명 그리고 타입을 가지고있다.
여기 맴버변수로 maxStack을 추가하여 아이템별로 값을 관리하도록 하는 방법.
Item클래스는 DB의 데이터 컬럼을 생각하고 만들어두어서 Item자체에 추가하는것이 가장 바람직하다고 생각된다.
이 경우 당장 작성할 코드는 가장 많을것 같지만 장기적으로 가장 깔끔한 코드가 될것으로 생각된다.
하여 작업할 내용은 다음과 같다.
Item의 멤버변수 maxStack추가.
ItemDatabase에 타입별 기본값을 정의하고 반환할수 있도록 함수 추가.
Inventory에 database참조를 추가하고, addItem 호출시 maxStack을 참조하여 최대값을 제한
사용자가 아이템데이터를 추가하는 tryAddCustomItem에 최대스택값을 입력할 수 있도록 추가(함수 오버로딩 예상)
멤버변수 추가는 간단히 값추가로 끝.
타입별 기본값을 반환하는 함수를 ItemDatabase에 추가
class ItemDatabase
{
private:
std::map<int, Item> itemDatabase;
void initializeItemDatabase();
ItemDatabase() { initializeItemDatabase(); }
int getItemDefaultStack(ItemType type);
}
int ItemDatabase::getItemDefaultStack(ItemType type)
{
switch (type) {
case ItemType::Material:
return 100;
case ItemType::Potion:
return 3;
default:
return -1;
}
}
재료는 최대 100개, 포션은 최대 3개로 설정해두었다.
따로 item의 maxStack을 지정하지 않은경우 이걸 통해 기본값을 가져올것이다.
Inventory에 ItemDatabase 참조 추가하고 이를이용해 스택 제한하기
#include "ItemType.h"
#include "ItemDatabase.h"
class Inventory {
private:
ItemDatabase& database;
std::map<int, int> stock;
};
원래있던 허접한 int maxStack을 제거하고 ItemDatabase클래스를 추가하였다.
해당 클래스는 싱글톤 객체이기 때문에 값참조를 사용하여 가볍게 사용 가능하다
그리고 아이템추가 addItem함수에 값을 참고하여 성공실패를 가르도록 수정한다.
bool Inventory::addItem(int itemId, int count)
{
if (count <= 0)
return false;
const Item* item = database.getItemById(itemId);
if (item == nullptr)
return false;
auto it = stock.find(itemId);
if (it == stock.end()) {
if (count > item->getMaxStack())
return false;
stock[itemId] = count;
}
else {
if ((it->second + count) > item->getMaxStack())
return false;
else {
it->second += count;
}
}
return true;
}
getMaxStack()을 통해 최대스택을 확인하고 분기한다.
마지막으로 ItemDatabase에 아이템 추가함수를 오버로딩하여 maxStack을 따로 지정하지 않은 경우를 처리한다.
기존의 함수에 maxStack을 받도록 파라미터를 추가하고
maxStack이 없는 함수는 기본값을 받아서 전달해주는 역할을한다.
이렇게하여 기존에 maxStack을 입력하지 않고 사용하던 함수들도 정상 작동할 수 있다.
QueryResult ItemDatabase::tryAddCustomItem(
const std::string& name, const std::string& desc, ItemType type)
{
int maxStack = getItemDefaultStack(type);
return tryAddCustomItem(name, desc, type, maxStack);
}
QueryResult ItemDatabase::tryAddCustomItem(
const std::string& name, const std::string& desc, ItemType type, int maxStack) {
//아이템 존재하는지 먼저 체크
for (const auto& [k, v] : itemDatabase) {
if (v.getName() == name) {
return { QueryResultType::AlreadyExist , k };
}
}
int startIdx, endIdx;
switch (type) {
case(ItemType::Material):
startIdx = 0, endIdx = 100;
break;
case(ItemType::Potion):
startIdx = 100, endIdx = 200;
break;
default:
return { QueryResultType::InvalidItemType, -1 };
}
if (maxStack == -1) {
maxStack = getItemDefaultStack(type);
}
//신규 아이템 추가
for(int idx = startIdx ; idx < endIdx ; idx++){
//아이템 ID가 사용중이지 않으면 해당 아이디 사용.
if (itemDatabase.contains(idx) == false) {
itemDatabase.emplace(idx, Item{ idx, name, desc, type, maxStack });
return { QueryResultType::Success, idx };
}
}
return { QueryResultType::NoAvailableId , -1 };
}
이제 기존에 각 기능을 테스트하던 코드는 아무 이상이없으면서,
아이템을 새로 추가할때 해당 객체의 최대 개수를 제한하도록 해 볼 수 있다.
마지막으로 Inventory도 결과 객체를 추가하여,
인벤토리관련 함수의 실행결과를 좀 더 명확히 하여 상황별 대응이 좀 더 쉽도록 추가하였다.
enum class StoreResultType {
Success,//성공
CannotStackItems,
InventoryIsFull,
AtLeastOneRequired,
ItemNotFound,
ItemNotEnough
};
struct StoreResult {
StoreResultType resultType;
};
https://github.com/Zerosik/nbc_cpp_project4/tree/master/nbc_cpp_project4
nbc_cpp_project4/nbc_cpp_project4 at master · Zerosik/nbc_cpp_project4
내일배움캠프 cpp 과제4. Contribute to Zerosik/nbc_cpp_project4 development by creating an account on GitHub.
github.com
'개발 > 내일배움캠프' 카테고리의 다른 글
| 언리얼 멀티플레이어 개발전 설정들 (0) | 2026.06.01 |
|---|---|
| 내배캠 2차과제후 피드백 키워드 개념 정리 (0) | 2026.04.01 |
| C++ 인벤토리, 제작시스템 구현해보기 4 / 실제 기능 구현 (0) | 2026.03.18 |
| C++ 인벤토리, 제작시스템 구현해보기 3 (0) | 2026.03.16 |
| C++ 인벤토리, 제작시스템 구현해보기 2 (0) | 2026.03.13 |