본문 바로가기

내일배움캠프_TIL

8월 28일 TIL

C# 4주차 강의 과제 : TRPG 구현하기

public interface ICharacter
    {
        string Name { get; }
        int Health { get; set; }
        int Attack { get; }
        bool IsDead { get; }
        void TakeDamage(int damage);
    }

플레이어 구현에 필요한 멤버들을 인터페이스로 선언하고 직업 클래스에서 구현하도록 한다

public class Warrior : ICharacter
    {
        public string Name { get; }
        public int Health { get; set; }
        public int AttackPower { get; set; }
        public bool IsDead => Health <= 0;
        public int Attack => new Random().Next(10, AttackPower); // 공격력은 랜덤

        public Warrior(string name) // 초기화
        {
            Name = name;
            Health = 100;
            AttackPower = 20;
        }

        public void TakeDamage(int damage)
        {
            Health -= damage;
            if (IsDead) Console.WriteLine($"{Name}이(가) 죽었습니다.");
            else Console.WriteLine($"{Name}이(가) {damage}의 대미지를 받았습니다.\n남은 체력: {Health}");
        }
    }

인터페이스의 멤버들을 구현해주고 생성자에서 이름, 체력, 공격력을 초기화한다

    public class Monster : ICharacter
    {
        public string Name { get; }
        public int Health { get; set; }
        public int Attack => new Random().Next(10, 20);
        public bool IsDead => Health <= 0;

        public Monster(string name, int health)
        {
            Name = name;
            Health = health;
        }

        public void TakeDamage(int damage)
        {
            Health -= damage;
            if (IsDead) Console.WriteLine($"{Name}이(가) 죽었습니다.");
            else Console.WriteLine($"{Name}이(가) {damage}의 대미지를 받았습니다. 남은 체력: {Health}");
        }
    }

몬스터 클래스도 인터페이스를 상속받아 멤버를 구현해주고 생성자에서 초기화한다

public class Goblin : Monster
    {
        public Goblin(string name) : base(name, 50) { }
    }
    
    public class Dragon : Monster
    {
        public Dragon(string name) : base(name, 100) { }
    }

몬스터 클래스를 상속받는 자식클래스 고블린과  드래곤을 만든다

    public interface IItem
    {
        string Name { get; }
        void Use(Warrior warrior);// 전사에게 아이템을 사용하는 메서드
    }

아이템 인터페이스를 만든다

    public class HealthPotion : IItem
    {
        public string Name => "체력 포션";

        public void Use(Warrior warrior)
        {
            Console.WriteLine("체력 포션을 사용합니다. 체력이 50 증가합니다.");
            warrior.Health += 50;
            if (warrior.Health > 100) warrior.Health = 100;
        }
    }

아이템 인터페이스를 상속받은 체력 포션 클래스를 만들어 체력회복 기능을 구현한다

    public class StrengthPotion : IItem
    {
        public string Name => "공격력 포션";

        public void Use(Warrior warrior)
        {
            Console.WriteLine("공격력 포션을 사용합니다. 공격력이 10 증가합니다.");
            warrior.AttackPower += 10;
        }
    }

마찬가지로 공격력 포션 클래스를 만들어 구현한다

    public class Stage
    {
        private ICharacter player;
        private ICharacter monster;
        private List<IItem> reward;

        //이벤트 델리게이트 정의
        public delegate void GameEvent(ICharacter character);
        public event GameEvent OnCharacterDeath;

        public Stage(ICharacter player, ICharacter monster, List<IItem> reward)
        {
            this.player = player;
            this.monster = monster;
            this.reward = reward;
            OnCharacterDeath += StageClear;
        }
    }

스테이지 클래스를 만들어 이벤트 델리케이트를 정의한다

        public void Start()
        {
            Console.WriteLine($"스태이지 시작!\n플레이어 정보\n체력: {player.Health}\n 공격력: {player.Attack}");
            Console.WriteLine($"몬스터 정보\n이름: {monster.Name}\n체력: {monster.Health}\n 공격력: {monster.Attack}");
            Console.WriteLine($"─────────────────────────────────────────────────────────────────────────────────");

            while (!player.IsDead && !monster.IsDead)
            {
                Console.WriteLine($"{player.Name}의 턴!");
                monster.TakeDamage(player.Attack);
                Thread.Sleep(1000);

                if (monster.IsDead) break;

                Console.WriteLine($"{monster.Name}의 턴!");
                player.TakeDamage(monster.Attack);
                Thread.Sleep(1000);
            }

            if (player.IsDead) OnCharacterDeath?.Invoke(player);
            else if (monster.IsDead) OnCharacterDeath?.Invoke(monster);
        }

스타트 클래스에서 플레이어와 몬스터 정보를 출력하고 둘 중 하나가 죽을때까지 전투 턴을 반복한다

private void StageClear(ICharacter character)
        {
            if (character is Monster)
            {
                Console.WriteLine($"스테이지 클리어! {character.Name}을(를) 물리쳤습니다!");
                if (reward != null)
                {
                    Console.WriteLine("아래의 보상 아이템 중 하나를 선택하여 사용할 수 있습니다.");
                    foreach (var item in reward) Console.WriteLine(item.Name);
                    Console.WriteLine("사용할 아이템 이름을 입력하세요");
                    string input = Console.ReadLine();
                    IItem selectedItem = reward.Find(item => item.Name == input);
                    if (selectedItem != null) selectedItem.Use((Warrior)player);
                }

                player.Health = 100;
            }
            else Console.WriteLine("게임 오버! 패배했습니다...");
        }

스테이지 클리어 메서드에서 클리어 후 보상 선택과 사용 기능을 구현한다

    class Game
    {
        static void Main(string[] args)
        {
            Warrior player = new Warrior("Player");
            Goblin goblin = new Goblin("Goblin");
            Dragon dragon = new Dragon("Dragon");

            List<IItem> stage1Rewards = new List<IItem>
            {
                new HealthPotion(),
                new StrengthPotion()
            };
            List<IItem> stage2Rewards = new List<IItem>
            {
                new HealthPotion(),
                new StrengthPotion()
            };

            Stage stage1 = new Stage(player, goblin, stage1Rewards);
            stage1.Start();

            if (player.IsDead) return;

            Stage stage2 = new Stage(player, dragon, stage2Rewards);
            stage2.Start();

            if (player.IsDead) return;

            Console.WriteLine("축하합니다! 모든 스테이지를 클리어했습니다!");
        }
    }

게임 클래스에서 최종적으로 만든 클래스로 객체를 생성하고 메서드들을 호출하여 게임을 완성한다

'내일배움캠프_TIL' 카테고리의 다른 글

8월 30일 TIL  (0) 2023.08.30
8월 29일 TIL  (0) 2023.08.29
8월 25일 TIL  (0) 2023.08.25
8월 24일 TIL  (0) 2023.08.24
8월 23일 TIL  (0) 2023.08.23