C# 머드 게임 프로젝트 (3)
일단 전투를 추가하기 전에 상점 기능을 추가하였다.
private Tuple<string, ConsoleColor> _shopMsg;
먼저, 상점의 상단에 출력할 메세지를 저장할 튜플을 하나 선언하였다.
여기엔 어떤 물품의 구매를 성공했는지, 혹은 소지 금액이 모자라서 실패했는지 등을 알려주는 문자열이 저장된다.
item2가 출력할 색상이다.
아래는 상점 코드이다.
private void SelectShopItem()
{
DevFunctions.WriteLineColored("구매하고 싶은 물건의 번호를 입력하세요.", ConsoleColor.Cyan);
Console.WriteLine();
Console.Write("1. 사과 : ");
DevFunctions.WriteColored("30원", ConsoleColor.Red);
DevFunctions.WriteLineColored("[사용시 HP를 50 회복합니다.]", ConsoleColor.Green);
Console.Write("2. 배 : ");
DevFunctions.WriteColored("50원", ConsoleColor.Red);
DevFunctions.WriteLineColored("[사용시 HP를 100 회복합니다.]", ConsoleColor.Green);
Console.Write("3. 필살의 영약 : ");
DevFunctions.WriteColored("200원", ConsoleColor.Red);
DevFunctions.WriteLineColored("[사용시 다음 공격의 크리티컬 확률이 50% 증가합니다.]", ConsoleColor.Green);
Console.WriteLine("4. 구매를 종료합니다.");
string input = Console.ReadLine();
if (DevFunctions.IsNumeric(input) == false)
{
return;
}
if (input.Length > 1)
{
return;
}
int toInt = int.Parse(input);
switch (toInt)
{
case 1:
BuyItem(ItemName.사과);
break;
case 2:
break;
case 3:
break;
case 4:
_updateFunc = null;
_selectFunc = new SelectFunc(SelectMenu);
_shopMsg = null;
break;
}
}
물건을 선택하면 BuyItem이라는 함수를 호출한다.
private void BuyItem(ItemName itemName)
{
if (Item.isCanBuy(_parentCore.CurrentPlayer, itemName) == true)
{
SetShopMsg_Buy(itemName);
Item.BuyItem(_parentCore.CurrentPlayer, itemName);
}
else
{
SetShopMsg_Failed();
}
}
private void SetShopMsg_Buy(ItemName itemName)
{
_shopMsg = new Tuple<string, ConsoleColor>(itemName.ToString() + "를 구매하였습니다", ConsoleColor.Blue);
}
private void SetShopMsg_Failed()
{
_shopMsg = new Tuple<string, ConsoleColor>("소지 금액이 모자랍니다.", ConsoleColor.Red);
}
레벨에 함수는 이렇게 설정되어 있고, 내부 코드를 보면 Item 클래스의 static 함수를 사용하고 있는데 코드는 아래와 같다.
public static bool isCanBuy(Player player, ItemName itemName)
{
switch(itemName)
{
case ItemName.사과:
return (player.Money >= 30);
}
return false;
}
public static void BuyItem(Player player, ItemName itemName)
{
switch (itemName)
{
case ItemName.사과:
player.Inventory.Add(new Apple());
player.Money -= 30;
break;
}
}
물품을 구매할 수 있는지 확인하는 함수와 실제로 구매하는 함수이다.
아래 코드를 통해, 상단에 소지 금액과 함께 메세지가 출력된다. 그 아래엔 위에서 본 선택 메세지가 출력되는 것이다.
private void WriteShopMsg()
{
string Str = "소지 금액 : " + _parentCore.CurrentPlayer.Money.ToString();
DevFunctions.WriteLineColored(Str, ConsoleColor.Yellow);
if (_shopMsg != null)
{
DevFunctions.WriteLineColored(_shopMsg.Item1, _shopMsg.Item2);
}
}
구현된 결과다.
또한, 아이템을 구매한 뒤 현재 소지 품목을 출력하는 기능도 추가하였다.
물품을 구매한 뒤 2번 인벤토리를 확인한다를 선택하면 아래와 같이 소지 품목이 출력된다.
상점 기능을 추가하였고, 전투 기능을 추가하기 위해 몬스터와 플레이어에 공통의 인터페이스를 하나 상속하였다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace C_Study
{
public interface ICreatureStat
{
int AttPower { get; }
int DefPower { get; }
}
}
그냥 공격력, 방어력을 get하는 함수만 있다.
이걸 상속하도록 한 이유는 데미지 계산을 하기 위해서인데, 공격자와 피격자가 몬스터인지 플레이어인지 알 필요 없이 공격력과 방어력만으로 계산하기 위해서이다.
public static int GetFinalAttPower(ICreatureStat attacking, ICreatureStat attacked)
{
int Att = attacking.AttPower;
int Def = attacked.DefPower;
float DefRate = Def / 100.0f;
DefRate = 1.0f - DefRate;
return (int)(Att * DefRate);
}
위의 함수를 호출하면, 공격자가 몬스터인지 플레이어인지 알 필요 없이 결과적인 데미지만 얻어낼 수 있다.
이 외에도 필요한 기능이 있으면 인터페이스에 추가하면 될 것 같다.
생각해보니 아이템을 구현할 때 enum을 한글로 사용해보았다.
public enum ItemName
{
사과,
배,
필살의영약,
}
그냥 되나 궁금해서 해봤는데 되길래 걍 써봤다 ㅋㅋ
은근 편한 부분이 있긴 한데, 다시는 쓸 일 없을듯