1. 코드 및 주요 개념 분석

Inventory 클래스 생성 목적

  • 왜 필요한가?
    • 아이템 관리 문제를 해결하기 위함:
      • 동적으로 생성된 아이템의 소유권 및 메모리 관리를 단순화합니다.
      • 인벤토리를 통해 모든 아이템을 중앙에서 관리하고, 필요할 때 쉽게 생성/제거할 수 있습니다.
      • 인벤토리가 없으면 모든 아이템 객체를 수동으로 추적하고 메모리를 해제해야 하므로 복잡성이 증가합니다.
    • 코드 유지보수성 향상:
      • 인벤토리 시스템을 별도로 두어, 아이템 관련 작업을 단일 책임으로 캡슐화합니다.

1.1 Inventory.h 헤더 파일

#pragma once   
#include "Item.h"

// Enums.h 파일로 상수를 이동
enum {
    MAX_SLOT = 100 // 인벤토리 슬롯 최대 수
};

class Inventory
{
public:
    Inventory();
    ~Inventory();
    bool AddItem(Item* item);       // 아이템 추가
    bool RemoveItem(Item* item);    // 아이템 제거
    Item* GetItemAtSlot(int slot);  // 특정 슬롯의 아이템 반환
    void Clear();                   // 인벤토리 초기화
    static Inventory* GetInstance(); // 싱글톤 인스턴스 반환

private:
    int FindEmptySlot();            // 빈 슬롯 찾기
    int FindItemSlot(Item* item);   // 특정 아이템 위치 찾기

private:
    Item* _items[MAX_SLOT];         // 아이템 포인터 배열
    int _itemCount = 0;             // 현재 아이템 수
    static Inventory* s_instance;  // 싱글톤 인스턴스
};

1.2 Inventory.cpp 소스 파일

#include "Inventory.h"

// 싱글톤 인스턴스를 초기화
Inventory* Inventory::s_instance = nullptr;

Inventory::Inventory()
{
    // 모든 슬롯을 초기화
    for (int i = 0; i < MAX_SLOT; ++i)
        _items[i] = nullptr;
}

Inventory::~Inventory()
{
    Clear(); // 인벤토리 소멸 시 모든 아이템 제거
}

bool Inventory::AddItem(Item* item)
{
    if (item == nullptr) return false; // 유효하지 않은 아이템 거부
    int emptySlot = FindEmptySlot();   // 빈 슬롯 찾기
    if (emptySlot < 0) return false;  // 빈 슬롯 없음

    _items[emptySlot] = item; // 아이템 추가
    _itemCount++;
    return true;
}

bool Inventory::RemoveItem(Item* item)
{
    if (item == nullptr) return false;
    int slot = FindItemSlot(item); // 아이템 슬롯 찾기
    if (slot < 0) return false;    // 슬롯 없음

    delete _items[slot]; // 메모리 해제
    _items[slot] = nullptr; // 슬롯 초기화
    _itemCount--;
    return true;
}

Item* Inventory::GetItemAtSlot(int slot)
{
    if (slot < 0 || slot >= MAX_SLOT) return nullptr; // 유효하지 않은 슬롯 인덱스
    return _items[slot];
}

void Inventory::Clear()
{
    for (int i = 0; i < MAX_SLOT; ++i)
    {
        if (_items[i])
        {
            delete _items[i]; // 동적으로 생성된 아이템 삭제
            _items[i] = nullptr; // 슬롯 초기화
        }
    }
    _itemCount = 0;
}

int Inventory::FindEmptySlot()
{
    for (int i = 0; i < MAX_SLOT; ++i)
    {
        if (_items[i] == nullptr) return i; // 빈 슬롯 반환
    }
    return -1; // 빈 슬롯 없음
}

int Inventory::FindItemSlot(Item* item)
{
    for (int i = 0; i < MAX_SLOT; ++i)
    {
        if (_items[i] == item) return i; // 특정 아이템 슬롯 반환
    }
    return -1; // 아이템 없음
}

Inventory* Inventory::GetInstance()
{
    if (s_instance == nullptr)
    {
        s_instance = new Inventory(); // 싱글톤 인스턴스 생성
    }
    return s_instance;
}

1.3 Item.h

#pragma once

enum ItemRarity
{
    IR_None,
    IR_Normal,
    IR_Rare,
    IR_Unique,
};

enum ItemType
{
    IT_None,
    IT_Weapon,
    IT_Armor,
};

class Item
{
protected:
    Item(ItemType itemType);
public:
    virtual ~Item();
    virtual void PrintInfo() = 0; // 순수 가상 함수
    ItemType GetItemType() { return _itemType; }

protected:
    int _itemId = 0;
    int _itemCount = 0;
    ItemRarity _rarity = IR_Normal;
    ItemType _itemType = IT_None;
};

1.4 main.cpp

#include <iostream>
#include "Inventory.h"
#include "Item.h"

Item* DropItem()
{
    if (rand() % 2 == 0)
    {
        Weapon* weapon = new Weapon();
        return weapon;
    }
    else
    {
        Armor* armor = new Armor();
        return armor;
    }
}

int main()
{
    srand((unsigned)time(0)); // 난수 초기화

    for (int i = 0; i < 100; ++i)
    {
        Item* item = DropItem(); // 무작위로 아이템 드롭
        item->PrintInfo();

        if (Inventory::GetInstance()->AddItem(item))
        {
            std::cout << "Added item to Inventory" << std::endl;
        }
        else
        {
            std::cout << "Failed to add item to Inventory" << std::endl;
            delete item; // 인벤토리에 추가 실패 시 메모리 해제
        }
    }

    // 랜덤으로 일부 아이템 제거 (PK 등 시뮬레이션)
    for (int i = 0; i < 20; ++i)
    {
        int randIndex = rand() % MAX_SLOT; // 무작위 슬롯 선택
        Item* item = Inventory::GetInstance()->GetItemAtSlot(randIndex);
        if (item && Inventory::GetInstance()->RemoveItem(item))
        {
            std::cout << "Removed Item" << std::endl;
        }
    }

    Inventory::GetInstance()->Clear(); // 인벤토리 정리
    delete Inventory::GetInstance(); // 싱글톤 인스턴스 삭제

    return 0;
}

profile
李家네_공부방

0개의 댓글