Today I Learned

[내일배움캠프] C# 문법 종합반 - 개인 프로젝트 마무리

김국민 2023. 11. 13. 23:25

주말 포함 해서 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
    }//~
}

 

마지막으로 처음으로 개인 프로젝트를 하는 시간을 가지며 스스로 부족한 점에 대해 많이 알게 되고 얼마나 다른 내 배캠 동기들을 의지하고 있었는지 알게 되었던 거 같다. 앞으로도 의지는 하겠지만 나 자신도 누군가 의지할 수 있는 사람이 되어 다른 동기들에게 도움을 주고 싶다고 생각하지 않을 수 없지 않지 않았다.(맞춤법 검사 통과했음)

반응형