연금술 제작법 관리 시스템 (2)

 

게임 속에 있을 연금술 제작 공방 관리 프로그램

 

기능 요구사항

기존  연금술 공방 관리 시스템에 검색 기능 추가

  • 물약 이름으로 검색이 가능해야 한다.
  • 재료로 검색이 가능해야 한다. 특정 재료가 포함된 모든 레시피를 찾을 수 있어야 한다.
  • 물약 이름이 동일한 경우는 없다고 가정

#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;

class PotionRecipe
{
private:
	string potionName;
	vector<string> ingredients;

public:
	PotionRecipe(const string& name, const vector<string>& ingredient)
	{
		potionName = name;
		ingredients = ingredient;
	}

	const int GetSize() const { return ingredients.size(); }

	const vector<string>& GetIngredients() const { return ingredients; }	// const &를 안붙이면 겟 할때마다 복사생성자가 호출된다.

	bool operator==(const PotionRecipe& recipe) const
	{
		return potionName == recipe.potionName && ingredients == recipe.ingredients;
	}
};

class AlchemyWorkShop
{
private:
	vector<PotionRecipe> recipes;
	map<string, PotionRecipe> storage;	// map의 선언 map<key타입, value타입> 
public:
	AlchemyWorkShop() 
	{
		 
	}

	void addRecipe(const string& name, const vector<string>& ingredients)
	{
		PotionRecipe potionRecipe(name, ingredients); // 포션 클래스 선언 및 이름과 재료를 넣어 초기화	
		recipes.push_back(potionRecipe);	//	PotionRecipe 클래스 타입 백터에 푸쉬

		storage.emplace(name, potionRecipe);	// map.insert(ket값, value값)
	}
	
	void displayAllRecipes() const
	{
		
		for (const auto& pair : storage)
		{
			
			cout << "name : " << pair.first << ", 재료 : ";
			for (const auto& vec : pair.second.GetIngredients())
			{
				cout << vec << " ";
			}
			cout << endl;
		}

	}

	PotionRecipe searchRecipeByName(const string& name)
	{
		const auto& it = storage.find(name);	// 그냥 find의 결과값이 이터레이터로 감싸져있어서 *로 포장 뜯어서 사용
		if (it == storage.end()) return PotionRecipe("None", vector<string>()); // 못찾으면 end값이랑 같아지고 end는 빈값
		const auto& pair = *it;	

		for (const auto& ingredient : pair.second.GetIngredients())	// ingredient & 안붙이면 스트링 복사생성자 호출 / const 는 수정 불가
		{
			cout << ingredient << endl;
		}
		return pair.second;
	}

	vector<PotionRecipe> searchRecipeByIngredient(const string& ingredient)
	{
		vector<PotionRecipe> result;

		for(const auto& pair : storage)
		{
			const auto& ingredients = pair.second.GetIngredients();

			for (const auto& item : ingredients)
			{
				if (item == ingredient)
				{
					cout << pair.first << endl;
					result.push_back(pair.second);
				}
			}
		}
		return result;
	}
};


int main()
{
	vector<string> ingredients;
	AlchemyWorkShop* potion = new AlchemyWorkShop();



	potion->addRecipe("healing potion", { "버섯", "물" });
	potion->addRecipe("Mana potion", { "별가루", "물" });
	potion->addRecipe("stamina potion", { "허브", "물" });
	potion->addRecipe("strength potion", { "각성가루", "녹용", "황금잉어"});

	potion->displayAllRecipes();

	potion->searchRecipeByName("healing potion");

	
	vector<PotionRecipe> waterRecipes =
		potion->searchRecipeByIngredient("물");

	if (waterRecipes.empty()) // 검색한 재료를 사용한 레시피가 없을 때의 예외처리 + 벡터는 빈값을 가져도 에러가 발생하지 않는다.
	{
		cout << "해당 재료를 사용한 레시피가 없습니다." << endl;
	}
	cout << "물을 사용하는 레시피 수 : "
		<< waterRecipes.size() << endl;

	delete potion;
	return 0;
}

searchRecipeByIngredient(const string& ingredient)

재료이름을 통해 검색하는 기능을 추가하여 요구사항을 최종적으로 완성하였다.

 

기능 구현 과정

AlchemyWorkShop 클래스 멤버 변수 storage(map<string, vector<PotionRecipe>>) 에서 value인 클래스 타입 벡터가 필요하기에 pair.second.GetIngredients() (value의 클래스 멤버 getter를 통해 가져오고 가져온 벡터를 for each 문을 통해 검색어와 같은 데이터를 찾고 있다면 그 벡터를 새로운 벡터에 저장하여 리턴한다.

+ Recent posts