
도전 기능의 상점 판매하기, 저장하기 기능을 제외한 모든 기능을 제작 완료하였습니다.
던전 입장 및 클리어 보상 획득. 휴식, 레벨업, 장착 개선 기능을 추가 완료했습니다.
{
"Idx": 1,
"Name": "쉬운 던전",
"Defense": 5,
"Gold": 1000,
"DefenseProbability": 0.4,
"FailHealthDivied": 2,
"MinUseHp": 20,
"MaxUseHp": 35,
"GoldRatio": 2
},
public static void EquipItem(int index)
{
Item item = inventory[index - 1];
//토글
item.TogleEquipState();
// 장착 해제에 따른 효과 반영
if (equipDict.ContainsKey(item._itemType)) // 해당하는 타입이 있다면 장착해제 후 장착
{
var ChangeItem = equipDict[item._itemType];
ChangeItem.TogleEquipState();
ActiveItemEffect(ChangeItem);
equipDict[item._itemType] = item;
}
else
{
equipDict.Add(item._itemType, item);
}
ActiveItemEffect(item);
}
장착 개선은 이전에 그래도 코드를 잘 작성해두어서 그런지 간단하게 적용이 가능했습니다. 장착 Dict 를 별도로 선언하고, Type을 Key로 받아서 이미 해당 Key에 Value가 존재한다면 그 Value를 토글시키고, 새로 들어온 Item 으로 변경해주는 방식으로 구현했습니다.
"Intro": {
"intro_welcome": "스파르타 던전에 오신 여러분 환영합니다\n원하시는 닉네임을 설정해 주세요\n>>",
"choose_job": "원하시는 직업을 설정해 주세요 :\n1. 전사 2. 마법사 3. 도적\n>>"
},
"Town": {
"town_welcome": "스파르타 마을에 오신 여러분 환영합니다\n이곳에서 던전으로 들어가기 전 활동을 할 수 있습니다\n>>",
"town_select": "1. 상태보기\n2. 인벤토리\n3. 상점\n4. 던전입장\n5. 휴식하기\n원하시는 행동을 입력해 주세요\n>>"
},
public class SceneTextData
{
public IntroText Intro { get; set; }
public TownText Town { get; set; }
public StatText Stat { get; set; }
public InventoryText Inventory { get; set; }
public ShopText Shop { get; set; }
public DungeonText Dungeon { get; set; }
public RestoreText Restore { get; set; }
public ETCText ETC { get; set; }
public ErrorText Error { get; set; }
}
public class IntroText
{
public string intro_welcome { get; set; }
public string choose_job { get; set; }
}
public static string FormatText(string template, Dictionary<string, string> dict)
{
foreach (var pair in dict)
{
template = template.Replace("{" + pair.Key + "}", pair.Value);
}
return template;
}
dungeonFormat.Add( new Dictionary<string, string>()
{
{"idx", value.Idx.ToString()},
{"name", value.Name},
{"defense", value.Defense.ToString()}
});
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
namespace TextRpg
{
interface IAddable<T>
{
T Add(T other);
}
class StatFloat : IAddable<StatFloat>
{
public float Value { get; }
public StatFloat()
{
Value = 0f;
}
public StatFloat(float value)
{
Value = value;
}
public StatFloat Add(StatFloat other)
{
return new StatFloat(this.Value + other.Value);
}
}
abstract class Stat<T> where T : IAddable<T>, new()
{
public T _baseValue { get; protected set; }
public T _addValue { get; protected set; }
// 생성자에서 기본값을 설정
public Stat(T value)
{
_baseValue = value;
_addValue = new T();
}
// 최종 값을 구하는 프로퍼티
public T FinalValue => _baseValue.Add(_addValue);
// 기본값과 추가값을 반환하는 메서드
public T GetBaseValue() => _baseValue;
public T GetAddValue() => _addValue;
public T GetFinalValue() => FinalValue;
// 기본값 설정
public void SetBaseValue(T value)
{
_baseValue = value;
}
// 추가값 설정
public void SetAddValue(T value)
{
_addValue = _addValue.Add(value); // Add 연산을 호출
}
}
}
- 문제점 : 제네릭 T 타입에서는 이 타입이 연산이 가능한지 알 수 없기 때문에, + -등을 사용할 수 없었습니다
- 시도해본것 : 우선은 별도의 StatFloat 함수를 만들까 고민했지만 코드 반복이 계속될 것 같아 다른 방법을 찾아보려고 검색을 돌렸습니다
- 해결 방법 : 여러가지 해결 방법이 있었는데, 총 3가지가 있었고, 각각의 대표적인 문제는 아래와 같았습니다.
- INumber : .NET 7 이상에서만 사용 가능
- object 캐스팅 : 박싱 문제 발생
- 별도의 인터페이스 제작 : 별도의 포장이 필요함- 알게된 것 : 만능처럼 보이는 제네릭 타입을 다루는 것도 생각보다 많은 주의가 필요하다는 것을 알게 되었습니다. 또, 이를 해결하기 위한 인터페이스 구현도 마냥 단순하지만은 않아 앞으로도 해당 파트에 대한 더 많은 공부가 필요 할 것이라고 생각합니다.
public static T LoadData<T>(string path)
{
string json = File.ReadAllText(path);
return JsonConvert.DeserializeObject<T>(json);
}