내일배움캠프 14일차 [TIL]

장민제·2025년 4월 24일

내일배움캠프

목록 보기
14/41

✅ 오늘의 요약

  • 코딩 테스트 문제 풀이
  • 팀프로젝트 작업을 진행

🔍 코딩테스트 문제 풀기

오늘도 코딩테스트 문제를 풀었다.
가볍게 Lv. 0 문제들 몇 개 풀어주고
Lv. 1 문제들을 시작했다.

외계행성의 나이
진료순서 정하기
명예의 전당(1)

레벨 하나 올라갔는데 왜이리... 어렵게만 느껴지는지 모르겠다.
아직 C#과 덜 친해진거 같다.. 더 열심히 해야겠다는 생각만 든다.

💪 TextRpg 팀 프로젝트 진행

전투 종료 시 보상 지급을 하는 기능을 구현해냈다.

📃 Reward 클래스

public class Reward
{
    public int Exp { get; set; }
    public int Gold { get; set; }
    public List<Item> Items { get; set; }

    public Reward()
    {
        Exp = 0;
        Gold = 0;
        Items = new List<Item>();
    }
}

전투 보상을 담는 클래스를 생성
경험치, 골드, 아이템 등의 정보를 저장한다.

📃 BattleReward 클래스

public class BattleReward
{
    Random rand = new Random();
    ItemManager itemManager;

    public BattleReward(ItemManager itemManager)
    {
        this.itemManager = itemManager;
    }

    public Reward CreateBattleReward(int floor, int killCount)
    {
        // 새로운 보상 생성
        Reward reward = new Reward();

        // 보상 경험치 적용
        reward.Exp = 20 * floor * killCount;

        // 처치한 몬스터 만큼 아이템 생성
        for (int i = 0; i < killCount; i++)
        {
            int chance = rand.Next(0, 100);

            // 아이템 생성 확률 = (5 + 현재 층수)% 
            if (chance < 5 + floor)
            {
                reward.Items.Add(itemManager.GetRandomItem());
            }

            else
                reward.Gold += floor * 10;
        }

        return reward;
    }

    public void ApplyReward(Reward reward, Player player)
    {
        player.RewardExp(reward.Exp);
        player.state.Gold += reward.Gold;

        if (reward.Items.Count != 0)
        {
            foreach (var item in reward.Items)
            {
                if (item.IsOwned)
                {
                    player.state.Gold += item.Price;
                }
                item.ChangeOwnership(true);
            }
        }
    }

CreateBattleReward() 메서드

  • 현재 층수floor와 처치한 몬스터 수killCount에 따라 보상을 생성해준다.

ApplyReward() 메서드

  • 보상을 플레이어에게 적용하는 메서드
  • 이미 소유한 아이템이라면 판매 처리를 한다.
BattleReward battleReward = new BattleReward(sceneManager.ItemManager);
Reward reward = battleReward.CreateBattleReward(floor, killCount);
battleReward.ApplyReward(reward, player);

위와 같이 생성하고 사용한다.

💻 실행 화면


🔧 코드 리팩토링

🏹 BattleScene.cs

  • 기존에 BattleScene 클래스에서 출력하던 정보들을 PrintBattleInfo 클래스를 만들어 기능을 분할 하였다.
using TextRPG.Unit.Child;

public class PrintBattleInfo
{
	// 전투 시작 시 Hp, Mp
    public int entranceHp { get; }
    public int entranceMp { get; }
	
    public PrintBattleInfo(int entranceHp, int entranceMp)
    {
        this.entranceHp = entranceHp;
        this.entranceMp = entranceMp;
    }
    
	// 전투 과정 출력 대기
    public void WaitBattleProgress()
    {
        Console.WriteLine("계속하려면 아무 키나 입력해주세요.");
        Console.ReadKey();
    }
	
    // 플레이어 정보 출력 (전투 중)
    public void PrintPlayerInfo(Player player)
    {
        Console.WriteLine("[내정보]");
        Console.WriteLine($"Lv. {player.state.Level} {player.state.Name} ({player.GetType().Name})");
        Console.WriteLine($"HP {player.state.CurHp}/{player.state.MaxHp}");
        Console.WriteLine($"MP {player.state.CurMp}/{player.state.MaxMp}");
    }
	
    // 플레이어 정보 출력 (전투 결과)
    public void PrintPlayerInfoEndBattle(Player player)
    {
        Console.WriteLine($"Lv.{player.state.Level} {player.state.Name}");
        Console.WriteLine($"HP {entranceHp} -> {player.state.CurHp}");
        Console.WriteLine($"MP {entranceMp} -> {player.state.CurMp}");
    }
	
    // 몬스터 정보 출력
    public void PrintMonsterInfo(List<Monster> monsters, bool useNum)
    {
        if (useNum)
        {
            int num = 1;

            for (int i = 0; i < monsters.Count; i++)
            {
                if (monsters[i].state.CurHp != 0)
                    Console.WriteLine($"[{num}] Lv. {monsters[i].state.Level} {monsters[i].state.Name} HP {monsters[i].state.CurHp}");
                else
                    Console.WriteLine($"[{num}] Lv. {monsters[i].state.Level} {monsters[i].state.Name} Dead");
                num++;
            }
        }

        else
        {
            foreach (var monster in monsters)
            {
                if (monster.state.CurHp != 0)
                    Console.WriteLine($"Lv. {monster.state.Level} {monster.state.Name} HP {monster.state.CurHp}");
                else
                    Console.WriteLine($"Lv. {monster.state.Level} {monster.state.Name} Dead");
            }
        }
    }
    
    // 보상 정보 출력
    public void PrintRewardInfo(Reward reward)
    {
        Console.WriteLine($"Exp {reward.Exp}");
        Console.WriteLine($"Gold {reward.Gold}");
        if (reward.Items.Count > 0)
        {
            foreach (var item in reward.Items)
                Console.WriteLine($"{item.Name} x 1");
        }
    }
}

💼 ItemManager.cs

아이템 관련 메서드도 읽기에 복잡했던 부분을 분할하여 정리했다.

📃 이전 코드

//아이템 보유 및 착용, 해제 기능 일체화
public void EquipItemByIndex(int index)
{
    if (index < 0 || index >= Items.Count)
    {
        Console.WriteLine("잘못된 인덱스입니다.");
        return;
    }

    var item = Items[index];

    if (!item.IsOwned)
    {
        Console.WriteLine($"{item.Name}은(는) 보유 중이지 않습니다.");
        return;
    }

    var itemType = item.Stats.Keys.First();

    if (item.IsEquipped)
    {
        Console.WriteLine($"{item.Name}은(는) 이미 장착 중입니다.");
        return;
    }

    if (itemType == Item.ItemType.WeaPon)
    {
        if (equippedWeapon != null)
        {
            equippedWeapon.ChangeEquipStatus(false);
            Console.WriteLine($"기존 무기 {equippedWeapon.Name} 장착 해제.");
        }

        equippedWeapon = item;
    }
    else if (itemType == Item.ItemType.Armor)
    {
        if (equippedArmor != null)
        {
            equippedArmor.ChangeEquipStatus(false);
            Console.WriteLine($"기존 방어구 {equippedArmor.Name} 장착 해제.");
        }

        equippedArmor = item;
    }

    item.ChangeEquipStatus(true);
    Console.WriteLine($"{item.Name} 장착 완료!");
}

📝 변경 코드

public void EquipItemByIndex(int index)
{
    if (index < 0 || index >= Items.Count)
    {
        Console.WriteLine("잘못된 인덱스입니다.");
        return;
    }

    var item = Items[index];

    if (item.IsEquipped)
        DeEquipmentItem(item);
    else
        EquipmentItem(item);
}

// 아이템 장착
private void EquipmentItem(Item item)
{
    switch (item.itemType)
    {
        case Item.ItemType.Weapon:
            if (equippedWeapon != null)
            {
                // 장착된 무기가 있다면 해제
                equippedWeapon.ChangeEquipStatus(false);
                player.DequimentItem(equippedWeapon);
            }

            // 현재 장착 무기 변경
            equippedWeapon = item;
            break;

        case Item.ItemType.Armor:
            if (equippedArmor != null)
            {
                // 장착된 방어구가 있다면 해제
                equippedArmor.ChangeEquipStatus(false);
                player.DequimentItem(equippedArmor);
            }

            // 현재 장착 방어구 변경
            equippedArmor = item;
            break;
    }
    Console.WriteLine($"{item.Name}을(를) 장착");

    // 플레이어 아이템 착용
    player.EquimentItem(item);
    item.ChangeEquipStatus(true);
}

// 아이템 장착해제
private void DeEquipmentItem(Item item)
{
    switch (item.itemType)
    {
        case Item.ItemType.Weapon:
            if (item == equippedWeapon)
                equippedWeapon = null;
            break;

        case Item.ItemType.Armor:
            if (equippedArmor == item)
                equippedArmor = null;
            break;
    }

    Console.WriteLine($"{item.Name}을(를) 장착 해제");
    player.DequimentItem(item);
    item.ChangeEquipStatus(false);
}

코드는 더 길어졌지만 역할을 분할하여 보기도 쉽고, 유지보수에 용이하게 작성했다.


🧠 느낀점

TextRpg가 마무리를 해가면서 서로 다른 사람이 작업했던 것을 합치며 진행하다보니 예상치 못한 부분에서 오류가 나고 하는 부분들이 있는거 같다. 그래도 우리 팀원분들을 다같이 열심히 최대한 코드의 병합을 고려해서 코드 작성을 해주셔서 원활하게 흘러가는거 같다.
이제 더 디테일을 잡아보며 끝까지 달려보려고 한다!!

오늘도 내일도 화이팅

profile
Unity, C#

0개의 댓글