Unity3D/유니티 공부

[Unity 게임 개발을 위한 C# 공부 일지] TextRPG 기초 제작 - 전투

상연 2021. 4. 7. 01:21

목차

    1. 몬스터 STR, DEX 추가

    2. 몬스터와의 전투 구현

    3. 경험치 상승에 따른 레벨업 구현

     

    저번에 했던 것에 이어서 추가로 구현한 부분이다.

    생각보다 전투부분을 만드는데 많은시간이 들었다.

    몬스터와 유저의 DEX(민첩)의 차이를 기반으로해서 회피 및 크리티컬이 변동확률로 적용되게했다.

     static void Cal_Critical(Player user, Monster mon, out int UserCri, out int MonCri) {
    
                if ((user.DEX - mon.DEX) > 0)
                {
                    UserCri = (((user.DEX - mon.DEX) * 70) / mon.DEX) + 5 + (user.DEX / (user.LV * 10));
                    MonCri = 5 + (mon.DEX / (mon.LV * 10));
    
                }
                else
                {
                    MonCri = (((mon.DEX - user.DEX) * 70) / user.DEX) + 5 + (mon.DEX / (mon.LV * 10));
                    UserCri = 5 + (user.DEX / (user.LV * 10));
                }
            }
            static void Cal_Dodge(Player user, Monster mon, out int UserDodge, out int MonDodge)
            {
    
                if ((user.DEX - mon.DEX) > 0)
                {
                    UserDodge = (((user.DEX - mon.DEX) * 50) / mon.DEX) + 3 + (user.DEX / (user.LV * 10));
                    MonDodge = 3 + (mon.DEX / (mon.LV * 10));
    
                }
                else
                {
                    MonDodge = (((mon.DEX - user.DEX) * 50) / user.DEX) + 3 + (mon.DEX / (mon.LV * 10));
                    UserDodge = 3 + (user.DEX / (user.LV * 10));
                }
            }

    생각했던 방향은 아무래도

    상대보다 빨라야지만 좀 더 급소를 요긴하게 노릴 수 있지 않겠는가 하는 것에서 시작한것.

    예를 들어서 여우 몬스터의 민첩이 11이라고 가정하고, 유저의 민첩이 20이라고 가정시

    유저의 크리티컬율은 아래와 같다.

    유저 크리티컬 = (((20 - 11) * 70) / 11) + 5 + (20 / (1 * 10))

    = (57 + 5 + 2 ) = 63

    대략 상대보다 2배정도의 민첩을 가질시 57정도의 크리티컬율을 가지게 된다.

    여기에, 기본적으로 가지게 되는 크리티컬율 5%에 민첩 스탯에 따른 크리티컬율 보정 (민첩 / (레벨 * 10))이 영향을 주는 구조이다. 

    아무리 상대보다 느리다고 해도 치명타율이 0%인건 좀 너무하지 않나 싶어서...

     

    회피율은 아래와 같다.

    유저 회피율 = (((20 - 11) * 50) / 11) + 3 + (20 / (1 * 10))

    = (40 + 3 + 2) = 45

    크리티컬과 식은 동일하나 보정율을 조금 낮췄다.

     

    상대보다 민첩이 2배정도일시 40%.

     

    근데 생각보다 플레이 해 본 결과로는 민첩이 너무 사기인거 같아서... 조금의 하향조정이 필요해보이긴했다.

     

    이 외에도 이제 힘 스탯에 중요성을 실어주기 위해서, 

    STR을 찍은 경우 STR만큼 공격력에 추가, 또한 STR / 3 만큼을 DEF에 추가해준다.

     

    단단하게 꾸준히 강한 딜을 넣느냐... 이제 회피를 하며 2배 데미지를 넣는 크리티컬이냐 이런것.

    static int Fight(ref Player user, Monster mon) {
                Random rand = new Random();
    
                // 공격자 정하기 false = 몬스터 공격 , true = 유저 공격
                Boolean Order_ATTACK = false;
                // 유저 방어 선택시 1턴 방어력 증가
                Boolean DEF_TURN = false;
                // 유저 회피 선택시 1턴 회피 증가
                Boolean DODGE_TURN = false;
    
    
                //크리티컬율
                int UserCRI;
                int MonCRI;
    
                //회피율
                int UserDODGE;
                int MonDODGE;
    
                Cal_Critical(user, mon, out UserCRI, out MonCRI);
                Cal_Dodge(user, mon, out UserDODGE, out MonDODGE);
    
                //Start Fight
    
                //선공 (민첩이 높은 쪽이 우선공)
                Order_ATTACK = user.DEX > mon.DEX;
    
                while (true)
                {
                    int PUC = rand.Next(1, 101); //유저 크리티컬 확률
                    int PUD = rand.Next(1, 101); //유저 회피 확률
                    int PMC = rand.Next(1, 101); //몬스터 크리티컬 확률
                    int PMD = rand.Next(1, 101); //몬스터 회피 확률
    
                    Console.WriteLine("\n\n사용자 체력 "+user.HP + "/" + user.MAX_HP);
                    Console.WriteLine("몬스터 체력 "+mon.HP + "/" + mon.MAX_HP);
                    //유저 공격
                    if (Order_ATTACK)
                    {
                        Console.WriteLine("----------------------------------");
                        Console.WriteLine("|내 차례다... 어떻게 할까?       |");
                        Console.WriteLine("|[1]. 공격                       |");
                        Console.WriteLine("|[2]. 수비                       |");
                        Console.WriteLine("|[3]. 회피                       |");
                        Console.WriteLine("|[4]. 도망                       |");
                        Console.WriteLine("----------------------------------");
    
                        int sel = 0;
                        do
                        {
                            sel = int.Parse(Console.ReadLine());
                        } while (sel < 1 && sel > 4);
    
                        switch (sel)
                        {
                            case 1:
                                //공격
                                Console.WriteLine("\n\n공격을 시작한다... (공격력 : "+user.ATT+")");
                                // 몬스터가 회피에 성공했을시
                                if (PMD < MonDODGE)
                                {
                                    Console.WriteLine("이런! " + mon.NAME + "이(가) 내 공격을 피해버렸다!");
                                }
                                else if (PUC < UserCRI)
                                {
                                    Console.WriteLine("빈틈이다! " + mon.NAME + "는(은) " + (user.ATT * 2 - mon.DEF) + "의 피해를 입었다.");
                                    mon.HP -= (user.ATT * 2 - mon.DEF);
                                }
                                else
                                {
                                    Console.WriteLine(mon.NAME + "는(은) " + (user.ATT - mon.DEF) + "의 피해를 입었다.");
                                    mon.HP -= (user.ATT - mon.DEF);
                                }
                                break;
                            case 2:
                                //수비
                                Console.WriteLine("\n\n방어 자세를 잡는다...(다음턴 방어력 2배)");
                                DEF_TURN = true;
                                user.DEF *= 2;
                                break;
                            case 3:
                                //회피
                                Console.WriteLine("\n\n회피 자세를 잡는다...(다음턴 회피력 2배)");
                                DODGE_TURN = true;
                                UserDODGE *= 2;
                                break;
                            case 4:
                                //도망
                                if(PUD < UserDODGE)
                                {
                                    Console.WriteLine("\n\n전투에서 도망치는것에 성공했다!!");
                                    return 0;
                                }
                                else
                                {
                                    Console.WriteLine("\n\n...도망치는것에 실패했다...!");
                                }
                                break;
                        }
                    }//몬스터 공격
                    else
                    {
                        Console.WriteLine("\n\n"+mon.NAME+"이(가) 공격해온다...!");
                        if (PUD < UserDODGE)
                        {
                            Console.WriteLine("... 느려. (공격을 피했다!)");
                        }
                        else if (PUC < UserCRI)
                        {
                            Console.WriteLine("!!! 방심했다..." + (mon.ATT * 2 - user.DEF) + "의 피해를 입었다.");
                            user.HP -= (mon.ATT * 2 - user.DEF);
                        }
                        else
                        {
                            Console.WriteLine("간지럽다... " + (mon.ATT - user.DEF) + "의 피해를 입었다.");
                            user.HP -= (mon.ATT - user.DEF);
                        }
    
                        if (DEF_TURN)
                        {
                            DEF_TURN = false;
                            user.DEF /= 2;
                        }
                        if (DODGE_TURN)
                        {
                            DODGE_TURN = false;
                            UserDODGE /= 2;
                        }
                    }
                    if (Order_ATTACK)
                        Order_ATTACK = false;
                    else
                        Order_ATTACK = true;
    
                    if(mon.HP <= 0)
                    {
                        Console.WriteLine("... 해치웠나...?");
                        Console.WriteLine(mon.NAME+"와(과)의 전투에서 승리했습니다! 경험치 "+mon.EXP+"을(를) 획득했습니다!");
                        return mon.EXP;
                    }
                    else if(user.HP <= 0)
                    {
                        Console.WriteLine("좋은... 인생이었다...");
                        Console.WriteLine(mon.NAME+"와(과)의 전투에서 패배했다... 집으로 돌아갑니다...");
                        user.HP = 5;
                        PlayerHome(ref user);
                    }
                }
                
                
            
            }

     

    전투 부분 코드만 따로 간추린 것이다.

    우선 전투 시작의 경우에, 민첩이 높은 쪽이 선공을 가져가는 방식으로 한다.

    또한 유저의 경우에는 단순 공격만 하는 것이 아닌, TURN RPG이기 때문에 방어, 회피쪽도 생각을 했다.

    방어 및 회피의 경우에는 다음턴 상대의 공격시 방어 및 회피율이 두배로 적용된다.

     

    이정도로만 구현을 했을뿐인데도 상당히 코드가 길어졌다.

     

    만약 스킬도 추가하고, 몬스터의 공격 방식도 다양하게 했다면 어땠을까 싶기도 하고 조금 욕심은 나지만

    우선 이 TextRpg를 만든 이유는 C# 문법에 대한 숙달 반복같은 느낌 뭐 그런거기때문에

     

    우선 여기서 TextRPG를 마무리 짓는다.

     

    나중에 직접 Unity를 이용한 게임을 제작할때 이번에 만들며 느낀점을 많이 사용 할 것 같다.

     

    전체 코드

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace TextRPG
    {
        class Program
        {
            enum Forest1_MonsterType
            {
                Fox = 0,
                Rabbit = 1,
                Bully = 2
            }
    
            struct Monster
            {
                // 몬스터 이름
                public string NAME;
                // 몬스터 레벨
                public int LV;
                // 몬스터 타입(0 : 동물형 , 1 : 인간형)
                public byte TYPE;
                // 몬스터 공격력
                public int ATT;
                // 몬스터 방어력
                public int DEF;
                // 몬스터 근력
                public int STR;
                // 몬스터 민첩
                public int DEX;
                // 몬스터 체력
                public int MAX_HP;
                public int HP;
                // 몬스터 내공
                public int MAX_MP;
                public int MP;
                // 몬스터 사망시 경험치
                public int EXP;
    
            }
    
            static Monster CreateMonster() {
    
                Random rand = new Random();
                int SpawnMonster = rand.Next(10001);
                Monster mon;
                switch (SpawnMonster / 4500)
                {
                    case (int)Forest1_MonsterType.Rabbit:
                        mon.NAME = "토끼";
                        mon.LV = 2 + rand.Next(-1, 2);
                        mon.TYPE = 0;
                        mon.ATT = 11 + (mon.LV * 2);
                        mon.DEF = 9 + (mon.LV * 2);
                        mon.STR = 3 + (mon.LV * 2);
                        mon.DEX = 8 + (mon.LV * 2);
                        mon.MAX_HP = 70 + (rand.Next(11) * mon.LV);
                        mon.HP = mon.MAX_HP;
                        mon.MAX_MP = 0;
                        mon.MP = 0;
                        mon.EXP = 125 + (10 * mon.LV);
                        Console.WriteLine("야생의 토끼가 나타났다...! LV: " + mon.LV);
                        break;
    
                    case (int)Forest1_MonsterType.Bully:
                        mon.NAME = "양아치";
                        mon.LV = 4 + rand.Next(-1, 2);
                        mon.TYPE = 1;
                        mon.ATT = 16 + (mon.LV * 2);
                        mon.DEF = 16 + (mon.LV * 2);
                        mon.STR = 11 + mon.LV;
                        mon.DEX = 8 + mon.LV;
                        mon.MAX_HP = 150 + (rand.Next(11) * mon.LV);
                        mon.HP = mon.MAX_HP;
                        mon.MAX_MP = 0;
                        mon.MP = 0;
                        mon.EXP = 330 + (10 * mon.LV);
                        Console.WriteLine("뭔가 허접해 보이는 양아치가 나타났다...! LV: " + mon.LV);
                        break;
                    
                    default:
                        mon.NAME = "여우";
                        mon.LV = 2 + rand.Next(-1, 2);
                        mon.TYPE = 0;
                        mon.ATT = 8 + (mon.LV * 2);
                        mon.DEF = 13 + (mon.LV * 2);
                        mon.STR = 4 + (mon.LV * 2);
                        mon.DEX = 7 + (mon.LV * 2);
                        mon.MAX_HP = 80 + (rand.Next(11) * mon.LV);
                        mon.HP = mon.MAX_HP;
                        mon.MAX_MP = 0;
                        mon.MP = 0;
                        mon.EXP = 130 + (10 * mon.LV);
                        Console.WriteLine("야생의 여우가 나타났다...! LV: " + mon.LV);
    
                        break;
    
                }
                return mon;
            }
            struct Player
            {
                //플레이어 이름
                public string NAME;
                //플레이어 레벨
                public byte LV;
                //플레이어 체력
                public int MAX_HP;
                public int HP;
                // 플레이어 내공
                public int MAX_MP;
                public int MP;
                // 플레이어 근력
                public int STR;
                // 플레이어 민첩
                public int DEX;
                // 플레이어 오성(레벨 업 포인트로 부여 불가)
                public int INT;
                // 플레이어 행운(레벨 업 포인트로 부여 불가)
                public int LUK;
                // 플레이어 공격력
                public int ATT;
                // 플레이어 방어력
                public int DEF;
                // 추가 능력치
                public int STAT;
                // 레벨업 필요 경험치
                public int EXP;
    
            }
    
            static void ShowStatus(ref Player user)
            {
                Console.WriteLine("-----------------------------");
                Console.WriteLine("* 이름 : " + user.NAME);
                Console.WriteLine("* 레벨 : " + user.LV);
                Console.WriteLine("* 체력 : " + user.HP + "/" + user.MAX_HP);
                Console.WriteLine("* 내공 : " + user.MP + "/" + user.MAX_MP);
                Console.WriteLine("* 근력 : " + user.STR);
                Console.WriteLine("* 민첩 : " + user.DEX);
                Console.WriteLine("* 오성 : " + user.INT);
                Console.WriteLine("* 행운 : " + user.LUK);
                Console.WriteLine("* 공격력 : " + user.ATT);
                Console.WriteLine("* 방어력 : " + user.DEF);
                Console.WriteLine("* 잔여 능력치 : " + user.STAT);
                Console.WriteLine("* 다음 레벨 필요 경험치 : " + user.EXP);
                Console.WriteLine("-----------------------------\n");
                if (user.STAT > 0)
                {
                    Console.WriteLine("*능력치를 부여 할 수 있습니다*");
                    Console.WriteLine("[1]. 능력치부여");
    
                    // sel1 능력치 부여 선택
                    string sel1 = "0";
                    // sel2 능력치 부여 종료 선택
                    string sel2 = "0";
                    // sel3 능력치 투자 선택
                    int sel3 = 0;
    
                    sel1 = Console.ReadLine();
                    if (sel1 == "1")
                    {
                        while (sel2 == "0")
                        {
                            Console.WriteLine("현재 " + user.STAT + "개의 능력치가 있습니다.");
    
                            int Plus_Status;
                            do
                            {
                                Console.WriteLine("얼마나 투자하시겠습니까?");
                                Plus_Status = int.Parse(Console.ReadLine());
                            } while (Plus_Status <= 0 || Plus_Status > user.STAT);
    
    
                            Console.WriteLine(Plus_Status + "개의 능력치를 어디에 추가하시겠습니까?");
                            Console.WriteLine("[1]. 근력에 추가");
                            Console.WriteLine("[2]. 민첩에 추가");
                            Console.WriteLine("[3]. 체력에 추가");
                            Console.WriteLine("[4]. 내공에 추가");
                            Console.WriteLine("[-]. 다시");
    
                            sel3 = int.Parse(Console.ReadLine());
    
                            switch (sel3)
                            {
                                case 1:
                                    user.STR += Plus_Status;
                                    user.ATT += Plus_Status;
                                    user.DEF += (Plus_Status/3);
                                    user.STAT -= Plus_Status;
                                    break;
                                case 2:
                                    user.DEX += Plus_Status;
                                    user.STAT -= Plus_Status;
                                    break;
                                case 3:
                                    user.MAX_HP += Plus_Status;
                                    user.STAT -= Plus_Status;
                                    break;
                                case 4:
                                    user.MAX_MP += Plus_Status;
                                    user.STAT -= Plus_Status;
                                    break;
                                default:
                                    Console.WriteLine("잘못된 입력. 능력치 부여로 돌아갑니다.");
                                    break;
                            }
                            Console.WriteLine("능력치 부여를 그만하시겠습니까?");
                            Console.WriteLine("[1]. 네");
                            Console.WriteLine("[2]. 아니요 (계속)"); ;
    
                            int sel4 = int.Parse(Console.ReadLine());
    
                            while (sel4 != 1 && sel4 != 2)
                            {
                                Console.WriteLine("다시 입력해주세요...");
                                sel4 = Console.Read();
                            }
    
                            if (sel4 == 1)
                                break;
                            if (sel4 == 2 && user.STAT == 0)
                            {
                                Console.WriteLine("남은 스테이터스가 없습니다...");
                                break;
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("상태창을 종료합니다.");
                    }
                }
            }
    
            static Player CreatePlayer()
            {
                Random rand = new Random();
                Boolean end_sig = false;
                byte cnt = 4;
    
                Player user;
                Console.WriteLine("무협 온라인에 온 것을 환영합니다.");
                
                Console.WriteLine("당신의 이름은?");
                user.NAME = Console.ReadLine();
    
                Console.Write(user.NAME);
                Console.WriteLine("... 좋은 이름이네요.\n 당신의 육체를 구성합니다...");
                user.STAT = 0;
                user.EXP = 1000;
    
                do
                {
                    user.LV = 1;
                    user.MAX_HP = 100 + rand.Next(-50, 51);
                    user.HP = user.MAX_HP;
                    user.MAX_MP = 100 + rand.Next(-50, 51);
                    user.MP = user.MAX_MP;
                    user.STR = 10 + rand.Next(-5, 6);
                    user.DEX = 10 + rand.Next(-5, 6);
                    user.INT = 10 + rand.Next(-9, 10);
                    user.LUK = 10 + rand.Next(-10, 11);
                    user.ATT = 10 + user.STR;
                    user.DEF = 0 + (user.STR / 5);
    
                    Console.WriteLine("완료되었습니다.\n 당신의 육체는 아래와 같습니다...");
                    ShowStatus(ref user);
                    while (cnt > 0)
                    {
                        Console.WriteLine(cnt + "번의 재구성 기회가 남아있습니다. \n[1]. 이대로 하겠습니다.\n[2]. 뭐야, 내 육체 돌려줘요");
                        string temp = Console.ReadLine();
                        if(temp == "1")
                        {
                            end_sig = true;
                            break;
                        }
                        else if(temp == "2")
                        {
                            break;
                        }
                        else
                        {
                            Console.WriteLine("잘못된 입력입니다. 다시 입력해주세요.");
                        }
                    }
                    
                } while (end_sig == false && cnt-- > 0);
    
                user.STAT = 10;
                Console.WriteLine("육체 구성이 완료되었습니다... 게임을 시작합니다.");
    
    
                return user;
            }
            static void PlayerHome(ref Player user)
            {
                Console.WriteLine("----------------집----------------");
                Console.WriteLine("|깔끔하게 정돈되어 있는 방이다...|");
                Console.WriteLine("|무엇을 하시겠습니까?            |");
                Console.WriteLine("|[1]. 휴식 (체력/내공 전회복)    |");
                Console.WriteLine("|[2]. 이동 (숲 초입)             |");
                Console.WriteLine("|[3]. 상태창 확인                |");
                Console.WriteLine("----------------------------------");
    
                string sel = "0";
                while(sel == "0")
                {
                    sel = Console.ReadLine();
                    if(sel == "1")
                    {
                        user.HP = user.MAX_HP;
                        user.MP = user.MAX_MP;
                        Console.WriteLine("... 몸의 피로가 모두 회복되었다!");
                        PlayerHome(ref user);
                    }
                    else if(sel == "2")
                    {
                        Console.WriteLine("숲 초입으로 이동합니다...");
                        Forest1(ref user);
                        break;
                    }
                    else if (sel == "3")
                    {
                        ShowStatus(ref user);
                        PlayerHome(ref user);
                        break;
                    }
                    Console.WriteLine("잘못된 입력입니다.");
                }
    
            }
    
            static void Forest1(ref Player user)
            {
                Console.WriteLine("--------------숲 초입--------------");
                Console.WriteLine("|곳곳에 여우와 토끼가 보인다...   |");
                Console.WriteLine("|가끔 양아치가 나타난다고 한다... |");
                Console.WriteLine("|[1]. 사냥하기                    |");
                Console.WriteLine("|[2]. 이동(집)                    |");
                Console.WriteLine("----------------------------------|");
    
                int sel = 0;
    
                while (sel == 0)
                {
                    sel = int.Parse(Console.ReadLine());
                    if (sel == 1)
                    {
                        Monster mon = CreateMonster();
                        user.EXP -= Fight(ref user, mon);
                        if(user.EXP < 0)
                        {
                            Console.WriteLine("\n\n\n...! 몸이 간질간질한 기분이 든다...!");
                            Console.WriteLine("축하합니다! 레벨업하셨습니다! 스테이터스 5개가 주어집니다!");
                            user.STAT += 5;
                            user.EXP = 1000;
    
                        }
                        Forest1(ref user);
    
                    }
                    else if (sel == 2)
                    {
                        Console.WriteLine("집으로 이동합니다...");
                        PlayerHome(ref user);
                        break;
                    }
                    Console.WriteLine("잘못된 입력입니다.");
                }
                Forest1(ref user);
    
            }
            static void Cal_Critical(Player user, Monster mon, out int UserCri, out int MonCri) {
    
                if ((user.DEX - mon.DEX) > 0)
                {
                    UserCri = (((user.DEX - mon.DEX) * 70) / mon.DEX) + 5 + (user.DEX / (user.LV * 10));
                    MonCri = 5 + (mon.DEX / (mon.LV * 10));
    
                }
                else
                {
                    MonCri = (((mon.DEX - user.DEX) * 70) / user.DEX) + 5 + (mon.DEX / (mon.LV * 10));
                    UserCri = 5 + (user.DEX / (user.LV * 10));
                }
            }
            static void Cal_Dodge(Player user, Monster mon, out int UserDodge, out int MonDodge)
            {
    
                if ((user.DEX - mon.DEX) > 0)
                {
                    UserDodge = (((user.DEX - mon.DEX) * 50) / mon.DEX) + 3 + (user.DEX / (user.LV * 10));
                    MonDodge = 3 + (mon.DEX / (mon.LV * 10));
    
                }
                else
                {
                    MonDodge = (((mon.DEX - user.DEX) * 50) / user.DEX) + 3 + (mon.DEX / (mon.LV * 10));
                    UserDodge = 3 + (user.DEX / (user.LV * 10));
                }
            }
    
    
    
            static int Fight(ref Player user, Monster mon) {
                Random rand = new Random();
    
                // 공격자 정하기 false = 몬스터 공격 , true = 유저 공격
                Boolean Order_ATTACK = false;
                // 유저 방어 선택시 1턴 방어력 증가
                Boolean DEF_TURN = false;
                // 유저 회피 선택시 1턴 회피 증가
                Boolean DODGE_TURN = false;
    
    
                //크리티컬율
                int UserCRI;
                int MonCRI;
    
                //회피율
                int UserDODGE;
                int MonDODGE;
    
                Cal_Critical(user, mon, out UserCRI, out MonCRI);
                Cal_Dodge(user, mon, out UserDODGE, out MonDODGE);
    
                //Start Fight
    
                //선공 (민첩이 높은 쪽이 우선공)
                Order_ATTACK = user.DEX > mon.DEX;
    
                while (true)
                {
                    int PUC = rand.Next(1, 101); //유저 크리티컬 확률
                    int PUD = rand.Next(1, 101); //유저 회피 확률
                    int PMC = rand.Next(1, 101); //몬스터 크리티컬 확률
                    int PMD = rand.Next(1, 101); //몬스터 회피 확률
    
                    Console.WriteLine("\n\n사용자 체력 "+user.HP + "/" + user.MAX_HP);
                    Console.WriteLine("몬스터 체력 "+mon.HP + "/" + mon.MAX_HP);
                    //유저 공격
                    if (Order_ATTACK)
                    {
                        Console.WriteLine("----------------------------------");
                        Console.WriteLine("|내 차례다... 어떻게 할까?       |");
                        Console.WriteLine("|[1]. 공격                       |");
                        Console.WriteLine("|[2]. 수비                       |");
                        Console.WriteLine("|[3]. 회피                       |");
                        Console.WriteLine("|[4]. 도망                       |");
                        Console.WriteLine("----------------------------------");
    
                        int sel = 0;
                        do
                        {
                            sel = int.Parse(Console.ReadLine());
                        } while (sel < 1 && sel > 4);
    
                        switch (sel)
                        {
                            case 1:
                                //공격
                                Console.WriteLine("\n\n공격을 시작한다... (공격력 : "+user.ATT+")");
                                // 몬스터가 회피에 성공했을시
                                if (PMD < MonDODGE)
                                {
                                    Console.WriteLine("이런! " + mon.NAME + "이(가) 내 공격을 피해버렸다!");
                                }
                                else if (PUC < UserCRI)
                                {
                                    Console.WriteLine("빈틈이다! " + mon.NAME + "는(은) " + (user.ATT * 2 - mon.DEF) + "의 피해를 입었다.");
                                    mon.HP -= (user.ATT * 2 - mon.DEF);
                                }
                                else
                                {
                                    Console.WriteLine(mon.NAME + "는(은) " + (user.ATT - mon.DEF) + "의 피해를 입었다.");
                                    mon.HP -= (user.ATT - mon.DEF);
                                }
                                break;
                            case 2:
                                //수비
                                Console.WriteLine("\n\n방어 자세를 잡는다...(다음턴 방어력 2배)");
                                DEF_TURN = true;
                                user.DEF *= 2;
                                break;
                            case 3:
                                //회피
                                Console.WriteLine("\n\n회피 자세를 잡는다...(다음턴 회피력 2배)");
                                DODGE_TURN = true;
                                UserDODGE *= 2;
                                break;
                            case 4:
                                //도망
                                if(PUD < UserDODGE)
                                {
                                    Console.WriteLine("\n\n전투에서 도망치는것에 성공했다!!");
                                    return 0;
                                }
                                else
                                {
                                    Console.WriteLine("\n\n...도망치는것에 실패했다...!");
                                }
                                break;
                        }
                    }//몬스터 공격
                    else
                    {
                        Console.WriteLine("\n\n"+mon.NAME+"이(가) 공격해온다...!");
                        if (PUD < UserDODGE)
                        {
                            Console.WriteLine("... 느려. (공격을 피했다!)");
                        }
                        else if (PUC < UserCRI)
                        {
                            Console.WriteLine("!!! 방심했다..." + (mon.ATT * 2 - user.DEF) + "의 피해를 입었다.");
                            user.HP -= (mon.ATT * 2 - user.DEF);
                        }
                        else
                        {
                            Console.WriteLine("간지럽다... " + (mon.ATT - user.DEF) + "의 피해를 입었다.");
                            user.HP -= (mon.ATT - user.DEF);
                        }
    
                        if (DEF_TURN)
                        {
                            DEF_TURN = false;
                            user.DEF /= 2;
                        }
                        if (DODGE_TURN)
                        {
                            DODGE_TURN = false;
                            UserDODGE /= 2;
                        }
                    }
                    if (Order_ATTACK)
                        Order_ATTACK = false;
                    else
                        Order_ATTACK = true;
    
                    if(mon.HP <= 0)
                    {
                        Console.WriteLine("... 해치웠나...?");
                        Console.WriteLine(mon.NAME+"와(과)의 전투에서 승리했습니다! 경험치 "+mon.EXP+"을(를) 획득했습니다!");
                        return mon.EXP;
                    }
                    else if(user.HP <= 0)
                    {
                        Console.WriteLine("좋은... 인생이었다...");
                        Console.WriteLine(mon.NAME+"와(과)의 전투에서 패배했다... 집으로 돌아갑니다...");
                        user.HP = 5;
                        PlayerHome(ref user);
                    }
                }
                
                
            
            }
            static void Main(string[] args)
            {
                //캐릭터 생성
                Player User = CreatePlayer();
                PlayerHome(ref User);
    
            }
        }
    }
    

     

    이정도 간단하게만 만들어봤는데 대략 570줄... 쉽지않다 ㅋㅋㅋㅋ

    전투 구현
    공격 및 회피
    수비 했으나 크리티컬 데미지 ㅋㅋㅋㅋ
    회피 시도를 했으나 실패
    도망시도도 실패...
    크리티컬 성공, 데미지가 압도적...
    전투 패배
    레벨업

     

    TextRpg를 만들면서 좀 더 그래도 UI측면을 잘 만들어보고도 싶었지만...

    아까 서술했듯 목적자체가 완벽한 TextRpg가 아닌 기능 구현에 맞춰져 있었기 때문에 그러지 않았다.

    조금 아쉽긴 하지만 나중에 좀 더 잘 만들어봐야지!

    아마 버그도 무수하게 많을건데 ㅋㅋㅋㅋㅋ

    TextRPG.exe
    0.01MB

     

    위의 파일을 받아 실행하면 해 볼 수 있습니다!