내일배움캠프 9일차 TIL <C# TextRPG> 04/17

정광훈(Unity_9기)·2025년 4월 17일

TIL (Today I Learned)

목록 보기
21/110
post-thumbnail

C# TextRPG

● 오늘 있었던 일

프로젝트를 진행하면 막히는 부분이 많았다.

그래도 오늘 필수구현 기능까지 구현했다.

내가 생각한대로 잘 작동되어서 오늘 하루 만족한다.

구현하는 과정에서 다른 사람이 한 것도 참고해 보고 튜터님에게도 물어도 보고 스스로 해결도 해보고 알아가는 점이 많은 날이었다.

그 중에서 튜터님에게 물어보고 해결한 아이템 구매 부분에 대해서 작성한다.


● 발생한 문제

    public void buyItem(Player player) // 3.1 아이템 구매
    {
        bool loop = true; // 반복한다

        do
        {
            Console.Clear();

            Console.WriteLine("상점\n필요한 아이템을 얻을 수 있는 상점입니다.\n");
            Console.WriteLine($"[보유 골드]\n{player.Gold} G\n");
            Console.WriteLine("[아이템 목록]");

            for (int i = 0; i < itemStatus.list.Count; i++) // 아이템 불러오기
            {
                string StrItemPur = itemStatus.list[i].itemPur ? "구매 완료" : $"{itemStatus.list[i].itemPrice} G"; // 가격을 표시할 건지 구매 완료를 표시할 건지

                if (itemStatus.list[i].itemType == "공격력")
                {
                    Console.WriteLine($"- {i + 1} {itemStatus.list[i].itemName}  | {itemStatus.list[i].itemType} +{itemStatus.list[i].itemAtt}  | {itemStatus.list[i].itemInfo}  | {StrItemPur}"); // 무기 출력
                }
                else
                {
                    Console.WriteLine($"- {i + 1} {itemStatus.list[i].itemName}  | {itemStatus.list[i].itemType} +{itemStatus.list[i].itemDf}  | {itemStatus.list[i].itemInfo}  | {StrItemPur}"); // 방어구 출력
                }
            }

            Console.WriteLine("\n0. 나가기\n");
            Console.Write("\n원하시는 행동을 입력해주세요.\n>> ");

            string input = Console.ReadLine(); // 입력값

            if (int.TryParse(input, out int input2)) // 문자로 입력받은 숫자를 int형으로 변환 -> input: 문자, input2: 숫자
            {
                input2--; // 리스트는 0부터 시작하므로 입력값에서 1 감소

                if (input != "0" && (input2 >= 0 && input2 < itemStatus.list.Count)) // input이 "0"이 아니고,  list[0] <= 입력값 < list[리스트의 개수] 
                {
                    Item BI = itemStatus.list[input2]; // BI(BuyItem)의 줄인말

                    switch (input) // 입력에 따른 선택 
                    {
                        case "1": // 수련자 갑옷
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다.");
                            }
                            break;

                        case "2": // 무쇠갑옷
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다.");
                            }
                            break;

                        case "3": // 스파르타의 갑옷
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다.");
                            }
                            break;

                        case "4": // 낡은 검
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다.");
                            }
                            break;

                        case "5": // 청동 도끼
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다."); ;
                            }
                            break;

                        case "6": // 스파르타의 창
                            if (BI.itemPur) // 인벤토리에 아이템이 있을 경우
                            {
                                Message("이미 구매한 아이템입니다.");
                            }
                            else if (player.Gold >= BI.itemPrice) // 소지금 >= 아이템 가격
                            {
                                BI.itemPur = true; // 아이템 구매했다.
                                player.Gold -= BI.itemPrice; // 소지금을 아이템 가격만큼 차감
                                player.InvenItem.Add(BI); // 내 아이템에 추가
                                Message($"{BI.itemName}구매를 완료했습니다.");
                            }
                            else if (player.Gold < BI.itemPrice) // 소지금 < 아이템 가격
                            {
                                Message("Gold 가 부족합니다.");
                            }
                            break;

                        default: // 그 외 입력
                            Message("잘못된 입력입니다."); //ErrorMessage는 아래 있음
                            break;
                    }
                }
                else if (input == "0")
                {
                    loop = false; // 반복 끝
                    Shop(player); // 상점으로 이동
                }
                else
                {
                    Message("잘못된 입력입니다."); // 숫자로 변환 실패
                }
            }
            else
            {
                Message("잘못된 입력입니다."); // 숫자로 변환 실패
            }
        } while (loop); //  계속 반복
    }
    
    static void ErrorMessage(string msg) // 에러 문구
    {
        Console.WriteLine($"{msg}\n"); // 에러 문구 출력
        Console.WriteLine("아무키를 누르세요.\n");
        Console.ReadKey(); // 아무키 입력 받기
    }

내가 처음 코드를 짰을 때 Console.WriteLine("\n0. 나가기\n"); 전까지 문장(상점 UI라고 하겠다)은 do while문 밖에 있었다.

그렇게 했던 이유는 입력이 잘못되었을 때 콘솔 창에 문장들이 쌓이는게 지저분해보였다.

이 때 발생하는 문제는 아이템을 구매한 이후에 플레이어의 소지금과 아이템의 상태변화(구매 완료했는지 여부)가 업데이트 되지 않았다.

결국 do while 문에 전부 넣었는데 clear가 작동하면서 "잘못된 입력입니다" 나 "구매했습니다" 같은 문장도 출력되지않고 바로 삭제되어 버렸다.

다른 문제로 입력을 int로 받아서 if문으로 조건을 구성 했는데 숫자 키만 누를 거라 문자를 눌렀을 때 에러가 발생하는 상황을 생각하지 않았었다.

이 부분도 튜터님이 string으로 입력을 받고 switch문을 통해 코드를 짜는게 에러 발생을 방지 할 수 있다고 알려주셨다.


● 해결 방안

ErrorMessage라는 함수를 만들었고 그 안에 ReadKey()를 넣었다.

Console.ReadKey()는 아무 키를 입력했을 때 다음으로 넘어 가도록 하는 메서드다.

이 방법을 통해 콘솔 창이 Clear가 되기 전에 한번 멈춰 화면의 문구를 확인하고

넘어가도록 하는 방법도 있다는 것을 알게 되었다. ("구매했습니다", "잘못된 입력입니다." 같은 문구)

    static void Message(string msg) // 에러 문구
    {
        Console.WriteLine($"\n{msg}\n"); // 에러 문구 출력
        Console.WriteLine("아무키를 누르세요.\n");
        Console.ReadKey(); // 아무키 입력 받기
    }

Readkey()를 이용하여 출력문구가 있는 부분들에 다 넣어서 확실하게 출력된 후

아무 키를 눌러 다음으로 넘기도록 했다.

이 방법을 통해 모든 문장을 do while문에 넣어 입력시 출력되는 문구도 확인하면서 UI도 업데이트 시킬 수 있게 되었다.

입력을 int가 아닌 string으로 받고, if문이 아닌 switch문으로 아이템 구매를 제어하면서

문자 "0" ~ "6" 이외에 입력되는 모든 문자를 default로 가도록 하여 에러가 나는 것을 방지했다.

코드가 처음 작성했을 때보다 많이 늘어났지만 에러없이 안정적인 실행이 가능하게 해준다.
(switch부분은 너무 길기 때문에 위의 코드를 보자. 입력값을 받는 부분부터 보면 된다.)

0개의 댓글