Unity_2기 내일배움캠프 TIL

Unity_2기 2주차 (231110)

잼잼재미 2023. 11. 10. 21:04

오늘은 내일배움캠프 2주차 개인과제인 스파르타 던전 Text게임을 만들었다.

Text RPG 게임은 예전에 한번 만들어 본적 있어서 조금 자신이 있었는데,

막상 새로 만들려고하니 쉽지가 않았다. 

 

● 전체코드

using System.Collections.Generic;
internal class Program
{
    private static Character player;
    public static List<Item> inventory;
    public static List<Item> equip;

    // 무기
    public static Weapon oldSword;
    public static Weapon goldSword;
    public static Weapon woodAx;
    public static Weapon silverBow;

    // 방어구
    public static Armor ironArmor;
    public static Armor goldArmor;
    public static Armor silverGloves;

    static void Main(string[] args)
    {           
        GameDataSetting();
        DisplayGameIntro();
    }

    static void GameDataSetting()
    {
        // 캐릭터 정보 세팅
        player = new Character("나재민", "전사", 1, 10, 5, 100, 1500);
        inventory = new List<Item>();
        equip = new List<Item>();

        // 아이템 정보 세팅
        // 1.무기
        oldSword = new Weapon();
        oldSword.itemType = ItemType.Weapon;
        oldSword.Name = "낡은 검";
        oldSword.Description = "쉽게 볼 수 있는 낡은 검입니다.";
        oldSword.Atk = 2;
        inventory.Add(oldSword);

        goldSword = new Weapon();
        goldSword.itemType = ItemType.Weapon;
        goldSword.Name = "황금 검";
        goldSword.Description = "황금으로 만든 비싼 검입니다.";
        goldSword.Atk = 4;
        inventory.Add(goldSword);

        woodAx = new Weapon();
        woodAx.itemType = ItemType.Weapon;
        woodAx.Name = "나무 도끼";
        woodAx.Description = "나무로 만든 도끼입니다.";
        woodAx.Atk = 3;
        inventory.Add(woodAx);

        silverBow = new Weapon();
        silverBow.itemType = ItemType.Weapon;
        silverBow.Name = "은 활";
        silverBow.Description = "은으로 만든 활입니다.";
        silverBow.Atk = 1;
        inventory.Add(silverBow);

        // 2.방어구
        ironArmor = new Armor();
        ironArmor.itemType = ItemType.Armor;
        ironArmor.Name = "무쇠 갑옷";
        ironArmor.Description = "무쇠로 만들어져 튼튼한 갑옷입니다.";
        ironArmor.Def = 5;
        inventory.Add(ironArmor);
        Equip(ironArmor);

        goldArmor = new Armor();
        goldArmor.itemType = ItemType.Armor;
        goldArmor.Name = "황금 갑옷";
        goldArmor.Description = "황금으로 만들어져 튼튼하고 비싼 갑옷입니다.";
        goldArmor.Def = 10;
        goldArmor.Hp = 5;
        inventory.Add(goldArmor);

        silverGloves = new Armor();
        silverGloves.itemType = ItemType.Armor;
        silverGloves.Name = "은 장갑";
        silverGloves.Description = "은로 만든 장갑입니다.";
        silverGloves.Def = 3;
        silverGloves.Hp = 2;
        inventory.Add(goldArmor);
    }

    static void DisplayGameIntro()
    {
        Console.Clear();

        Console.WriteLine("스파르타 마을에 오신 여러분 환영합니다.");
        Console.WriteLine("이곳에서 전전으로 들어가기 전 활동을 할 수 있습니다.");
        Console.WriteLine();
        Console.WriteLine("1. 상태보기");
        Console.WriteLine("2. 인벤토리");
        Console.WriteLine();
        Console.WriteLine("원하시는 행동을 입력해주세요.");

        int input = CheckValidInput(1, 2);
        switch (input)
        {
            case 1:
                DisplayMyInfo();
                break;

            case 2:
                // 작업해보기
                DisplayInventory();
                break;
        }
    }

    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.Atk - player.StartAtk})");
        Console.WriteLine($"방어력 :{player.Def} (+{player.Def - player.StartDef})");
        Console.WriteLine($"체력 : {player.Hp} (+{player.Hp - player.StartHp})");
        Console.WriteLine($"Gold : {player.Gold} G");
        Console.WriteLine();
        Console.WriteLine("0. 나가기");

        int input = CheckValidInput(0, 0);
        switch (input)
        {
            case 0:
                DisplayGameIntro();
                break;
        }
    }

    static void DisplayInventory()
    {
        Console.Clear();

        Console.WriteLine("인벤토리");
        Console.WriteLine("보유 중인 아이템을 관리할 수 있습니다.");
        Console.WriteLine();
        Console.WriteLine("[아이템 목록]");
        foreach (Item it in inventory)
        {
            Console.Write(" - ");

            foreach(Item item in equip)
            {
                if (item == it)
                {
                    Console.Write($"[E]");
                    break;
                }                 
            }

            Console.Write($"{it.Name}");

            if (it.itemType == ItemType.Weapon)
            {
                Console.Write($" | 공격력 + {((Weapon)it).Atk}"); 
            }
            else
            {
                Console.Write($" | 방어력 + {((Armor)it).Def}");
                Console.Write($" | 체 력 + {((Armor)it).Hp}");
            }

            Console.WriteLine($" | {it.Description}");         
        }

        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:
                // 장착 관리
                DisplayInventoryManager();
                break;
        }
    }

    static void DisplayInventoryManager()
    {
        Console.Clear();

        Console.WriteLine("장착관리");
        Console.WriteLine("보유 중인 아이템을 장착 및 해제할 수 있습니다.");
        Console.WriteLine();
        Console.WriteLine("[아이템 목록]");

        int count = 1;

        foreach (Item it in inventory)
        {
            Console.Write(" - ");
            Console.Write($"{count}. ");

            foreach (Item item in equip)
            {
                if (item == it)
                {
                    Console.Write($"[E]");
                    break;
                }
            }

            Console.Write($"{it.Name}");

            if (it.itemType == ItemType.Weapon)
            {
                Console.Write($" | 공격력 + {((Weapon)it).Atk}");
            }
            else
            {
                Console.Write($" | 방어력 + {((Armor)it).Def}");
                Console.Write($" | 체 력 + {((Armor)it).Hp}");
            }

            Console.WriteLine($" | {it.Description}");

            count++;
        }

        Console.WriteLine();
        Console.WriteLine("0. 나가기");
        Console.WriteLine();
        Console.WriteLine("장착 및 해제할 아이템의 숫자를 입력해주세요.");

        int input = CheckValidInput(0, count - 1);
        if(input == 0)
        {
            DisplayGameIntro();
        }
        else
        {
            foreach (Item item in equip)
            {
                if (item == inventory[input - 1])
                {
                    UnEquip(inventory[input - 1]);
                    DisplayInventoryManager();
                }             
            }
            Equip(inventory[input - 1]);
            DisplayInventoryManager();
        }
    }

    // 장착
    static void Equip(Item item)
    {
        equip.Add(item);

        if (item.itemType == ItemType.Weapon)
        {
            player.Atk += ((Weapon)item).Atk;
        }
        else
        {
            player.Def += ((Armor)item).Def;
            player.Hp += ((Armor)item).Hp;
        }
    }

    // 장착 해제
    static void UnEquip(Item item)
    {
        equip.Remove(item);

        if (item.itemType == ItemType.Weapon)
        {
            player.Atk -= ((Weapon)item).Atk;
        }
        else
        {
            player.Def -= ((Armor)item).Def;
            player.Hp -= ((Armor)item).Hp;
        }
    }

    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("잘못된 입력입니다.");
        }
    }
}


public class Character
{
    public string Name { get; set; }
    public string Job { get; set; }
    public int Level { get; set; }
    public int StartAtk { get; set; }
    public int Atk { get; set; }
    public int StartDef { get; set; }
    public int Def { get; set; }

    public int StartHp { get; set; }
    public int Hp { get; set; }
    public int Gold { get; set; }

    public Character(string name, string job, int level, int startAtk, int startDef, int startHp, int gold)
    {
        Name = name;
        Job = job;
        Level = level;
        StartAtk = startAtk;
        Atk = startAtk;
        StartDef = startDef;
        Def = startDef;
        StartHp = startHp;
        Hp = startHp;
        Gold = gold;
    }
}
    
public enum ItemType
{
    None,
    Weapon,
    Armor,
}

public class Item
{
    public string Name { get; set; }
    public string Description { get; set; }
    public ItemType itemType = ItemType.None;
}

public class Weapon : Item
{
    public int Atk { get; set; }


}

public class Armor : Item
{
    public int Def { get; set; }
    public int Hp { get; set; }
}

 

● 어려웠던 점

foreach (Item it in inventory)
{
    Console.Write(" - ");

    foreach(Item item in equip)
    {
        if (item == it)
        {
            Console.Write($"[E]");
            break;
        }                 
    }

    Console.Write($"{it.Name}");

    if (it.itemType == ItemType.Weapon)
    {
        Console.Write($" | 공격력 + {((Weapon)it).Atk}"); 
    }
    else
    {
        Console.Write($" | 방어력 + {((Armor)it).Def}");
        Console.Write($" | 체 력 + {((Armor)it).Hp}");
    }

    Console.WriteLine($" | {it.Description}");         
}

가장 어려웠던 점은 Item을 상속 받는 Weapon과 Armor를 List<Item>으로 관리할 때, Weapon과 Armor에 있는 변수를 불러오는 것이었다. 자식 클래스에서는 부모 클래스의 변수를 그냥 받을 수 있지만 반대인 경우에서는 안됐다.

하지만 인벤토리를 관리하기 위해서는 무조건 List<Item> 형식으로 관리할 수 밖에 없었다.

그래서 구글링을 통해서 형변환을 하면 되지 않을까? 라는 생각이 들었고, 형변환을 해봤지만 여전히 되지 않았다.

if (it.itemType == ItemType.Weapon)
{
    Console.Write($" | 공격력 + {(Weapon)it.Atk}");
}

위와 같이 형변환을 했는데 되지 않았고, 구글링과 고민을 2시간 정도 한 뒤, 처음으로 튜터님께 질문을 했다.

튜터님도 같은 형변환 방법으로 알려주셨고, 알고보니 괄호가 빠진 것이었다..

if (it.itemType == ItemType.Weapon)
{
    Console.Write($" | 공격력 + {((Weapon)it).Atk}");
}

겨우 괄호 하나로 2시간을 고민했다고 생각하니 조금 허무했지만, 앞으로 위와 비슷한 작업을 할 때, 절대 까먹지 않을 것 같았다.

 

딱히 그 외에는 많이 어려웠던 부분은 없었던 것 같은데 작업 시간은 거의 오늘 하루를 모두 썼다.

아직 필수 구현부분만 완성을 했고, 주말과 월요일 오전까지 시간이 된다면 추가 구현부분도 더 추가해 볼 것이다.

게임을 완성하고 막상 플레이를 하니, 생각보다 짧아서 아직 나의 실력이 많이 부족하다는 것을 또 느꼈다.

 

● 완성본

 

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

Unity_2기 3주차 (231114)  (1) 2023.11.14
Unity_2기 3주차 (231113)  (1) 2023.11.13
Unity_2기 2주차 (231109)  (0) 2023.11.09
Unity_2기 2주차 (231108)  (0) 2023.11.08
Unity_2기 2주차 (231107)  (0) 2023.11.07