[내일배움캠프] C# 문법 종합반 - 개인 프로젝트 마무리
주말 포함 해서 4일 동안 만든 프로젝트를 제출 완료했다.
이번에 만든 프로젝트이름은 TextGame이고, 텍스트 기반 콘솔 게임이다.
프로젝트 시 일어난 문제와 해결
1) 문제 :
장착 및 해제 구현
*구현하기로 한 내용 : 장착 관리 창을 만들고, 원하는 무기의 번호를 입력하면 장착 및 해제가 가능하게 만든다.
*문제가 발생한 상황 : 게임시작 시 아무것도 장착하지 않은 상태에서 아이템 장착을 연달아했을 때,
이전 아이템이 로그에 남아있어 장착이 되어 있는 아이템도 장착해제가 안됨.
*문제 해결을 위해 노력한 것 : 다른 동기 님께 조언을 구하고, 스스로 문제 해결을 위해 많은 고민을 했음.
결과 :
장착 및 해제에 사용된 선택한 아이템과 착용 중인 아이템을 비교하던 구문에 허점을 발견해 냈음.
해결방안 : 장착 및 해제에 쓰인 if문의 조건을 더 세밀하게 조정해서 문제를 해결함.
2) 문제 :
상점 아이템 구매
*구현하기로 한 내용 : 상점에 들어가서 원하는 아이템의 번호를 입력할 시 아이템을 구매할 수 있게 만든다.
문제가 발생한 상황 : 아이템을 구매해서 인벤토리에 넣는 거 까지는 구현이 됐는데, 한번 구매한 아이템이 중복으로
구매되고 그 아이템은 인벤토리에 몇 개가 들어 있던지, 한 번에 장착 및 해제가 된다. 그리고 실제 스텟 적용은 한 개만
이루어진다.
*문제 해결을 위해 노력한 것 : 관련된 코드를 다시 한번 보면서 추가해야 될 부분이 있는지 공부를 하였다.
결과 :
인벤토리에 아이템을 넣어줄 뿐 더 이상 다른 기능이 없다는 걸 알게 됐다.
해결방안 : 아이템을 구매할 때 아이템을 상점에서 사라지게 만들고 판매 기능까지 추가로 구현하게 됨.
작성 코드
using System.Xml.Linq;
using System.Threading;
using static TextGame.Program;
using System.Collections.Generic;
using System.Diagnostics;
namespace TextGame
{
internal class Program
{
private static Character player;
public static List <Item> shopItem;
public static List <Item> Inventory;
public static bool Isequip; //= false;
static void Main(string [] args)
{
Console.Clear();
GameItemSetting();
Intro();
GameStartScene();
DisplayGameIntro();
}//Main
static void Intro()
{
for (int i = 0; i < 10; i++)
{
Console.SetCursorPosition(10 - i, 0);
Console.WriteLine(":::::::::'##:::::'##:'########:'##::::::::'######:::'#######::'##::::'##:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 1);
Console.WriteLine("::::::::: ##:'##: ##: ##.....:: ##:::::::'##... ##:'##.... ##: ###::'###:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 2);
Console.WriteLine("::::::::: ##: ##: ##: ##::::::: ##::::::: ##:::..:: ##:::: ##: ####'####:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 3);
Console.WriteLine("::::::::: ##: ##: ##: ######::: ##::::::: ##::::::: ##:::: ##: ## ### ##:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 4);
Console.WriteLine("::::::::: ##: ##: ##: ##...:::: ##::::::: ##::::::: ##:::: ##: ##. #: ##:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 5);
Console.WriteLine("::::::::: ##: ##: ##: ##::::::: ##::::::: ##::: ##: ##:::: ##: ##:.:: ##:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 6);
Console.WriteLine(":::::::::. ###. ###:: ########: ########:. ######::. #######:: ##:::: ##:::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 7);
Console.WriteLine("::::::::::...::...:::........::........:::......::::.......:::..:::::..::::::::::::: ");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 8);
Console.WriteLine("'########:'########:'##::::'##:'########::'######::::::'###::::'##::::'##:'########:");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 9);
Console.WriteLine("... ##..:: ##.....::. ##::'##::... ##..::'##... ##::::'## ##::: ###::'###: ##.....::");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 10);
Console.WriteLine("::: ##:::: ##::::::::. ##'##:::::: ##:::: ##:::..::::'##:. ##:: ####'####: ##:::::::");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 11);
Console.WriteLine("::: ##:::: ######:::::. ###::::::: ##:::: ##::'####:'##:::. ##: ## ### ##: ######:::");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 12);
Console.WriteLine("::: ##:::: ##...:::::: ## ##:::::: ##:::: ##::: ##:: #########: ##. #: ##: ##...::::");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 13);
Console.WriteLine("::: ##:::: ##:::::::: ##:. ##::::: ##:::: ##::: ##:: ##.... ##: ##:.:: ##: ##:::::::");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 14);
Console.WriteLine("::: ##:::: ########: ##:::. ##:::: ##::::. ######::: ##:::: ##: ##:::: ##: ########:");
Thread.Sleep(10);
Console.SetCursorPosition(10 - i, 15);
Console.WriteLine(":::..:::::........::..:::::..:::::..::::::......::::..:::::..::..:::::..::........::\r\n");
Thread.Sleep(100);
Console.Clear();
}
Console.SetCursorPosition(20, 0);
Console.WriteLine("\r:::::::::'##:::::'##:'########:'##::::::::'######:::'#######::'##::::'##:::::::::::: " +
"\r\n::::::::: ##:'##: ##: ##.....:: ##:::::::'##... ##:'##.... ##: ###::'###:::::::::::: " +
"\r\n::::::::: ##: ##: ##: ##::::::: ##::::::: ##:::..:: ##:::: ##: ####'####:::::::::::: " +
"\r\n::::::::: ##: ##: ##: ######::: ##::::::: ##::::::: ##:::: ##: ## ### ##:::::::::::: " +
"\r\n::::::::: ##: ##: ##: ##...:::: ##::::::: ##::::::: ##:::: ##: ##. #: ##:::::::::::: " +
"\r\n::::::::: ##: ##: ##: ##::::::: ##::::::: ##::: ##: ##:::: ##: ##:.:: ##:::::::::::: " +
"\r\n:::::::::. ###. ###:: ########: ########:. ######::. #######:: ##:::: ##:::::::::::: " +
"\r\n::::::::::...::...:::........::........:::......::::.......:::..:::::..::::::::::::: " +
"\r\n'########:'########:'##::::'##:'########::'######::::::'###::::'##::::'##:'########:" +
"\r\n... ##..:: ##.....::. ##::'##::... ##..::'##... ##::::'## ##::: ###::'###: ##.....::" +
"\r\n::: ##:::: ##::::::::. ##'##:::::: ##:::: ##:::..::::'##:. ##:: ####'####: ##:::::::" +
"\r\n::: ##:::: ######:::::. ###::::::: ##:::: ##::'####:'##:::. ##: ## ### ##: ######:::" +
"\r\n::: ##:::: ##...:::::: ## ##:::::: ##:::: ##::: ##:: #########: ##. #: ##: ##...::::" +
"\r\n::: ##:::: ##:::::::: ##:. ##::::: ##:::: ##::: ##:: ##.... ##: ##:.:: ##: ##:::::::" +
"\r\n::: ##:::: ########: ##:::. ##:::: ##::::. ######::: ##:::: ##: ##:::: ##: ########:" +
"\r\n:::..:::::........::..:::::..:::::..::::::......::::..:::::..::..:::::..::........::\r\n");
Thread.Sleep(1000);
Console.WriteLine("숫자 '0'을 눌러 시작하세요");
int input = CheckValidInput(0, 0);
switch (input)
{
case 0:
Console.Clear();
break;
}
}
static void GameItemSetting()
{
// 상점 아이템 정보 세팅
Item shopItem01 = new Item(" 나무 검 ", 4, 0, 50, false);
Item shopItem02 = new Item(" 무쇠 창 ", 6, 0, 100, false);
Item shopItem03 = new Item(" 황금 검 ", 8, 0, 150, false);
Item shopItem04 = new Item(" 다이아 검 ", 10, 0, 200, false);
Item shopItem05 = new Item(" 티타늄 검 ", 100, 0, 50000, false);
Item shopItem06 = new Item(" 비브라늄 검", 150, 0, 70000, false);
Item shopItem07 = new Item(" 판자 갑옷 ", 0, 4, 50, false);
Item shopItem08 = new Item(" 무쇠 갑옷 ", 0, 6, 100, false);
Item shopItem09 = new Item(" 황금 갑옷 ", 0, 8, 150, false);
Item shopItem10 = new Item("다이아 갑옷 ", 0, 10, 200, false);
Item shopItem11 = new Item("티타늄 갑옷 ", 0, 100, 50000, false);
Item shopItem12 = new Item("비브라늄 갑옷", 0, 150, 70000, false);
Item shopItem13 = new Item("다이아 반지", 100, 100, 100000, false);
shopItem = new List <Item>();
shopItem.Add(shopItem01);
shopItem.Add(shopItem02);
shopItem.Add(shopItem03);
shopItem.Add(shopItem04);
shopItem.Add(shopItem05);
shopItem.Add(shopItem06);
shopItem.Add(shopItem07);
shopItem.Add(shopItem08);
shopItem.Add(shopItem09);
shopItem.Add(shopItem10);
shopItem.Add(shopItem11);
shopItem.Add(shopItem12);
shopItem.Add(shopItem13);
}
static void GameStartScene()
{
// 캐릭터 이름 세팅
Console.WriteLine("스파르타 마을에 오신 여러분 환영합니다.");
Console.WriteLine("이름을 입력하세요.");
Console.WriteLine();
string playerName = Console.ReadLine();
Console.WriteLine("\n");
Console.WriteLine($"이름 :{playerName}");
Console.Clear();
// 캐릭터 직업 세팅
Console.WriteLine("원하는 직업을 선택하세요.");
Console.WriteLine();
Console.WriteLine("1. 전사 : 공격과 방어에 밸런스가 좋고 초기 체력이 높습니다.\n");
Console.WriteLine("2. 궁수 : 공격력이 강한 대신 방어력과 체력이 낮습니다.\n");
Console.WriteLine("3. 도적 : 초기스텟이 낮은 대신 추가 소지금이 있습니다.\n");
int input = CheckValidInput(1, 3);
switch (input)
{
case 1:
player = new Character($"{playerName}", "전사", 1, 10, 10, 150, 1500);
break;
case 2:
player = new Character($"{playerName}", "궁수", 1, 15, 5, 80, 1500);
break;
case 3:
player = new Character($"{playerName}", "도적", 1, 7, 7, 77, 7777);
break;
default:
Console.WriteLine("잘못된 선택입니다.");
break;
}
}//GameStartScene()
static void DisplayGameIntro()
{
Console.Clear();
Console.WriteLine("스파르타 마을에 오신 여러분 환영합니다.");
Console.WriteLine("이곳에서 전전으로 들어가기 전 활동을 할 수 있습니다.");
Console.WriteLine();
Console.WriteLine("1. 상태보기");
Console.WriteLine("2. 인벤토리");
Console.WriteLine("3. 상점\n");
Console.WriteLine("원하시는 행동을 입력해 주세요.");
int input = CheckValidInput(1, 3);
switch (input)
{
case 1:
DisplayMyInfo();
break;
case 2:
DisplayInventory();
break;
case 3:
DisplayShop(player, shopItem);
break;
}
}//DisplayGameIntro()
static void DisplayMyInfo()
{
Console.Clear();
Console.WriteLine("상태보기");
Console.WriteLine("캐릭터의 정보를 표시합니다.");
Console.WriteLine();
Console.WriteLine($"Lv. {player.Level}");
Console.WriteLine($"{player.Name}({player.Job})");
Console.WriteLine($"공격력 :{player.Atk}"); // (+ {player.equippedItem.Atk})");
Console.WriteLine($"방어력 : {player.Def}"); // (+ {player.equippedItem.Atk})");
Console.WriteLine($"체력 : {player.Hp}");
Console.WriteLine($"Gold : {player.Gold} G");
Console.WriteLine();
Console.WriteLine("0. 나가기");
int input = CheckValidInput(0, 0);
switch (input)
{
case 0:
DisplayGameIntro();
break;
}
}//DisplayMyInfo()
static void DisplayInventory() //인벤토리
{
Console.Clear();
Console.WriteLine("인벤토리");
Console.WriteLine("보유 중인 아이템을 관리할 수 있습니다.");
Console.WriteLine();
Console.WriteLine("[아이템 목록]");
for (int i = 0; i < player.Inventory.Count; i++)
{
Console.WriteLine($"{player.Inventory [i]}");
}
Console.WriteLine();
Console.WriteLine("1. 장착관리");
Console.WriteLine("0. 나가기");
Console.WriteLine();
Console.WriteLine("원하시는 행동을 입력해 주세요.");
int input = CheckValidInput(0, 1);
switch (input)
{
case 0:
DisplayGameIntro();
break;
case 1:
DisplayEquipment();
break;
default:
Console.WriteLine("잘못된 번호를 입력하셨습니다!");
break;
}
}//DisplayInventory()
static void DisplayEquipment() //장착관리
{
Isequip = false;
Console.Clear();
Console.WriteLine("인벤토리");
Console.WriteLine("보유 중인 아이템을 관리할 수 있습니다.");
Console.WriteLine();
Console.WriteLine("[아이템 목록]");
for (int i = 0; i < player.Inventory.Count; i++)
{
Console.WriteLine($"{i + 1} : {player.Inventory [i]}");
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("0. 나가기");
Console.WriteLine();
Console.WriteLine("장착을 원하는 번호를 입력해 주세요.");
if (int.TryParse(Console.ReadLine(), out int choice) && choice >= 1 && choice <= player.Inventory.Count)
{
Item selectedItem = player.Inventory [choice - 1];
player.equippedItem = selectedItem;
if (selectedItem.Isequip == false)
{
selectedItem.Isequip = true;
Console.WriteLine($"{selectedItem.Name}을(를) 장착했습니다.");
player.Atk += selectedItem.Atk;
player.Def += selectedItem.Def;
Thread.Sleep(600);
DisplayEquipment();
}
else
{
player.equippedItem = null;
selectedItem.Isequip = false;
Console.WriteLine($"{selectedItem.Name}을(를) 장착 해제했습니다.");
player.Atk -= selectedItem.Atk;
player.Def -= selectedItem.Def;
Thread.Sleep(600);
DisplayEquipment();
}
}
else if (choice == 0)
{
Console.WriteLine("나가기");
DisplayInventory();
}
else
{
Console.WriteLine("잘못된 입력입니다");
Thread.Sleep(500);
DisplayEquipment();
}
}//DisplayEquipment()
static void DisplayShop(Character player, List <Item> shopItem) //상점
{
Console.Clear();
Console.WriteLine("상점");
Console.WriteLine($"구매할 물품을 선택하세요. {player.Gold} G");
Console.WriteLine("\n");
Console.WriteLine("[아이템 목록]");
for (int i = 0; i < shopItem.Count; i++)
{
Console.WriteLine($"{i + 1} : {shopItem [i]}");
}
Console.WriteLine();
Console.WriteLine("구입할 아이템을 선택하세요");
Console.WriteLine("20000. 판매");
Console.WriteLine("0. 나가기");
int.TryParse(Console.ReadLine(), out int choice);
if (choice >= 0 && choice <= shopItem.Count)
{
if (choice == 0)
{
DisplayGameIntro();
}
Item selectedShopItem = shopItem [choice - 1];
if (player.Gold >= selectedShopItem.Price)
{
// 플레이어의 소지금에서 아이템 가격을 차감
player.Gold -= selectedShopItem.Price;
// 아이템을 플레이어의 인벤토리에 추가
player.Inventory.Add(selectedShopItem);
shopItem.Remove(selectedShopItem);
Console.WriteLine($"{selectedShopItem.Name}을(를) 구입했습니다. 남은 골드: {player.Gold}");
Thread.Sleep(600);
DisplayShop(player, shopItem);
}
else
{
Console.WriteLine("골드가 부족하여 아이템을 구입할 수 없습니다.");
Thread.Sleep(600);
DisplayShop(player, shopItem);
}
}
else if (choice == 20000)
{
DisplaySellShop(player, Inventory);
}
else
{
Console.WriteLine("잘못된 선택입니다.");
Thread.Sleep(500);
DisplayShop(player, shopItem);
}
}//DisplayShop()
static void DisplaySellShop(Character player, List <Item> Inventory) //상점 - 판매
{
Console.Clear();
Console.WriteLine("상점");
Console.WriteLine($"판매할 물품을 선택하세요. {player.Gold} G");
Console.WriteLine("\n");
Console.WriteLine("[아이템 목록]");
for (int i = 0; i < player.Inventory.Count; i++)
{
Console.WriteLine($"{i + 1} : {player.Inventory [i]}");
}
Console.WriteLine();
Console.WriteLine("판매할 아이템을 선택하세요");
Console.WriteLine("0. 나가기");
if (int.TryParse(Console.ReadLine(), out int choice) && choice >= 0 && choice <= player.Inventory.Count)
{
if (choice == 0)
{
DisplayShop(player, shopItem);
}
Item selectedSellShopItem = player.Inventory [choice - 1];
if (selectedSellShopItem.Price >= 0)
{
// 플레이어의 소지금에서 아이템 가격을 더함
player.Gold += selectedSellShopItem.Price;
player.equippedItem = null;
selectedSellShopItem.Isequip = false;
player.Atk -= selectedSellShopItem.Atk;
player.Def -= selectedSellShopItem.Def;
// 아이템을 플레이어의 인벤토리에 삭제
shopItem.Add(selectedSellShopItem);
player.Inventory.Remove(selectedSellShopItem);
Console.WriteLine($"{selectedSellShopItem.Name}을(를) 판매했습니다. 남은 골드: {player.Gold}");
Thread.Sleep(600);
DisplaySellShop(player, Inventory);
}
}
else
{
Console.WriteLine("잘못된 선택입니다.");
Thread.Sleep(500);
DisplayShop(player, Inventory);
}
}//DisplaySellShop()
//input setting
static int CheckValidInput(int min, int max)
{
while (true)
{
string input = Console.ReadLine();
bool parseSuccess = int.TryParse(input, out var ret);
if (parseSuccess)
{
if (ret >= min && ret <= max)
return ret;
}
Console.WriteLine("잘못된 입력입니다.");
Thread.Sleep(500);
}
}//CheckValidInput()
public class Character
{
public string Name { get; }
public string Job { get; }
public int Level { get; set; }
public int Atk { get; set; }
public int Def { get; set; }
public int Hp { get; set; }
public int Gold { get; set; }
public List <Item> Inventory { get; set; }
public Item equippedItem { get; set; }
public Character(string name, string job, int level, int atk, int def, int hp, int gold)
{
Name = name;
Job = job;
Level = level;
Atk = atk;
Def = def;
Hp = hp;
Gold = gold;
Inventory = new List <Item>(); // 인벤토리
Inventory.Add(new Item("나무 몽둥이", 2, 0, 50, false));
Inventory.Add(new Item("냄비 뚜껑 ", 0, 2, 50, false));
equippedItem = null; //장착했는지 안 했는지 알려주는 거
}
}// Character
public class Item
{
public string Name { get; set; }
public int Atk { get; set; }
public int Def { get; set; }
public int Price { get; set; }
public bool Isequip { get; set; } // [E] 표시
public Item(string name, int atk, int def, int price, bool equip)
{
Name = name;
Atk = atk;
Def = def;
Price = price;
Isequip = equip;
}
public override string ToString()
{
if (Isequip == true && Price >= 100)
{
return ($" [E] {Name}\t | 공격력 +{Atk}\t | 방어력 +{Def}\t | {Price}\t G ");
}
else if (Isequip == true)
{
return ($" [E] {Name}\t | 공격력 +{Atk}\t | 방어력 +{Def}\t | {Price}\t\t G ");
}
else if (Isequip == false && Price >= 100)
{
return ($" {Name}\t | 공격력 +{Atk}\t | 방어력 +{Def}\t | {Price}\t G ");
}
else
return ($" {Name}\t | 공격력 +{Atk}\t | 방어력 +{Def}\t | {Price}\t\t G ");
}
}//class Item
}//~
}
마지막으로 처음으로 개인 프로젝트를 하는 시간을 가지며 스스로 부족한 점에 대해 많이 알게 되고 얼마나 다른 내 배캠 동기들을 의지하고 있었는지 알게 되었던 거 같다. 앞으로도 의지는 하겠지만 나 자신도 누군가 의지할 수 있는 사람이 되어 다른 동기들에게 도움을 주고 싶다고 생각하지 않을 수 없지 않지 않았다.(맞춤법 검사 통과했음)