240105-TIL

2024. 1. 5. 20:52내일배움캠프

1월 5일 어제 너무 늦게까지 배운 내용을 정리하고 제출할 과제를 만지작 거리다보니

 

오늘 너무 피곤하다. 아침에 눈을 뜨기가 너무 힘들었지만 어떻게든 일어나서 컴퓨터 앞에 앉았다.

 

오늘은 어제 말한대로 C#을 이용해 콘솔창으로 작은 게임을 만들어보자.

 

 

요구사항

더보기
  • 1. 게임 시작 화면
    • 게임 시작시 간단한 소개 말과 마을에서 할 수 있는 행동을 알려줍니다.
    • 원하는 행동의 숫자를 타이핑하면 실행합니다.
    • 1 ~ 3 이외 입력시 - 잘못된 입력입니다 출력
  •  2. 상태보기
    • 캐릭터의 정보를 표시합니다.
    • 7개의 속성을 가지고 있습니다. 레벨 / 이름 / 직업 / 공격력 / 방어력 / 체력 / Gold
    • 처음 기본값은 이름을 제외하고는 아래와 동일하게 만들어주세요
    • 이후 장착한 아이템에 따라 수치가 변경 될 수 있습니다.
  • 3.  인벤토리
    • 보유 중인 아이템을 전부 보여줍니다. 이때 장착중인 아이템 앞에는 [E] 표시를 붙여 줍니다.
    • 처음 시작시에는 아이템이 없습니다. 
      •  장착 관리
        • 장착관리가 시작되면 아이템 목록 앞에 숫자가 표시됩니다.
        • 일치하는 아이템을 선택했다면 (예제에서 1~3선택시)
          • 장착중이지 않다면 → 장착 [E] 표시 추가
          • 이미 장착중이라면 → 장착 해제 [E] 표시 없애기
        • 일치하는 아이템을 선택했지 않았다면 (예제에서 1~3이외 선택시)
          • 잘못된 입력입니다 출력
          • 창과 검을 동시에 장착가능
          • 갑옷도 동시에 착용가능 
          • 장착 갯수 제한 X아이템의 중복 장착을 허용합니다. 
  • 4.상점
    • 보유중인 골드와 아이템의 정보,가격이 표시됩니다.
    • 아이템 정보 오른쪽에는 가격이 표시가 됩니다.
    • 이미 구매를 완료한 아이템이라면 구매완료 로 표시됩니다.
  • 4 - 1. 아이템 구매
    • 아이템 구매 를 선택하면 아이템 목록 앞에 숫자가 표시됩니다.
    • 일치하는 아이템을 선택했다면 (예제에서 1~6선택시)
      • 이미 구매한 아이템이라면 → 이미 구매한 아이템입니다 출력
      • 구매가 가능하다면
        • 보유 금액이 충분하다면 → 구매를 완료했습니다. 출력 재화 감소 / 인벤토리에 아이템 추가 / 상점에 구매완료 표시
        • 보유 금액이 부족하다면 → Gold 가 부족합니다. 출력
    • 일치하는 아이템을 선택했지 않았다면 (예제에서 1~3이외 선택시)
      • 잘못된 입력입니다 출력
  •  

 

과제풀이

더보기

처음부터 하나씩 하나씩 해결해봤다.

 

일단 처음 게임 시작 화면을 만들어봤다.

 

  Console.WriteLine("스파르타 마을에 오신것을 환영합니다");
            Console.WriteLine("이곳에서 던전으로 들어가기전 활동을 할 수 있습니다.");

            Console.WriteLine("1. 상태 보기");
            Console.WriteLine("2. 인벤토리");
            Console.WriteLine("3. 상점");
            Console.WriteLine("0. 종료");

            Console.WriteLine("원하시는 행동을 입력해주세요.");
            Console.Write(">>");
            string input = Console.ReadLine();
            
             switch (input)
            {
                case "1":
                    // 플레이어 정보
                   
                    break;
                case "2":
                    // 인벤토리
                    
                    break;
                case "3":
                    // 상점
                  
                    break;
                case "0":
                    run = false;
                    break;
                default:
                    Console.Clear();
                    Console.WriteLine(" ");
                    Console.WriteLine("잘못된 입력입니다. ");
                    Console.WriteLine(" ");
                    break;
            }​

 

이런식으로 StartScene이라는 메서드를 하나 만들어서 동작하게 만들었다.

 

input값을 입력받아 원하는 동작을 하게 만들었다.

 

그 다음엔 상태 보기를 만들어야 했다.

 

internal class Player
    {
        public int level;
        public string name;
        public string classType;
        public int atk;
        public int def;
        public int hp;
        public int gold;
        
        public void CreatePlayer(int _level,string _name,  string _classType, int _atk, int _def, int _hp, int _gold) // 플레이어 생성자.
        {
            level = _level;
            name = _name;
            classType = _classType;
            atk = _atk;
            def = _def;
            hp = _hp;
            gold = _gold;
        }
   }

 

처음엔 그냥 주욱 작성하다가 이건 그냥 따로 Player라는 클래스를 만들어서 그 Player 클래스에서 

 

Player에 관한 정보들이나 Player가 실행해야하는 메서드를 정리해 두는게 맞는거 같아서

 

Player 클래스를 하나 만들었다. 이곳에는 플레이어가 가지고 있는 레벨 이름같은 정보나

 

인벤토리, 그리고 장착관리를 만들 생각이었다.

 

일단 플레이어의 정보를 보여주는 메서드를 하나 만들었다.

 

 public void Info() // 플레이어 정보
        {
            string input = "1";

            while(input != "0")
            {
                Console.WriteLine($"{name}  ({classType})");
                if(addAtk == 0)
                {
                    Console.WriteLine($"공격력 : {atk}");
                }
                else
                {
                    addAtkTxt = "(+" + addAtk + ")";
                    Console.WriteLine($"공격력 : {atk} " + addAtkTxt);
                }
                
                if(addDef == 0)
                {
                    Console.WriteLine($"방어력 : {def}");
                }
                else
                {
                    addDefTxt = "(+" + addDef + ")"; 
                    Console.WriteLine($"방어력 : {def} " + addDefTxt);
                }
                
                Console.WriteLine($"체력 : {hp}");
                Console.WriteLine($"Gold : {gold} G");

                Console.WriteLine();
                Console.WriteLine("0.나가기");
                Console.WriteLine();

                Console.WriteLine("원하시는 행동을 입력해주세요.");
                Console.Write(">>");
                input = Console.ReadLine();

                if(input !=  "0")
                {
                    Console.Clear();
                    Console.WriteLine("다시 입력해주세요");
                }

            }
            Console.Clear();
        }

 

플레이어의 정보를 보여주는 메서드를 만들었으니 이제는 인벤토리를 만들어야하는데

 

처음에 감을 못잡아서 정말 많이 해매다가

 

public List<Item> inven = new List<Item>();

 

그냥 아이템 정보를 담을 리스트를 하나 만들기로 결정했다. 이곳에는 플레이어가 구매한 장비가 들어가게 할 생각이었다.

 

 

public void AddInven(Item item)
        {
            inven.Add(item);
        } // 인벤에 아이템 추가.

 

보관함에 아이템을 추가하는 메서드도 하나 만들어주고

 

플레이어 아이템이 들어갈 보관함도 만들었으니 이제 그 보관함을 보여주는 기능을 만들어야했다.

 

public void Inven()
        {
            string input;

            Console.WriteLine("[아이템 목록]");
            if(inven.Count > 0)
            {
                for (int i = 0; i < inven.Count; i++)
                {
                    Console.WriteLine($"{inven[i].equipMsg}{i + 1}. {inven[i].itemName}    | {inven[i].optionText}+{inven[i].option}    | {inven[i].itemInfo}");
                }
            }
            
            Console.WriteLine();
            Console.WriteLine("1. 장착관리");
            Console.WriteLine("2. 나가기");

            Console.WriteLine("원하시는 행동을 입력해주세요.");
            Console.Write(">>");
            input = Console.ReadLine();

            switch (input)
            {
                case "1":
                    //장착관리
                    Console.Clear();
                    EquipManager();
                    break;
                case "2":
                    Console.Clear();
                    break;
                default:
                    Console.Clear();
                    Inven();
                    break;
            }

        }

 

StartScene메서드 부분을 참고해서 비슷한 방식으로 만들었다 이 곳에서도 input값을 받아서 원하는 동작을 하게 만들었다.

 

그 다음엔 상점을 만들어야 했는데 상점을 만들기전에 Player와 마찬가지로 Item들도 다 각 Item들의 정보들이 있을텐데 이것도 그럼 Player처럼 따로 뺴서 관리를 해주는게 맞는것 같았다.

 

그래서 Item을 또 클래스로 빼서 하나 만들어줬다.

enum ItemType
    {
        Weapon,
        Armor
    }
    internal class Item
    {
        public string equipMsg ;// 장착시 표시할 문자 [E]
        public string itemName; // 아이템 이름
        public int option; // 옵션
        public string optionText; // 공격력,방어력 표시
        public ItemType itemType; // 타입
        public string itemInfo; // 아이템 설명
        public int buyGold; // 살때 필요한 골드
        public int sellGold;

        public bool isBuy; // 이미 구매했는지?
        public bool isEquip; // 장착했는지?

        public Item(string _itemName, int _option, ItemType _itemType, string _itemInfo, int _buyGold) //아이템 클래스 생성자
        {
            itemName = _itemName;
            option = _option;
            itemType = _itemType;
            if(_itemType == ItemType.Weapon )
            {
                optionText = "공격력";
            }
            else
            {
                optionText = "방어력";
            }
            itemInfo = _itemInfo;
            buyGold = _buyGold;
            sellGold = (int)(_buyGold * 0.85);

        }

    }

 

player와 마찬가지로 그냥 정보를 담아둘 클래스를 따로 파서 만들었는데

 

다른점이라고 한다면 itemType을 enum으로 만들었다.

 

추후에 내가 계속 더 공부를 해서 만지작 거리다보면 itemType도 더 늘어날것 같고

 

차라리 처음 만들때부터 따로 빼서 저렇게 관리를 한다면 추가나 삭제도 빠를것 같았다.

 

이제 본격적으로 상점을 만들어야했는데 여기서 진짜진짜진짜 힘들었다.

 

internal class Shop
    {
        

        List<Item> items = new List<Item>();


        


        public void AddShopItem(Item item)
        {
            items.Add(item);
        }

        public void Shopinfo(Player player)
        {
            Console.WriteLine("[보유 골드]");
            Console.WriteLine($"{player.gold}");

            Console.WriteLine("[아이템 목록]");
            for(int i = 0 ; i < items.Count; i++)
            {
                if (items[i].isBuy == true)
                {
                    Console.WriteLine($"- {items[i].itemName,-10}| {items[i].optionText} + {items[i].option}    | {items[i].itemInfo,-40}    | 구매완료.");
                }
                else
                    Console.WriteLine($"- {items[i].itemName,-10}| {items[i].optionText} + {items[i].option}    | {items[i].itemInfo,-40}    | {items[i].buyGold} G");

            }


            Console.WriteLine();
            Console.WriteLine("1. 아이템 구매");
            Console.WriteLine("2. 아이템 판매");
            Console.WriteLine("0. 나가기");
            Console.WriteLine();
            Console.WriteLine("원하시는 행동을 입력해주세요.");
            Console.Write(">>");
            string input = Console.ReadLine();

            switch(input)
            {
                case "1":
                    Console.Clear();
                    Shopping(player);
                    break;
                case"2":
                    Console.Clear();
                    SellShopping(player);
                    //판매 기능 추가
                    break;
                case "0":
                    Console.Clear();
                    break;
                default:
                    Console.Clear();
                    Console.WriteLine("다시 입력해주세요");
                    Shopinfo(player);
                    break;
            }
        }

        private void Shopping(Player player)
        {
            Console.WriteLine("[보유 골드]");
            Console.WriteLine($"{player.gold}");

            Console.WriteLine("[아이템 목록]");
            for (int i = 0; i < items.Count; i++)
            {
                if (items[i].isBuy == true)
                {
                    Console.WriteLine($"-{i+1} {items[i].itemName,-10}| {items[i].optionText} + {items[i].option,10}    | {items[i].itemInfo,30}    | 구매완료.");
                }
                else
                    Console.WriteLine($"-{i+1} {items[i].itemName,-10}| {items[i].optionText} + {items[i].option,10}    | {items[i].itemInfo,30}    | {items[i].buyGold} G");

            }

            Console.WriteLine();
            Console.WriteLine("0. 나가기");

            Console.WriteLine();
            Console.WriteLine("원하시는 행동을 입력해주세요.");
            Console.Write(">>");
            string input = Console.ReadLine();
            int inputNum = 0;
            inputNum = int.TryParse(input, out inputNum) ? inputNum : -1;

            if(inputNum == 0) 
            {
                Console.Clear();
                Shopinfo(player);
            }
            else if( inputNum < 0)  // 이상한 번호를 타이핑 했을때
            {
                Console.Clear() ;
                Console.WriteLine("다시 입력해주세요");
                Shopping(player);
            }
            else if(inputNum -1 < items.Count)
            {
                if (items[inputNum-1].buyGold <= player.gold)
                {
                    items[inputNum - 1].isBuy = true;
                    player.gold -= items[inputNum - 1].buyGold;
                    player.AddInven(items[inputNum - 1]);
                    Console.Clear();
                    Console.WriteLine("구매되었습니다!");
                }
                else
                {
                    Console.Clear();
                    Console.WriteLine("구매할 수 없습니다.");
                }

                Shopping(player);

            }
            else
            {
                Console.Clear();
                Console.WriteLine("잘못 입력하셨습니다.");
                Shopping(player);
            }
        
        }
        
        private void SellShopping(Player player)
        {
            Console.WriteLine("[보유 골드]");
            Console.WriteLine(player.gold);

            Console.WriteLine("[아이템 목록]");
            for(int i=0; i < player.inven.Count; i++)
            {
                Console.WriteLine($"{player.inven[i].equipMsg}{i + 1}. {player.inven[i].itemName}    | {player.inven[i].optionText}+{player.inven[i].option}    | {player.inven[i].itemInfo}     | {player.inven[i].sellGold} G");
            }

            Console.WriteLine();
            Console.WriteLine("0. 나가기");
            Console.WriteLine();
            Console.WriteLine("원하시는 행동을 입력해주세요");
            Console.Write(">>");
            string input = Console.ReadLine();
            int inputNum = 0;
            inputNum = int.TryParse(input, out inputNum) ? inputNum : -1;

            if (inputNum == 0)
            {
                Console.Clear();
                Shopinfo(player);
            }
            else if (inputNum < 0)  // 이상한 번호를 타이핑 했을때
            {
                Console.Clear();
                Console.WriteLine("다시 입력해주세요");
                SellShopping(player);
            }
            else if (inputNum -1 < player.inven.Count)
            {
                player.inven[inputNum - 1].isBuy = false;
                player.inven[inputNum -1].isEquip = false;
                player.inven[inputNum - 1].equipMsg = "";
                if (player.inven[inputNum - 1].itemType == ItemType.Weapon)
                {
                    player.addAtk -= player.inven[inputNum - 1].option;
                }
                else if (player.inven[inputNum - 1].itemType == ItemType.Armor)
                {
                    player.addDef -= player.inven[inputNum - 1].option;
                }
                player.gold += player.inven[inputNum - 1].sellGold;
                player.inven.RemoveAt(inputNum - 1);
                Console.Clear();
                SellShopping(player);
            }
            else
            {
                Console.Clear();
                SellShopping(player);
            }    


        }

 

 상점에서 아이템을 구매하는것과 판매하는것 그리고 이미 구매한것이라면 구매했다고 알림까지 만들었는데

 

상점에서 구매한 아이템을 인벤에 넣고 상점에서 판매하는 아이템과 내 인벤에 있는 아이템이 같다면

 

구매 완료표시를 하게 할때 리스트의 인덱스 범위를 초과하는 오류가 정말 많이나서

 

브레이크 포인트로 예외처리를 해줬다.

 

 

실력은 부족했지만 정말 열심히 했던것 같다. 근데 글을 작성하면서 내 코드를 돌아보니

 

정말 지저분하네....  뭔가 기능을 구현하는것에만 집중한 나머지 정리하면서 만들질 못해서

 

그리고 좀 더 다른 방법으로 같은 기능을 만들수 있을것 같고... 아직 실력이 많이 부족하다.

 

주말동안 좀 더 만지작 거리고 배운내용을 복습하는 시간을 가져야겠다.

 

1월 5일 TIL은 이렇게 마치도록 하겠다.

 

 

 

 

 

 

'내일배움캠프' 카테고리의 다른 글

240109 - TIL  (0) 2024.01.09
240108-TIL  (0) 2024.01.08
240104-TIL  (0) 2024.01.04
240103-TIL  (0) 2024.01.03
240102-TIL  (0) 2024.01.02