[C++ Project] 등급별 아이템

개요

다키스트 던전을 기반으로 기획했기 때문에 기존구조에 없던 장착 가능한 Artifact형태의 아이템을 구현해야한다.

초기 상태

일단 소비형 아이템과 장착형 아이템의 기능이 다르기 때문에 Artifact class를 따로 만들어 장착형 아이템은 모두 상속받게 만들었다.

현재 3가지 아이템 등급이 있는 enum이 있지만 해당 Artifact가 어떤 등급인지는 알 수 있지만 등급별로 기능은 동일할 수 밖에 없다.

 

요구 사항

사실 내맘대로 아이템을 기획해도 되기 때문에 구현해야할 기능들을 정리해봤다.

장착형 아이템  추가 요구사항

  • 등급이 올라갈 수록 기존 아이템 가격에서 +100씩 가격이 오른다. (Common: 20 -> Rare: 120 -> Ancestal: 220)
  • 등급이 오를수록 아이템이 주는 능력치가 + 1 된다.
  • 아이템명 앞에 등급이 표시된다.

데코레이터 패턴

해당 요구사항들을 상속으로만 구현하려고 하면 HealthStone, RareHealthStone, AncestalHealthStone을 모두 구현 해야하고 아이템이 하나 늘거나 등급이 하나 늘기만 해도 구현해야할 서브 클래스들이 너무 많아진다.

그래서 데코레이터 패턴을 이용해서 기본 Artifact를 등급 Decorator로 감싸서 등급별 기능을 추가하도록 했다.

바뀐 클래스 다이어그램은 다음과 같다.

Rare의 경우 가격을 +100 , 이름앞에 'Rare-'를 붙여주면 되기 때문에 다음과 같이 구현하였다.

#pragma once
#include "ArtifactDecorator.h"

class RareArtifact : public ArtifactDecorator
{

public:
	RareArtifact(Artifact* artifact);
	virtual string GetName() const override { return "Rare-" + wrappee->GetName(); };
	virtual int GetPrice() const override { return 100 + wrappee->GetPrice(); };
	virtual void Attach(Player& player) override;
	virtual void Detach(Player& player) override;
}

RareArtifact로 감쌀때 wrapper의 rank도 변경해주고

능력치를 적용하는 것은 Artifact마다 다르기 때문에 amount만 1증가 시켜준다.

#include "Item/Artifact/RareArtifact.h"
#include "Global/ProjectEnum.h"


RareArtifact::RareArtifact(Artifact* artifact) : ArtifactDecorator(artifact)
{
	wrappee->SetRank(EArtifactRank::RARE);
}

void RareArtifact::Attach(Player& player)
{
	wrappee->SetAmount(wrappee->GetAmount() + 1);
	wrappee->Attach(player);
}

void RareArtifact::Detach(Player& player)
{
	wrappee->Detach(player);
}

사용시

만약  여러 등급의 아이템을 만들고 싶다면 기본 Artifact를 생성한 다음에

Artifact를 원하는 등급의 Artifact로 감싸주면 된다.

int main()
{
	Player player("test");
	Artifact* arti = new HealthStone();
	Artifact* rare = new RareArtifact(arti);
	cout << rare->GetName() << '\n';
	cout << rare->GetPrice() << '\n';
	rare->Attach(player);
}

실행결과

Rare-HealthStone
200
Amount is 2

느낀 점

사실 데코레이터를 꼭 써야 하나 고민이 됐었다. 그냥 패턴이나 하나 적용해보자 하고 억지로 넣은 것 같은....

이렇게 생각하는 이유가 몇 가지 있는데

등급 중복 적용

하나의 아이템에는 하나의 등급이 적용되어야 한다. 하지만 지금 구현한대로면 Rare-Ancestal-Artifact가 될 수도 있다.

추가 구현없이 여러개의 데코레이터를 계속 붙일 수 있는게 데코레이터 패턴의 장점인데 이를 활용하지 못한다.

변수 접근

데코레이터가 wrapper의 기능에 추가하기 위해 변수를 직접적으로 접근을 못한다는 점이다. 때문에 public으로 Set함수를 추가로 만들어야 했고 결과적으로 누구나 해당 변수를 변경할 수 있게 됐다.

직접적으로 protected 변수를 변경하는 경우는 데코레이터가 잘 맞지 않는다고 느꼈다.

 

'C++' 카테고리의 다른 글

[STL] STL && STL 관련 함수 정리  (0) 2025.02.19
[C++ Projet] Text기반 게임 회고  (0) 2025.01.17
[C++ Project] text기반 게임 기획  (0) 2025.01.10
[C++] regex로 정규 표현식 사용하기  (0) 2025.01.06
[C++] STL queue  (0) 2024.12.30