부트캠프/본캠프

[내일배움캠프_2025JUL10]TextRPG 던전/레벨/저장 구현

Young_A 2025. 7. 10. 21:42

목차

    [내일배움캠프_2025JUL10]TextRPG 던전/레벨구현

     

    시간이 너무 빠르다. 벌써 목요일!


    ReadMe 

    GitHub에 프로젝트를 올릴 때, 프로젝트에 대한 개요와 사용 방법, 협업 방식 등의 정보를 담는 문서이다.

    누가 내 프로젝트를 보게 될지를 고려하여, 그들이 알고 싶어 할 내용을 중심으로 작성하는 것이 좋다.

    보통은

    • 협업 중인 팀원들과 같은 방향성과 이해를 공유하기 위해
    • 외부 사용자가 프로젝트에 대해 이해할 수 있도록 돕기 위해
    • 시간이 지나 다시 프로젝트를 열었을 때 내용을 쉽게 파악할 수 있도록 하기 위해

    작성되며, 내 경우에도 비슷하다.

    ReadMe의 구성 예시

    1. Project Description: 프로젝트의 목적과 주요 기능을 간단히 설명
    2. Project Information: 사용한 기술 스택, 설치 방법, 실행 방법 등을 정리
    3. Contribute: 오픈소스 프로젝트일 경우, 외부 개발자가 어떤 방식으로 참여할 수 있는지 설명
    4. License: 소스코드 사용과 배포에 대한 조건을 명시
    5. References: 외부에서 참고한 자료나 리소스를 기록
    6. Code Status: 현재 프로젝트의 개발 상태 (개발 중, 배포 완료 등)

    대부분의 ReadMe 파일은 마크다운 형식으로 작성 되는 편이다.

    깃헙 저장소에서 Add a README를 통해서 올릴 수도 있고, 프로젝트 폴더에 README.md 파일을 생성해도 자동으로 저장소 첫 화면에 표시 된다.

     

    물론 마크다운 형식을 익히는 것도 좋지만 당장 익히기보다는 이미 주요 형식 몇가지는 알고 있으니 작성하면서 하나씩 익히는 것이 더 좋을 것이라고 판단하여  https://www.easy-me.com/d 를 이용하기로 했다.

    MIT License

    오픈 소스 소프트웨어 라이선스 중 하나로, 가장 간단하고 자유로운 라이선스이다.

    • 누구나 자유롭게 사용, 복사, 수정, 배포, 상업적 이용 가능
    • 단, 소스코드에 포함된 라이선스 문구와 저작권 표시 (Copyright)는 그대로 유지
    • 책임은 사용자에게 있음.

    Dictionary 순회

    SceneManager에서 관리하는 _dungeons Dictionary를 던전 입장 할 때 리스트로 출력하기 위해 for를 쓰려고 했다.

    앞에 유저가 선택할 수 있게 1, 2, 3, 넘버링을 해야했기 때문에 for 문을 쓰려고 했지만 사용할 수 없었다.

    Dictionary 값은 Key 값이나 Value 값으로 받기 때문이다.

     

    dict.ElementAt(index)를 사용할 수도 있지만 (C# 7.0 이후로는 내부적으로 삽입 순서를 유지하더라도)

    공식적으로는 순서를 보장하지는 않기 때문에 항상 같은 항목이 반환된다고 확신할 수는 없다.

     

    따라서 Dictionary 순회를 하려면 foreach를 사용하는 것이 좋다.

    //SceneManager
    public Dictionary<DungeonType, Dungeon> _dungeons = new Dictionary<DungeonType, Dungeon>();

     


    이번 상황에는 Value 값인 Dungeon 들만 필요했는데 Key나 Value 값들만 ICollection<T> 형식으로 받을 수도 있다.

    foreach (var dungeon in dungeonDict.Values)	//ICollection<Dungeon>
    {
        Console.WriteLine(dungeon.Name);
    }

     

    만약 List<T>나 배열로 받고 싶다면 .ToList() 혹은 .ToArray()를 사용할 수도 있다.

    using System.Linq;
    List<Dungeon> dungeonList = dungeonDict.Values.ToList();
    Dungeon[] dungeonArray = dungeonDict.Values.ToArray();

     

    >>그러나 진행하다 보니까 Type의 의미가 없을 것 같아서 List<T>로 바꾸었다! 😂


    GitHub Organization

    컬리지 다닐 때 깃헙 계정을 만들고 공부 시작했다 멈췄다를 반복한 계정이 있다.

    그래도 그냥 쓰고 싶어서 Organization을 만들고 그 곳에 내일배움캠프 관련 프로젝트들은 이 곳에 저장하기 시작했다.

    오늘 튜터님께 간 김에 물어봤는데 오히려 권유하려고 했었다고 하셨다.


    한글, 영문 섞인 문자열 정렬

    아이템 출력할 때 \t 으로만 관리하다보니 상태가 다음과 같았다

     

    미쳐버린 가독성을 가만히 둘 수 없었고, 슬랙에 도움을 구했다.

    $"" 보간만 쓰는지라 string.Format() 보간을 아예 잊고 살았는데, 추천해주신 덕분에 생각이 났다.

    다음과 같이 덜 못생겨졌다. 아마 .PadRight()도 같이 썼을 거다.

     

    결국 한글과 영문의 길이를 계산하는 방법을 찾기 시작했고...

    다음과 같은 방법을 찾았다.

    Encoding.Default.GetByteCount(str_e);
    //출처: https://kojin777.tistory.com/67 [요정지니의 램프속 IT세상:티스토리]

     

    다만 이 방법도 완벽하지 않았다. ....

    내 컴퓨터에서 인코딩 문제가 자꾸 발생했는데 무언가 잘 못 된건가 싶기도 하고.

    그래서 그냥 무식하게 한글과 영문을 카운트하기로 했다.

    public static int GetStringWidth(string str)
    {
        int width = 0;
        foreach (char c in str)
        {
            width += c >= 0xAC00 && c <= 0xD7A3 ? 2 : 1;  
            //한글 전각 문자 범위 
            //https://lovepw.tistory.com/969
        }
        return width;
    }

     

    깔끔- 뿌듯-

    과제 다 끝내고 시간이 남아서 찾을 수 있었던 것 같다.

    아니었다면 이미 출력 방법부터 우회하고 잊어버렸을 듯.


    [JsonProperty] [JsonIgnore]

    처음에는 저장을 프로그램을 껐다가 같은 플레이어를 로드하면 보유 아이템이 로드가 안되는 걸 발견했다.

    제일 처음 스타터 아이템을 주고 시작했을 때는 아이템이 있으니까, 이전 아이템 잘 로드한 거겠지! 라는 생각에 알아차리지 못했다!

     

    Player 클래스에 가서 JsonProperty를 썼는데 잘 못 된 곳에 쓰는 바람에 아래와 같이 중복으로 저장이 되었다.

    {
      "id": 1,
      "level": 1,
      "name": "sa",
      "job": "전사",
      "attack": 10,
      "defence": 5,
      "health": 100,
      "gold": 1500,
      "exp": 0,
      "inventory": [],
      "equipment": {},
      "Id": 1,
      "Level": 1,
      "Name": "sa",
      "Job": "전사",
      "Attack": 10,
      "Defence": 5,
      "Health": 100,
      "Gold": 1500,
      "Exp": 0,
      "Inventory": []
    }

     

     

    private 앞에 [JsonProperty]를 사용하니 private 필드들도, public 프로퍼티들도 전부 json에 저장되고 있었던 것.

    다른 변수들은 어차피 값이 덮어씌워지니까 상관이 없는데 (아예 없진 않다), inventory, Inventory는 List 형식이라서 초기화될때 주어지던 스타터 장비 + 저장되어 있었던 장비까지 해서 더블링 되는 것 같았다.

    • public 필드는 직렬화, 역직렬화에 포함되지만,
    • private은 포함되지 않으므로 [JsonProperty]가 없다면 무시된다.
    • public 읽기 전용인 경우에는 직렬화는 가능하지만, 역직렬화는 불가능하다.

    나는 나중에 Property에서 어떤 작업을 하게 될 지 모르기 때문에 + 확실하게 셋업 되어서 헷갈릴 소지를 줄이기 위해 private 필드들을 모두 [JsonProperty] 선언해주었고, public 프로퍼티들은 모두 [JsonIgnore]로 선언해주었다.

     


    느낀점

    오늘은 아침 일찍 수영 다녀와서 조금 일찍 시작했는데,

    수영모 때문인가ㅋㅋ 오전 동안은 두통 때문에 실질적인 학습 효율은 그렇게 좋지 않았다.

    C# 체크리스트 귀로만 들으면서 TextRPG 코딩 하는 데, 수업 중 딴짓 재밌음 이슈로 도리어 코딩에 집중 할 수 있었다😂

     

    과제는 3시 30분 쯤 다 끝냈고, 튜터님께 가서 추가할만한 것들 확인 받았는데 리팩토링도 이미 다 끝내서 더 할 건 없어보인다는 답을 받고 쓸 데 없는 포맷팅에 전념하다가 저녁 먹고 깃헙이랑 이런 것들 확인한 후에 최최종으로 구현 리스트 실행해보고 과제를 제출하려고 했는데 저장 문제를 발견해서.. TIL 먼저 작성 완료하고 다시 제출할 것 같다. 하는 김에 시연 영상도 찍어서 첨부해야지.

     

     

    ReadMe 템플릿을 조사하면서 Reference를 잘 첨부하지 않고 있구나, 라는 걸 느꼈다.

    컬리지 다닐 때 팀원이 인터넷에서 긁어온 문단을 쓰는 바람에... 과제 점수 0점 받았던 트라우마가 드디어 치료됬나보다.

    앞으로는 조사 링크 첨부하려고 노력할 것이다.


    내일 학습 할 것은 무엇인지

    자러가기 전에 제출하려고 했는데 내일 아침에 영상 찍으면서 발견한 에러 (로드한 직후에 장비창에 들어가면 장착 해제된 것처럼 보임. 실제로 equipment에 안들어가있는건지 확인 필요함) 확인하고 올려야겠다.