ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2023.1.4
    TIL 2024. 1. 4. 20:45

    벌써 내일이면 개인과제를 제출해야하네요..

    우선 필수사항은 완료했습니다! 오예!

    필수사항은 완료했는데 어제 튜터님께서 말씀해주신 클래스끼리 연결을 느슨하게 하는 방법에 대해서 고민해보다가 수정 해봤구요. 그리고 변수명 중에서 다른게 더 맞는거 같아서 변수명도 바꾸고 새로운 함수도 만들어줬습니다.

    그러다보니깐 선택사항을 생각보다 많이 못만들긴 했는데 필수사항에 대해서 한차례 정리했으니깐 편하게 할 수 있지 않을까 기대해봅니다.


     

    개인과제

    menu.getClass(chain);
    inventory.getClass(chain);
    store.getClass(chain);
    itemList.getClass(chain);

    이어버리는 방법 변경.

    다른 클래스에서 State state를 정의할 수 없으므로, chain.state.name 식으로 변경.

     

    필수사항

     

    1. 게임 시작 화면

    2. 상태보기

    3. 인벤토리

    3-1. 장착 관리

    4. 상점

     

    어제 연결함에 따라 필수사항 완료.

    연결 방법 변경으로인한 변수들 변경만 있었음.

     

    선택사항

     

    1. 아이템 정보를 클래스 / 구조체로 활용해보기

    2. 아이템 정보를 배열로 관리하기

    하고 있는 중

     

    3. 아이템 추가하기

    3-1. 나만의 새로운 아이템을 추가하기

    4. 아이템 판매하기 : 장착한 아이템을 판매하면 아이템 장착 해제 설정

     void StoreSell()
     {
         if (n == 0);
         else 
         {
             int i = n - 1;
             if (sellitems[i].name.Contains("E"))
             {
                 chain.itemlist.RemoveItem(i);
                 if (sellitems[i].name.Contains("갑옷") || sellitems[i].name.Contains("망토"))
                 {
                     chain.inventory.installnameDepence = "";
                 }
                 else
                 {
                     chain.inventory.installnameStrike = "";
                 }
             }
             chain.state.Gold += sellitems[i].goldInt;
             sellitems[i] = null;
             for (i = n - 1; i < InventoryItemLength; i++)
             {
                 if (sellitems[i + 1] != null)
                 {
                     sellitems[i] = sellitems[i + 1];
                     sellitems[i + 1] = null;
                 }
                 else break;
             }
         }
     }

    어제 수정사항 코드 보는데 아이템 판매부분이라기 보다는 아이템 구매했을 때 나타나는 수정사항이다.

    아이템 장착 개선을 하면서 추가된 변수 두개를 추가해서 수정 완료.

    또한 어제 수정사항에서 적혀있는대로 새로운 객체를 만들어서 정보를 얻었기 때문에 따로 추가 변수를 이용해서 Gold 부분을 수정할 필요가 없으므로 삭제.

     

    5. 장착 개선 : 방어구와 무기 각각 한 개씩만 장착할 수 있도록 수정. 장착한 상태에서 같은 계열 아이템 선택 시 자동으로 장착 해제되도록 설정.

    public string installnameStrike = "";
    public string installnameDepence = "";
    
    void InventoryItemManage()
    {
        if (n == 0);
        else
        {
            int i = n - 1;
            if (inventoryitem[i].name.Contains("E")) //장착된 아이템 해제
            {
                if (inventoryitem[i].name.Contains("갑옷") || inventoryitem[i].name.Contains("망토"))
                {
                    inventoryitem[i].name = installnameDepence;
                    installnameDepence = "";
                }
                chain.itemlist.RemoveItem(i);
            }
            else //아이템 장착
            {
                if (inventoryitem[i].name.Contains("갑옷") || inventoryitem[i].name.Contains("망토"))//방어구
                {
                    if (installnameDepence == "")
                    {
                        installnameDepence = inventoryitem[i].name;
                        chain.itemlist.InstallItem(i);
                    }
                    else
                    {
                        for (int j = 0; j < InventoryItemLength; j++)//단, 다른 아이템 장착 시 장착된 아이템 자동 해제
                        {
                            if (inventoryitem[j].name.Contains("E") && (inventoryitem[j].name.Contains("갑옷") || inventoryitem[j].name.Contains("망토")))
                            {
                                inventoryitem[j].name = installnameDepence;
                                installnameDepence = inventoryitem[i].name;
                                chain.itemlist.RemoveItem(j);
                                chain.itemlist.InstallItem(i);
                                break;
                            }
                        }
                    }
                }
            }
            Console.Clear();
            InventoryItemManage();
        }

    else부분이 있지만 무기부분으로 안에 내용이 같기 때문에 생략

    어떻게 만들지 생각하는건 어렵지 않았으나 생각하지 못한 부분에서 로직이 생각대로 움직이지 않아서 시간이 걸렸음.

    installnameStrike와 installnameDepence는 아이템을 장착하면 아이템의 이름을 저장하는 변수로, 장착 시 [E]를 추가해서 name을 새로 저장하기 때문에 장착 해제 시 name을 바꾸는 방법을 생각하다가 나온 방법이다. 

    installname이 null아 아닐 경우 장착됐다고 확인되기 때문에 store에서도 장착된 아이템 판매 시 installname을 초기화 시켜준다.

    ->installname = null을 하면 null을 할 수없다는 식으로 문구가 나와서 초기화를 " "로 해준 상태. 편의상 null이라 설명.

    RemoveItem은 아이템 장착 해제 시 state에 설정해둔 추가된 스탯들을 초기화해주는 역할.

    따라서 장착된 아이템을 판매하거나 장착해제하거나 장착된 아이템을 변경 시 스탯을 초기화해서 다른 아이템 장착할 경우 스탯이 중복으로 들어가지 않게 해줌.

     

    InstallItem은 아이템 장착 시 state에 설정해둔 스탯들에게 지정된 스탯을 추가해주는 역할.

    따라서 installname이 null일 경우 장착된 아이템이 없으므로 아이템을 장착 시키면서 스탯을 추가해줌.

     

    가장 복잡했던 부분은 장착한 아이템이 있는 상태에서 다른 아이템을 장착하는 것으로, 장착하는 아이템을 계속 바꿀 때마다 같은 종류의 아이템이 두개 장착되거나 장착됐던 아이템 이름이 변경되는 등의 오류 발생.

    이유는 for문인데, 이 전에는 for문을 같은 부분을 두번 쓰기 싫어서 if문 바깥쪽으로 설정해둠. 이럴 경우 Contain("E")만 있을 때 가지고 있는 아이템의 종류에 상관없이 1. [E]가 초반에 있을 경우 그리고 2. 선택된 아이템이 방어구일 경우 무조건 저장되어있는 방어구로 변경되는 오류가 생김.

    해결하기 위해서 E가 있는 방어구 종류이면 if문 실행, E가 있는 무기 종류면 if문 실행할 수 있게 if문 조건을 수정해줌.

    적다보니 생각난거지만, for문의 위치가 변경됨에 따라 if문의 조건을 수정해도 될 것이라고 생각이 듬.

    ->원래 생각했던(오류가 생겼던) 조건문으로 설정 시 종류에 상관없이 E가 있는 name을 찾는 것이기 때문에 똑같은 오류 발생.

    어찌되었던 해결해서 완료함.

     

    6. 던전입장 기능 추가 : 추가 완료. 아직까지 오류 발견 안됨

    class Dungeon
    {
        public void ViewDungeon()
        {
            switch (n)
            {
                case 1:
                    Console.Clear();
                    int needStrike1 = 10 + chain.state.Lv;
                    int needDepence1 = 5 + chain.state.Lv;
                    int needHP1 = 20 + random.Next(6);
                    EasyDungeon(needStrike1, needDepence1, needHP1);
                    break;
            }
        }
    
        void EasyDungeon(int Strike, int Depence, int hp)
        {
            switch (n)
            {
                case 1:
                    Console.Clear();
                    if (chain.state.HP <= hp)
                    {
                        Console.Clear();
                        Console.WriteLine("\n체력이 부족해 입장하실 수 없습니다.\n던전을 나갑니다.");
                        Console.ReadLine();
                    }
                    else EnterDungeon(0, Strike, Depence, hp);
                    break;
            }
        }
        
        void EnterDungeon(int level, int Strike, int Depence, int hp)
        {
            switch (level)
            {
                case 2:
                    if (strike >= needStrike)
                    {
                        ClearPercent += PlusPercent;
                        if (strike - needStrike > 5)
                        {
                            ClearPercent += PlusPercent;
                        }
                        else if (needStrike - strike > 2)
                        {
                            ClearPercent -= PlusPercent;
                            if (needStrike - strike > 5)
                            {
                                ClearPercent -= PlusPercent;
                            }
                        }
                    }
                    if (depence >= needDepence)
                    {
                        ClearPercent += PlusPercent;
                        if (depence - needDepence > 5)
                        {
                            ClearPercent += PlusPercent;
                        }
                        else if (needDepence - depence > 2)
                        {
                            ClearPercent -= PlusPercent;
                            if (needDepence - depence > 5)
                            {
                                ClearPercent -= PlusPercent;
                            }
                        }
                    }
                    if (percent < ClearPercent)
                    {
                        clearGold = 1000 + (random.Next(10) + chain.state.Lv) * 100;
                        clear = true;
                        Clear(40, clearGold);
                        chain.state.HP -= 40;
                        chain.state.Gold += clearGold;
                    }
                    else
                    {
                        clear = false;
                        NonClear(hp);
                        chain.state.HP -= hp;
                    }
                    ClearCount(clear, 3);
                    break;
            }
    
            void Clear(int hp, int gold)
            {
                Console.WriteLine("\n던전 클리어\n");
                Console.WriteLine("[탐험 결과]\n");
                Console.WriteLine($"체력 {chain.state.HP} -> {chain.state.HP - hp}");
                Console.WriteLine($"골드 {chain.state.Gold} -> {chain.state.Gold + gold}");
            }
    
            void NonClear(int hp)
            {
                Console.WriteLine("\n던전 클리어 실패\n");
                Console.WriteLine("[탐험 결과]\n");
                Console.WriteLine($"체력 {chain.state.HP} -> {chain.state.HP - hp}");
            }
        }
    }

    던전은 총 세개의 난이도로 있으며, 난이도에 따라 요구하는 공격력과 방어력이 다르며, 사용되는 체력도 다름.

    공격력과 방어력이 낮다고 해서 못들어가는 것은 아님. 단, 체력은 낮으면 못들어감.

    ViewDungeon은 다른 클래스들이 그렇듯 메뉴에서 누르면 나오는 화면을 보여주는 함수. 여기서 다른 클래스들과 다른 점은 난이도에 따른 요구하는 공격력, 방어력, 체력을 만들어줌.

    이유는 난이도를 선택했을 때 보여주는 난이도별 입구 함수에서 앞에 Console로 보여주기위함이지만, 난이도별 함수에서 만들어도 될 것 같다고 정리하면서 생각이 듬.

     

    입구는 크게 신경쓸건 없고, 요구되는 최대 체력이 없으면 들어가지 못하게 만들었는데, 요구되는 최대 체력은 만약 던전 클리어 실패 시 깍이는 체력량을 의미함.

    체력이 0이 되면 안되게 하기 위해서 설정해둠.

     

    던전에 들어가면 가지고 있는 공격력, 방어력과 요구하는 공격력, 방어력을 비교해서 가중치를 줘서 클리어 확률을 높이거나 클리어 확률을 낮출 수 있도록 설정해둠.

    난이도 쉬움의 경우 쉬워야하기 때문에 클리어 확률을 낮추는 것은 없지만 보통부터 클리어 확률을 줄어들게 할 수 있고, 어려움은 차이가 크게 되면 확률이 더 적어지도록 설계함.

     

    클리어 시 소모되는 체력량은 동일하게 적용. 만약 클리어 실패 시 ViewDungeon에서 만든 체력량으로 깍이게 설정. 근데 클리어 시 소모되는 체력량을 랜덤하게 해줘도 상관없겠다 싶기는 함.

    클리어하게되면 난이도에 따라서 적용되는 경험치량을 다르게 주고 싶어서 difficult 변수를 사용해줌. 그리고 클리어하게 되면 골드량의 변화와 체력의 변화를 보여줬는데 바로 적용되는 것은 아니고 보여준 이후에 적용되게 만들어서 던전 클리어 보여주는 화면에서 중첩되지 않도록 설정해줌.

     

    7. 휴식기능 추가

    class Heal
    {
        public void ViewHeal();
        void CompleteHeal()
        {
            int hp = 100;
            chain.state.HP = hp;
            chain.state.Gold -= 500;
                default:
                    Console.Clear();
                    Console.WriteLine("잘못된 입력입니다.\n");
                    Console.WriteLine("체력이 회복되었으므로 나갑니다.\n");
                    Console.ReadLine();
                    break;
            }
        }
    }

    던전 기능을 만들고 가장 필요하다고 느낀 휴식기능.

    최대 100까지 가능하기 때문에 우선 회복은 무조건 100이 되도록 설정했으나 확률게임을 많이 했는지 회복량도 랜덤으로 해보고 싶은 생각이 드는 중.

    그리 어렵지 않게 만들었다.

     

    8. 레벨업 기능 추가

    void ClearCount(bool clear, int difficult)
    {
        int levelup = 10 * chain.state.Lv;
    
        if (clear)
        {
            clearCount += difficult;
        }
        if (clearCount > levelup)
        {
            LevelUp();
            chain.state.Lv++;
            chain.state.Strike += 0.5f;
            chain.state.Depence += 1;
            chain.state.HP += 10;
            clearCount = 0;
        }
    }
    
    void LevelUp()
    {
        Console.WriteLine("축하합니다! 레벨이 오르셨습니다!\n");
        Console.WriteLine($"{chain.state.Lv} -> {chain.state.Lv + 1}");
        Console.WriteLine("\n0. 나가기\n");
        int n = Number();
        switch (n)
        {
            default:
                Console.Clear();
                Console.WriteLine("잘못된 입력입니다.\n");
                LevelUp();
                break;
        }
    }

    회복기능과 레벨업 기능을 보았을 때 큰 차이점은 플레이어가 잘못입력해서 default로 이동할 경우이다.

    회복기능은 다시 원래 화면으로 돌려보내지 않는 반면, 레벨업 함수는 다시 레벨업 화면으로 돌아가게 된다.

    큰 이유는 회복기능을 사용할 경우 500골이 사용되면서 다시 회복기능 화면으로 돌아가게 되면 다시 500골을 쓰게 되고, 레벨업은 레벨업 화면으로 돌아가도 수치변화가 없기 때문이다.

    이렇게 만든 이유는 회복을 한 후에 다시 회복을 선택하는 화면으로 돌아갈 필요가 없기 때문에 메뉴화면으로 돌아가게 되고, 레벨업 함수는 레벨업 화면을 보여준 후에 바로 메뉴화면으로 이동하지 않기 때문에 수치 조정이 가능한 함수 부분이 있기 때문이다.

    레벨 업을 하게 되면 공격력이 0.5 오르게 되는데 공격력을 int로 설정했기 때문에 float으로 바꿔줘야 0.5를 더해줄 수 있다. 그러면서 공격력을 받고 있던 다른 변수들도 float으로 바꿔주었다.

     

    9. 게임 저장하기 추가 : 어떻게 해야할지 찾아봐야함

     


     

    어떻게 저장하기 빼고 전부 완성했습니다~~

    조금 세세하게 바꾸고 싶은 부분이 있기때문에 좀 더 만들어준 것을 플레이하면서 세부조정하지 않을까 싶습니다.

    좀 더 플레이하면서 생각나는 아이디어 있으면 바꾸는 것으로 해보려고 합니다.

    그리고 아직 강의 수강을 다 못해서 강의도 들어보고 또 간단하게 바꿀 수 있거나 코드를 깔끔하게 만들 수 있으면 그렇게 하는게 좋을 것 같습니다.

    추가적으로 던전 클리어 시 아이템 드랍하게 하고 싶은데 난이도에 따라서 나올 수 있는 아이템 정하려고 생각했는데 아이템 만드는걸 이걸 생각 안하고 만들었더니 .. 다시 하려면 좀 시간이 걸릴거같습니다.내일 안에 건드리는 것보다는 세세한걸 고치는게 맞는거같습니다.

    'TIL' 카테고리의 다른 글

    2024.1.8  (2) 2024.01.08
    2024.1.5  (0) 2024.01.05
    2024.1.3  (1) 2024.01.03
    2024.1.2-class  (1) 2024.01.02
    2023.12.29 - 주석 단축키, 조건문, 배열, 컬렉션  (1) 2023.12.29
Designed by Tistory.