월요일 조 아 (아님)
월요일..월요일....월요일~!
static void SellItem()
{
bool isExit = false;
while (!isExit)
{
Console.Clear();
("인벤토리 - 아이템 판매").PrintWithColor(ConsoleColor.Yellow, true);
Console.WriteLine("아이템을 판매할 수 있습니다.");
Console.WriteLine();
player.DisplayMoney();
Console.WriteLine();
player.DisplayPurchasedItem();
Console.WriteLine();
("0").PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(". 나가기");
int select = GetPlayerSelect(0, store.GetStoreItemCount());
if (select == 0)
{
isExit = true;
}
else
{
string itemName = player.SellItem(select - 1);
store.RecoverItem(itemName);
("판매를 완료했습니다.").PrintWithColor(ConsoleColor.Blue, true);
Thread.Sleep(1000);
}
}
}
public string SellItem(int itemIdx)
{
string itemName = purchasedItemList[itemIdx];
purchasedItemList.RemoveAt(itemIdx);
foreach (Item item in itemList)
{
if (itemName == item.Name)
{
item.IsEquipped = false;
money += (int)(item.Price * 0.85);
itemList.Remove(item);
return itemName;
}
}
return itemName;
}
public void RecoverItem(string itemName)
{
soldState[itemName] = false;
}
interface IDungeon
{
int RecommendedShield { get; }
int DefaultReward { get; }
void FailedDungeon();
void ClearDungeon();
}
internal class EasyDungeon : IDungeon
{
private int recommendedShield = 5;
private int defaultReward = 1000;
public int RecommendedShield
{
get { return recommendedShield; }
}
public int DefaultReward
{
get { return defaultReward; }
}
public void FailedDungeon()
{
("던전 실패").PrintWithColor(ConsoleColor.Magenta, true);
Console.WriteLine("쉬운 던전 클리어에 실패했습니다.");
Console.WriteLine();
}
public void ClearDungeon()
{
("던전 클리어").PrintWithColor(ConsoleColor.Yellow, true);
Console.WriteLine("축하합니다!!");
Console.WriteLine("쉬운 던전을 클리어 하였습니다.");
Console.WriteLine();
}
}
static void DisplayDungeonInfo()
{
Console.Clear();
("던전 입장").PrintWithColor(ConsoleColor.Yellow, true);
Console.WriteLine("이곳에서 들어갈 던전을 선택할 수 있습니다.");
Console.WriteLine();
printDungeonInfo(EASY, EASY_SHIELD);
printDungeonInfo(NORMAL, NORMAL_SHIELD);
printDungeonInfo(HARD, HARD_SHIELD);
("0").PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(". 나가기");
Console.WriteLine();
int select = GetPlayerSelect(0, 3);
if (select == 0) startState = 0;
else
{
startDungeon(select);
}
}
static void startDungeon(int mode)
{
Console.Clear();
Console.WriteLine("던전 진행 중...");
Thread.Sleep(2000);
Console.Clear();
IDungeon dungeon;
if (mode == EASY) dungeon = new EasyDungeon();
else if (mode == NORMAL) dungeon = new NormalDungeon();
else dungeon = new HardDungeon();
int success = new Random().Next(1, 101);
int playerTotalShield = player.Shield + player.GetAdditionalShield();
int playerTotalPower = player.Power + player.GetAdditionalPower();
// 권장 방어력보다 낮을 때
if ((dungeon.RecommendedShield > playerTotalShield) && (success > SUCCESS_PROBABLILITY))
{
dungeon.FailedDungeon();
player.DungeonFailed(0);
}
else
{
// 권장 방어력보다 높을 때 or 낮지만 던전 성공시
int defaultDecreasedHP = new Random().Next(20, 36);
int additionalDecreasedHP = dungeon.RecommendedShield - playerTotalShield;
int decreasedHP = defaultDecreasedHP + additionalDecreasedHP;
if (decreasedHP >= player.HP)
{
dungeon.FailedDungeon();
player.DungeonFailed(1);
}
else
{
int additionalRewardPercent = new Random().Next(playerTotalPower, (playerTotalPower * 2) + 1);
int additionalReward = (int)((dungeon.DefaultReward * additionalRewardPercent) / 100);
int reward = dungeon.DefaultReward + additionalReward;
dungeon.ClearDungeon();
player.ClearDungeon(decreasedHP, reward);
}
}
("0").PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(". 나가기");
Console.WriteLine();
int select = GetPlayerSelect(0, 0);
if (select == 0)
{
startState = 0;
return;
}
}
public void DungeonFailed(int type)
{
Console.WriteLine("[ 탐험 결과 ]");
Console.Write("체력 ");
(hp.ToString()).PrintWithColor(ConsoleColor.Magenta, false);
(" -> ").PrintWithColor(ConsoleColor.Yellow, false);
if (type == 0) hp = (int)(hp / 2);
else hp = 0;
(hp.ToString()).PrintWithColor(ConsoleColor.Magenta, true);
Console.WriteLine();
}
public void ClearDungeon(int decreasedHP, int reward)
{
Console.WriteLine("[ 탐험 결과 ]");
Console.Write("체력 ");
(hp.ToString()).PrintWithColor(ConsoleColor.Magenta, false);
(" -> ").PrintWithColor(ConsoleColor.Yellow, false);
hp -= decreasedHP;
(hp.ToString()).PrintWithColor(ConsoleColor.Magenta, true);
Console.Write("Gold ");
(money.ToString()).PrintWithColor(ConsoleColor.Magenta, false);
(" -> ").PrintWithColor(ConsoleColor.Yellow, false);
money += reward;
(money.ToString()).PrintWithColor(ConsoleColor.Magenta, true);
clearDungeonCount++;
bool isLevelUp = (clearDungeonCount == level);
if (isLevelUp)
{
Console.Write("Level ");
("Lv" + level).PrintWithColor(ConsoleColor.Magenta, false);
(" -> ").PrintWithColor(ConsoleColor.Yellow, false);
if (level < 5)
{
level++;
power += 1;
shield += 2;
clearDungeonCount = 0;
}
("Lv" + level).PrintWithColor(ConsoleColor.Magenta, true);
}
Console.WriteLine();
}
static void TakeRest()
{
bool isExit = false;
while (!isExit)
{
Console.Clear();
("휴식하기").PrintWithColor(ConsoleColor.Yellow, true);
("500").PrintWithColor(ConsoleColor.Magenta, false); Console.Write(" G를 내면 체력을 회복할 수 있습니다. (보유 골드 : ");
(player.Money.ToString()).PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(" G)");
Console.WriteLine();
("1").PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(". 휴식하기");
("0").PrintWithColor(ConsoleColor.Magenta, false); Console.WriteLine(". 나가기");
Console.WriteLine();
int select = GetPlayerSelect(0, 1);
if (select == 0)
{
isExit = true;
startState = 0;
}
else
{
if (player.Money < 500)
{
("Gold 가 부족합니다.").PrintWithColor(ConsoleColor.Red, true);
Thread.Sleep(1000);
} else
{
("휴식을 완료했습니다.").PrintWithColor(ConsoleColor.Blue, true);
player.GetRest();
isExit = true;
startState = 0;
Thread.Sleep(1000);
}
}
}
}
public void GetRest()
{
hp = 100;
money -= 500;
}
clearDungeonCount++;
bool isLevelUp = (clearDungeonCount == level);
if (isLevelUp)
{
Console.Write("Level ");
("Lv" + level).PrintWithColor(ConsoleColor.Magenta, false);
(" -> ").PrintWithColor(ConsoleColor.Yellow, false);
if (level < 5)
{
level++;
power += 1;
shield += 2;
clearDungeonCount = 0;
}
("Lv" + level).PrintWithColor(ConsoleColor.Magenta, true);
}
어려웠던 점
해결
IGameDatabaseRepository
internal interface IGameDatabaseRepository
{
// Player 정보 불러오기(string name, int hp, int shield, int power, int money) 및 업데이트
// 전체 상점 Item List 불러오기 및 업데이트
// 상점의 아이템 판매 현황 불러오기 및 업데이트
public Player? GetPlayerInfo();
public List<Item> GetStoreItemList();
public Dictionary<string, bool>? GetStoreItemSoldStateList();
public void UpdatePlayerInfo(Player player);
public void UpdateStoreItemSoldState(Dictionary<string, bool> soldState);
}
internal class DefaultGameDatabaseRepository : IGameDatabaseRepository
{
const string DATA_PATH = "D:\\coding\\Game Study\\C_Study_Sparta_2023\\";
const string PLAYER_DB_PATH = "UserDatabase.txt";
const string ITEM_DB_PATH = "ItemDatabase.txt";
const string ITEM_SOLD_STATE_DB_PATH = "ItemSoldStateDatabase.txt";
public Player? GetPlayerInfo()
{
try
{
string jdata = File.ReadAllText(DATA_PATH + PLAYER_DB_PATH);
return JsonConvert.DeserializeObject<Player>(jdata);
} catch
{
return null;
}
}
public List<Item> GetStoreItemList()
{
List<string[]> itemDB = new List<string[]>();
List<Item> storeItemList = new List<Item>();
try
{
StreamReader sr = new StreamReader(DATA_PATH + ITEM_DB_PATH);
string line = sr.ReadLine();
while (line != null)
{
itemDB.Add(line.Split("\t"));
line = sr.ReadLine();
}
sr.Close();
for (int i = 0; i < itemDB.Count; i++)
{
storeItemList.Add(ParseItemStr(itemDB[i]));
}
}
catch (Exception e)
{
Console.WriteLine("오류가 발생했습니다 : " + e.Message);
Environment.Exit(0);
}
return storeItemList;
}
public Dictionary<string, bool>? GetStoreItemSoldStateList()
{
try
{
string jdata = File.ReadAllText(DATA_PATH + ITEM_SOLD_STATE_DB_PATH);
return JsonConvert.DeserializeObject<Dictionary<string, bool>>(jdata);
}
catch
{
return null;
}
}
public void UpdatePlayerInfo(Player player)
{
string jdata = JsonConvert.SerializeObject(player);
File.WriteAllText(DATA_PATH + PLAYER_DB_PATH, jdata);
}
public void UpdateStoreItemSoldState(Dictionary<string, bool> soldState)
{
string jdata = JsonConvert.SerializeObject(soldState);
File.WriteAllText(DATA_PATH + ITEM_SOLD_STATE_DB_PATH, jdata);
}
// string 배열을 읽어와서 Item 객체로 파싱하여 반환함
private static Item ParseItemStr(string[] itemStr)
{
int idx = 0;
return new Item(
itemStr[idx++],
int.Parse(itemStr[idx++]),
int.Parse(itemStr[idx++]),
int.Parse(itemStr[idx++]),
itemStr[idx++]
);
}
}
private void InitStore(Dictionary<string, bool> soldStateList)
{
if (soldStateList == null)
{
int length = itemList.Count;
Console.WriteLine("length = " + length);
soldState = new Dictionary<string, bool>();
for (int i = 0; i < length; i++) soldState.Add(itemList[i].Name, false);
} else
{
soldState = soldStateList;
if (itemList.Count != soldState.Count)
{
foreach (Item item in itemList)
{
if (soldState[item.Name] == null)
{
soldState.Add(item.Name, false);
}
}
}
}
}
이렇게 추가 기능 구현은 끝!!! 인데 하나 더 수정사항이 있다면
Player 클래스의 purchasedItemList를 List 형식으로 변경했다.
구매한 아이템이 뭔지만 구분하면 되니까 아이템의 name 값만 저장하면 될 것 같았기 때문
~끗~