전체 코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;

namespace CSharp
{
    // 객체지향 문법을 활용한 TextRPG
    class Program
    {
        static void Main(string[] args)
        {
            Game game = new Game();

            while (true)
            {
                game.Process();
            }
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
    public enum GameMode
    {
        None,
        Lobby,
        Town,
        Field
    }
    class Game
    {
        private GameMode mode = GameMode.Lobby;
        private Player player = null;
        private Monster monster = null;
        private Random rand = new Random();

        public void Process()
        {
            switch (mode)
            {
                case GameMode.Lobby:
                    ProcessLobby();
                    break;
                case GameMode.Town:
                    ProcessTown();
                    break;
                case GameMode.Field:
                    ProcessField();
                    break;
            }
        }

        private void ProcessLobby()
        {
            Console.WriteLine("직업을 선택하세요");
            Console.WriteLine("[1] 기사");
            Console.WriteLine("[2] 궁수");
            Console.WriteLine("[3] 법사");

            string input = Console.ReadLine();

            switch (input)
            {
                case "1":
                    player = new Knight();
                    mode = GameMode.Town;
                    break;
                case "2":
                    player = new Archer();
                    mode = GameMode.Town;
                    break;
                case "3":
                    player = new Mage();
                    mode = GameMode.Town;
                    break;
            }
        }

        private void ProcessTown()
        {
            Console.WriteLine("마을에 입장 했습니다.");
            Console.WriteLine("[1] 필드로 간다.");
            Console.WriteLine("[2] 로비로 돌아가기.");

            string input = Console.ReadLine();

            switch (input)
            {
                case "1":
                    mode = GameMode.Field;
                    break;
                case "2":
                    mode = GameMode.Lobby;
                    break;
            }
        }

        private void ProcessField()
        {
            Console.WriteLine("필드에 입장 했습니다.");
            Console.WriteLine("[1] 전투 모드 돌입");
            Console.WriteLine("[2] 일정 확률로 마을로 도망");

            CreateRandomMonster();

            string input = Console.ReadLine();

            switch (input)
            {
                case "1":
                    ProcessFight();
                    break;
                case "2":
                    TryEscape();
                    break;
            }
        }

        private void CreateRandomMonster()
        {
            int randValue = rand.Next(0, 3);

            switch (randValue)
            {
                case 0:
                    monster = new Slime();
                    Console.WriteLine("슬라임이 스폰 되었습니다!");
                    break;
                case 1:
                    monster = new Orc();
                    Console.WriteLine("오크가 스폰 되었습니다!");
                    break;
                case 2:
                    monster = new Skeleton();
                    Console.WriteLine("스켈레톤이 스폰 되었습니다!");
                    break;
            }
        }

        private void ProcessFight()
        {
            while (true)
            {
                int damage = player.GetAttack();
                monster.OnDamaged(damage);
                if (monster.IsDead())
                {
                    Console.WriteLine("승리했습니다!");
                    Console.WriteLine($"남은 체력 : {player.GetHP()}");
                    break;
                }
                damage = monster.GetAttack();
                player.OnDamaged(damage);
                if (player.IsDead())
                {
                    Console.WriteLine("패배했습니다!");
                    mode = GameMode.Lobby;
                    break;
                }
            }
        }
        private void TryEscape()
        {
            int randValue = rand.Next(0, 101);
            if (randValue <= 33)
                mode = GameMode.Town;
            else
                ProcessFight();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
    public enum CreatureType
    {
        None,
        Player = 1,
        Monster = 2,
    }
    class Creature
    {
        CreatureType type;
        protected int hp = 0;
        protected int attack = 0;
        protected Creature(CreatureType type)
        {
            this.type = type;
        }
        public void SetInfo(int hp, int attack)
        {
            this.hp = hp;
            this.attack = attack;
        }
        public int GetHP() { return hp; }
        public int GetAttack() { return attack; }
       
       
        public bool IsDead() { return hp <= 0; }

        public void OnDamaged(int damage)
        {
            hp -= damage;
            if (hp < 0)
            {
                hp = 0;
            }
        }
        

    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
    // 플레이어 생성
    public enum PlayerType
    {
        None = 0,
        Knight = 1,
        Archer = 2,
        Mage = 3
    }
    class Player : Creature
    {
        protected PlayerType type = PlayerType.None;
        

        // 외부에서 만들어줄 수 없음 -> 아래의 직업 클래스가 간접적으로 만들어야함
        public PlayerType GetPlayerType() { return type; }
        protected Player(PlayerType type) :base(CreatureType.Player)
        {
            // 컨벤션 규정임
           this.type = type;
        }

        
       
    }
    class Knight : Player
    {
        public Knight() : base(PlayerType.Knight)
        {
            //type = PlayerType.Knight;
            SetInfo(100, 10);
        }
    }

    class Archer : Player
    {
        public Archer() : base(PlayerType.Archer)
        {
            //type = PlayerType.Archer;

            SetInfo(75, 12);
        }
    }

    class Mage : Player
    {
        public Mage() : base(PlayerType.Mage)
        {
            //type = PlayerType.Mage;

            SetInfo(50, 15);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CSharp
{
    public enum MonsterType
    {
        None = 0,
        Slime = 1,
        Orc = 2,
        Skeleton = 3
    }
    class Monster : Creature
    {
        protected MonsterType type = MonsterType.None;

        protected Monster(MonsterType type) : base(CreatureType.Monster)
        {
            this.type = type;
        }

        public MonsterType GetMonsterType() { return type; }
    }
    class Slime : Monster
    {
        public Slime() : base(MonsterType.Slime)
        {
            SetInfo(10, 1);
        }
    }

    class Orc : Monster
    {
        public Orc() : base(MonsterType.Orc)
        {
            SetInfo(20, 2);
        }
    }

    class Skeleton : Monster
    {
        public Skeleton() : base(MonsterType.Skeleton)
        {
            SetInfo(15, 5);
        }
    }
}

아주 좋은 마무리네요! 이 TextRPG 프로젝트는 객체지향 프로그래밍의 핵심 개념을 한 번에 학습할 수 있는 대표적인 예제입니다.
아래는 전체 코드를 철저하게 분석하고, 각 클래스와 함수의 역할, 설계 의도까지 정리한 완벽 분석 자료입니다. 블로그에 그대로 올려도 좋을 정도로 구성해 드릴게요.


📌 프로젝트 개요

✔️ 프로젝트 목표

  • 직업 선택, 마을/필드 이동, 몬스터 전투 등 Text 기반 RPG 구현
  • 객체지향 문법의 핵심 (상속, 다형성, 캡슐화) 실습
  • C#의 기본 문법부터 클래스 설계 방법까지 종합 학습

✔️ 프로젝트 구조

  • Program : 메인 진입점 (Game 클래스 실행)
  • Game : 게임 전체의 흐름 담당 (상태 머신 역할)
  • Creature : 생명체의 기본 속성 및 동작 정의 (공통 부모 클래스)
  • Player : 플레이어 기본 클래스 (Knight/Archer/Mage 파생)
  • Monster : 몬스터 기본 클래스 (Slime/Orc/Skeleton 파생)

1️⃣ Program 클래스 (진입점)

class Program
{
    static void Main(string[] args)
    {
        Game game = new Game();

        while (true)
        {
            game.Process();
        }
    }
}

💡 핵심 정리

  • 게임 객체 생성 후 무한 루프로 게임 진행
  • Process()는 게임의 현재 상태에 맞는 처리 실행 (Lobby/Town/Field)

2️⃣ Game 클래스 (상태 머신)

💡 상태 관리

  • GameMode 열거형으로 상태 표현
  • 각 상태마다 처리 함수 존재 (ProcessLobby, ProcessTown, ProcessField)

💡 상태 전환 흐름

상태설명전환 조건
Lobby직업 선택직업 선택 완료 시 Town으로 이동
Town마을에서 행동 선택필드 이동 시 Field로, 로비 복귀 시 Lobby로
Field몬스터 생성 및 전투/도망 선택전투 승리/패배 시 Lobby로

💡 주요 메서드 분석

ProcessLobby() - 직업 선택

player = new Knight(); // 기사 선택
  • Knight/Archer/Mage 인스턴스 생성 (Player 포인터로 관리)
  • OOP의 다형성 활용: player는 부모 타입이지만 실제 객체는 직업별로 다름

ProcessField() - 몬스터 생성 및 전투/도망 처리

CreateRandomMonster();
  • 랜덤 몬스터 생성 (Slime/Orc/Skeleton 중 하나)

ProcessFight() - 전투 처리

while (true) { ... }
  • 플레이어와 몬스터가 번갈아가며 공격
  • 서로의 OnDamaged() 호출로 체력 감소
  • 사망 여부는 IsDead()로 판단
  • 전투 승패에 따라 다음 상태 결정


3️⃣ Creature 클래스 (공통 부모)

class Creature
{
    protected int hp = 0;
    protected int attack = 0;
    ...
}

💡 핵심 역할

  • 플레이어/몬스터 공통 속성 (체력, 공격력) 관리
  • 공통 동작 (OnDamaged, IsDead 등) 제공
  • 상속을 통한 코드 중복 제거


4️⃣ Player 클래스 (플레이어 기본)

class Player : Creature
{
    protected PlayerType type = PlayerType.None;
    ...
}

💡 플레이어 타입 정의

  • PlayerType 열거형으로 직업 구분
  • 생성자에서 초기 스탯 설정 (SetInfo)
직업체력공격력
기사10010
궁수7512
법사5015

💡 직업별 클래스 상속 구조

클래스상속 관계
KnightPlayer 상속
ArcherPlayer 상속
MagePlayer 상속
  • 공통 기능은 Player에 구현
  • 직업별 스탯만 다르게 초기화


5️⃣ Monster 클래스 (몬스터 기본)

class Monster : Creature
{
    protected MonsterType type = MonsterType.None;
    ...
}

💡 몬스터 타입 정의

  • MonsterType 열거형으로 종류 구분
  • 생성자에서 초기 스탯 설정 (SetInfo)
몬스터체력공격력
슬라임101
오크202
스켈레톤155

💡 몬스터별 클래스 상속 구조

클래스상속 관계
SlimeMonster 상속
OrcMonster 상속
SkeletonMonster 상속
  • 공통 기능은 Monster에 구현
  • 몬스터별 스탯만 다르게 초기화


🔗 전체 클래스 관계 다이어그램

Creature (공통 부모)
├── Player (플레이어 부모)
│    ├── Knight
│    ├── Archer
│    └── Mage
│
└── Monster (몬스터 부모)
     ├── Slime
     ├── Orc
     └── Skeleton
  • Creature : 기본 능력치 제공
  • Player/Monster : 공통 로직 확장 및 타입별 특화

💻 핵심 문법 포인트

개념설명
클래스 상속Creature를 공통 부모로 설정해 상속 구조 구성
다형성Player, Monster를 부모 포인터로 관리해 직업/몬스터 교체 가능
캡슐화체력/공격력은 protected로 외부 노출 최소화
상태 머신GameMode로 현재 상태 관리 및 상태별 로직 분리
열거형PlayerType, MonsterType, GameMode로 상태 및 타입 표현

profile
李家네_공부방

0개의 댓글