문자열로 조작하는 대화창 만들기

 

 

이 글은 대화창 만들기에서 설명을 드린 곳에 들어간

 

실행기를 만든 전체 CS파일을 복사해서 올려드린 글입니다.

 

설명은 아래에서 보실 수 있습니다.

 

 

[C#] 문자열로 조작 가능! 대화창 만들기!

안녕하십니까. 밤말팅입니다! 저번 시간에는 [은/는] 과 같이 앞 글자에 영향을 받는 조사를 변환시켜 보았는데요! [C#]은는이가 타파!! 자연스러운 문장 만들기! 안녕하십니까 밤말팅입니다! 오

game-part-factory.tistory.com

 

 

스크립트 실행기.zip
0.09MB

using System;
using System.IO;

namespace LineReader
{
    class TextContainer
    {
        public static string[] text;
    }

    class Program
    {
        public static System.Diagnostics.Stopwatch time;

        private static System.Threading.Thread threadKeyRead;

        public static ConsoleKey currentKey = 0;

        static void Main(string[] args)
        {
            time = new System.Diagnostics.Stopwatch();
            time.Start();
            
            threadKeyRead = new System.Threading.Thread(delegate () {
                while (true)
                {
                    currentKey = Console.ReadKey(true).Key;
                };
            });
            threadKeyRead.Start();

            string textFilePath = Directory.GetCurrentDirectory() + @"\CONTEXT.txt";
            if (File.Exists(textFilePath))
            {
                TextContainer.text = File.ReadAllLines(textFilePath);

                TextReader.StartRead(0);
            }
            else
            {
                File.Create(textFilePath);
                Console.WriteLine("파일이 존재하지 않았습니다. 새로 생성된 CONTEXT.txt 파일을 이용하여 새로운 스크립트를 제작해주시기 바랍니다.");
            };

            while (true)
            {
                TextReader.Update();
            };
        }

        public class TextReader
        {
            private static SelectInformation[] currentSelection = new SelectInformation[8];

            public static VariableList globalVariable = new VariableList();

            private static string talkName = "???";
            private static string showText = "";
            private static string receiptText = "";
            private static string calculatedText = "";

            private static long nextTime = 0;

            private static int currentTextIndex = 0;
            private static int currentReadIndex = 0;

            private static int currentSelectionNumber = 0;

            private static int globalReadSpeed = 10;
            private static int currentReadSpeed = 10;

            private static int currentReadPage = 0;
            private static int nextReadPage = 0;

            private static int commandStartIndex = 0;
            private static int commandDepth = 0;

            private static bool reading = false;
            private static bool skip = false;

            public static void Update()
            {
                if (reading)
                {
                    if(currentKey == ConsoleKey.Enter || currentKey == ConsoleKey.Spacebar)
                    {
                        currentKey = 0;
                        skip = true;
                    };

                    OnRead();
                }
                else
                {
                    if(currentKey == ConsoleKey.Enter || currentKey == ConsoleKey.Spacebar)
                    {
                        if(currentSelectionNumber <= 0)
                        {
                            currentKey = 0;
                            StartRead(nextReadPage);
                        };
                    }
                    else if(currentKey == ConsoleKey.A)
                    {
                        ChoiceSelection(0);
                    }
                    else if (currentKey == ConsoleKey.S)
                    {
                        ChoiceSelection(1);
                    }
                    else if (currentKey == ConsoleKey.D)
                    {
                        ChoiceSelection(2);
                    }
                    else if (currentKey == ConsoleKey.F)
                    {
                        ChoiceSelection(3);
                    }
                    else if (currentKey == ConsoleKey.Z)
                    {
                        ChoiceSelection(4);
                    }
                    else if (currentKey == ConsoleKey.X)
                    {
                        ChoiceSelection(5);
                    }
                    else if (currentKey == ConsoleKey.C)
                    {
                        ChoiceSelection(6);
                    }
                    else if (currentKey == ConsoleKey.V)
                    {
                        ChoiceSelection(7);
                    };
                };
            }

            public static void StartRead(int page)
            {
                if (reading)
                {
                    return;
                };

                reading = true;
                skip = false;

                currentReadPage = page;
                nextReadPage = page + 1;

                calculatedText = "";
                showText = "";

                nextTime = 0;

                currentTextIndex = 0;
                currentReadIndex = 0;

                commandStartIndex = 0;
                commandDepth = 0;

                currentReadSpeed = globalReadSpeed;

                if (currentReadPage < TextContainer.text.Length)
                {
                    receiptText = TextContainer.text[currentReadPage];
                }
                else
                {
                    talkName = "<System>";
                    receiptText = "스크립트가 종료되었습니다.";
                    nextReadPage = page;
                };

                string showingName = talkName;
                Console.Clear();
                Console.WriteLine(showingName);
            }

            private static void OnRead()
            {
                if (skip || nextTime <= time.ElapsedMilliseconds)
                {
                    if (currentReadIndex < calculatedText.Length)
                    {
                        showText += calculatedText[currentReadIndex];
                        Console.Write(calculatedText[currentReadIndex]);
                        ++currentReadIndex;

                        nextTime = time.ElapsedMilliseconds + currentReadSpeed;
                    }
                    else if (currentTextIndex < receiptText.Length)
                    {
                        if (receiptText[currentTextIndex] == '[')
                        {
                            commandStartIndex = currentTextIndex;
                            ++currentTextIndex;
                            commandDepth = 1;

                            while (currentTextIndex < receiptText.Length)
                            {
                                if (receiptText[currentTextIndex] == '[')
                                {
                                    ++commandDepth;
                                }
                                else if (receiptText[currentTextIndex] == ']')
                                {
                                    --commandDepth;
                                };

                                if (commandDepth <= 0)
                                {
                                    if (calculatedText.Length - 1 > 0)
                                    {
                                        calculatedText += CommandChecker(calculatedText[calculatedText.Length - 1], receiptText.Substring(commandStartIndex, currentTextIndex - commandStartIndex + 1));
                                    }
                                    else
                                    {
                                        calculatedText += CommandChecker(' ', receiptText.Substring(commandStartIndex, currentTextIndex - commandStartIndex + 1));
                                    };

                                    ++currentTextIndex;

                                    break;
                                }
                                else
                                {
                                    ++currentTextIndex;
                                };
                            };
                        }
                        else
                        {
                            calculatedText += receiptText[currentTextIndex];
                            ++currentTextIndex;
                        };
                    };

                    if (currentTextIndex >= receiptText.Length && currentReadIndex >= calculatedText.Length)
                    {
                        reading = false;
                        skip = false;

                        Console.Write('\n');

                        if (currentSelectionNumber > 0)
                        {
                            Console.WriteLine("A : " + currentSelection[0].context);
                        };
                        if (currentSelectionNumber > 1)
                        {
                            Console.WriteLine("S : " + currentSelection[1].context);
                        };
                        if (currentSelectionNumber > 2)
                        {
                            Console.WriteLine("D : " + currentSelection[2].context);
                        };
                        if (currentSelectionNumber > 3)
                        {
                            Console.WriteLine("F : " + currentSelection[3].context);
                        };
                        if (currentSelectionNumber > 4)
                        {
                            Console.WriteLine("Z : " + currentSelection[4].context);
                        };
                        if (currentSelectionNumber > 5)
                        {
                            Console.WriteLine("X : " + currentSelection[5].context);
                        };
                        if (currentSelectionNumber > 6)
                        {
                            Console.WriteLine("C : " + currentSelection[6].context);
                        };
                        if (currentSelectionNumber > 7)
                        {
                            Console.WriteLine("V : " + currentSelection[7].context);
                        };
                        return;
                    };
                };
            }

            private enum CommandType
            {
                GetVariable,
                Substitute,
                Postposition,
                Condition,
                Select
            }

            private static string CommandChecker(char preText, string targetCommand)
            {
                if (targetCommand.Length <= 2)
                {
                    return "";
                }
                else
                {
                    targetCommand = targetCommand.Substring(1, targetCommand.Length - 2);
                };

                int divideIndex = 0;
                int commandDepth = 0;
                
                CommandType currentCommand = CommandType.GetVariable;

                string returnText = "";

                for (int index = 0; index < targetCommand.Length; ++index)
                {
                    if (targetCommand[index] == '[' || targetCommand[index] == '(')
                    {
                        ++commandDepth;
                    }
                    else if (targetCommand[index] == ']' || targetCommand[index] == ')')
                    {
                        --commandDepth;
                    };

                    if (commandDepth == 0)
                    {
                        if (targetCommand[index] == '/')
                        {
                            currentCommand = CommandType.Postposition;
                            divideIndex = index;
                            break;
                        }
                        else if (targetCommand[index] == ':')
                        {
                            currentCommand = CommandType.Substitute;
                            divideIndex = index;
                            break;
                        }
                        else if (targetCommand[index] == '?')
                        {
                            divideIndex = index;
                            string leftArgument = targetCommand.Substring(0, divideIndex).Trim();
                            if (leftArgument.Length > 0 && leftArgument[0] == '(' && leftArgument[leftArgument.Length - 1] == ')')
                            {
                                currentCommand = CommandType.Select;
                                break;
                            }
                            else
                            {
                                currentCommand = CommandType.Condition;
                                break;
                            };
                        };
                    };
                };

                if (currentCommand == CommandType.Postposition)
                {
                    if (FinalConsonant(preText))
                    {
                        returnText = CommandText(targetCommand.Substring(0, divideIndex).Trim());
                    }
                    else
                    {
                        returnText = CommandText(targetCommand.Substring(divideIndex + 1, targetCommand.Length - divideIndex - 1).Trim());
                    };
                }
                else if (currentCommand == CommandType.Substitute)
                {
                    string arg0 = CommandText(targetCommand.Substring(0, divideIndex).Trim());
                    string arg1 = CommandText(targetCommand.Substring(divideIndex + 1, targetCommand.Length - divideIndex - 1).Trim());

                    if (arg0 == "Speed")
                    {
                        int checkedNumber;

                        if (arg1.Length > 0 && int.TryParse(arg1, out checkedNumber))
                        {
                            currentReadSpeed = checkedNumber;
                        }
                        else
                        {
                            currentReadSpeed = globalReadSpeed;
                        };
                    }
                    else if (arg0 == "TalkName")
                    {
                        ChangeName(arg1);
                    }
                    else if(arg0 == "Wait")
                    {
                        int checkedNumber;

                        if (arg1.Length > 0 && int.TryParse(arg1, out checkedNumber))
                        {
                            nextTime = time.ElapsedMilliseconds + checkedNumber;
                        };
                    }
                    else if(arg0 == "Next")
                    {
                        int checkedNumber;

                        if(arg1.Length > 0 && int.TryParse(arg1, out checkedNumber))
                        {
                            if(arg1[0] == '+' || arg1[0] == '-')
                            {
                                nextReadPage = currentReadPage + checkedNumber;
                            }
                            else
                            {
                                nextReadPage = checkedNumber - 1;
                            };

                            if(nextReadPage < 0)
                            {
                                nextReadPage = 0;
                            };
                        };
                    }
                    else
                    {
                        globalVariable.Set(arg0, arg1);
                    };
                }
                else if (currentCommand == CommandType.GetVariable)
                {
                    if (targetCommand == "Speed")
                    {
                        returnText = Convert.ToString(currentReadSpeed);
                    }
                    else if (targetCommand == "TalkName")
                    {
                        returnText = talkName;
                    }
                    else if(targetCommand == "Next")
                    {
                        returnText = Convert.ToString(nextReadPage);
                    }
                    else if(targetCommand == "Wait")
                    {
                        returnText = null;
                    }
                    else if(targetCommand == "Input")
                    {
                        Console.Write('\n');
                        Console.WriteLine("입력 :");
                        returnText = Console.ReadLine();
                        Console.Clear();
                        Console.WriteLine(talkName);
                        Console.Write(showText);
                    }
                    else
                    {
                        returnText = globalVariable.Get(CommandText(targetCommand));
                    };
                }
                else if(currentCommand == CommandType.Condition)
                {
                    string arg0 = targetCommand.Substring(0, divideIndex).Trim();
                    string arg1 = targetCommand.Substring(divideIndex + 1, targetCommand.Length - divideIndex - 1).Trim();

                    bool conditionCheck = false;

                    if(arg0.Length > 0)
                    {
                        int leftEnd = 0;
                        int rightStart = 0;

                        bool checkEqual = false;
                        bool checkNotEqual = false;
                        bool checkBigger = false;
                        bool checkSmaller = false;

                        for (int index = 0; index < arg0.Length; ++index)
                        {
                            if (arg0[index] == '=')
                            {
                                if(index > 0 && arg0[index - 1] == '!')
                                {
                                    checkNotEqual = true;
                                    if(leftEnd == 0)
                                    {
                                        leftEnd = index - 2;
                                    };
                                    rightStart = index + 1;
                                }
                                else if(!checkNotEqual)
                                {
                                    checkEqual = true;
                                    if (leftEnd == 0)
                                    {
                                        leftEnd = index - 1;

                                        if(leftEnd < 0)
                                        {
                                            leftEnd = 0;
                                        };
                                    };
                                    rightStart = index + 1;
                                };
                            }
                            else if(arg0[index] == '>')
                            {
                                checkBigger = true;
                                if (leftEnd == 0)
                                {
                                    leftEnd = index - 1;
                                };
                                rightStart = index + 1;
                            }
                            else if (arg0[index] == '<')
                            {
                                checkSmaller = true;
                                if (leftEnd == 0)
                                {
                                    leftEnd = index - 1;
                                };
                                rightStart = index + 1;
                            };
                        };

                        if(leftEnd == 0 && rightStart == 0)
                        {
                            if (globalVariable.Get(CommandText(arg0)) != null && globalVariable.Get(CommandText(arg0)).ToLower() != "false")
                            {
                                conditionCheck = true;
                            };
                        }
                        else
                        {
                            string leftText = CommandText(arg0.Substring(0, leftEnd).Trim());
                            string leftValue = globalVariable.Get(leftText);
                            if (leftValue == null)
                            {
                                leftValue = leftText;
                            };

                            string rightText = CommandText(arg0.Substring(rightStart, arg0.Length - rightStart).Trim());
                            string rightValue = globalVariable.Get(rightText);
                            if (rightValue == null)
                            {
                                rightValue = rightText;
                            };

                            if (checkEqual && leftValue == rightValue)
                            {
                                conditionCheck = true;
                            }
                            else if (checkNotEqual && leftValue != rightValue)
                            {
                                conditionCheck = true;
                            };
                            
                            if (checkBigger || checkSmaller)
                            {
                                int leftNumber;
                                int rightNumber;

                                if (int.TryParse(leftValue, out leftNumber) && int.TryParse(rightValue, out rightNumber))
                                {
                                    if (checkBigger && leftNumber > rightNumber)
                                    {
                                        conditionCheck = true;
                                    };

                                    if (checkSmaller && leftNumber < rightNumber)
                                    {
                                        conditionCheck = true;
                                    };
                                };
                            };
                        };
                    }
                    else
                    {
                        conditionCheck = true;
                    };

                    int resultDivideIndex = -4;
                    int rightCommandDepth = 0;
                    for(int index = 0; index < arg1.Length; ++index)
                    {
                        if(arg1[index] == '[')
                        {
                            ++rightCommandDepth;
                        }
                        else if(arg1[index] == ']')
                        {
                            --rightCommandDepth;
                        }
                        else if(arg1[index] == ':' && rightCommandDepth == 0)
                        {
                            resultDivideIndex = index;
                            break;
                        };
                    };

                    if (conditionCheck || resultDivideIndex < 0)
                    {
                        if(resultDivideIndex < 0)
                        {
                            return CommandText(arg1.Trim());
                        }
                        else
                        {
                            return CommandText(arg1.Substring(0, resultDivideIndex).Trim());
                        };
                    }
                    else
                    {
                        return CommandText(arg1.Substring(resultDivideIndex + 1, arg1.Length - resultDivideIndex - 1).Trim());
                    };
                }
                else if(currentCommand == CommandType.Select)
                {
                    string arg0 = targetCommand.Substring(0, divideIndex - 1).Trim();
                    arg0 = arg0.Substring(1, arg0.Length - 2).Trim();
                    string arg1 = targetCommand.Substring(divideIndex + 1, targetCommand.Length - divideIndex - 1).Trim();

                    int rightDivide = 0;
                    int rightCommandDepth = 0;
                    bool rightDivided = false;
                    if(arg1.Length > 0)
                    {
                        for(int index = 0; index < arg1.Length; ++index)
                        {
                            if(arg1[index] == '[')
                            {
                                ++rightCommandDepth;
                            }
                            else
                            {
                                --rightCommandDepth;
                            };

                            if(rightCommandDepth == 0 && arg1[index] == ':')
                            {
                                rightDivided = true;
                                rightDivide = index;
                                break;
                            };
                        };
                    };

                    string onSelect;
                    string notSelect;

                    if (rightDivided)
                    {
                        onSelect = arg1.Substring(0, rightDivide).Trim();
                        notSelect = arg1.Substring(rightDivide + 1, arg1.Length - rightDivide - 1).Trim();
                    }
                    else
                    {
                        onSelect = arg1;
                        notSelect = "";
                    };

                    CreateSelection(arg0, onSelect, notSelect);
                };

                if (returnText == null || returnText.Length <= 0)
                {
                    return null;
                }
                else
                {
                    return CommandText(returnText);
                };
            }

            private static string CommandText(string targetText)
            {
                string returnText = targetText;
                int commandStartIndex = 0;
                int commandDepth = 0;

                string checkedCommand;

                for (int index = 0; index < returnText.Length; ++index)
                {
                    if (returnText[index] == '[')
                    {
                        if(commandStartIndex == 0)
                        {
                            commandStartIndex = index;
                        };
                        ++commandDepth;
                    }
                    else if (returnText[index] == ']')
                    {
                        --commandDepth;
                        if (commandDepth <= 0)
                        {
                            checkedCommand = returnText.Substring(commandStartIndex, index - commandStartIndex + 1);

                            returnText = returnText.Remove(commandStartIndex, index - commandStartIndex + 1);
                            index = commandStartIndex;

                            if (checkedCommand != null)
                            {
                                if (index <= 0)
                                {
                                    index = 0;
                                    returnText = CommandChecker(' ', checkedCommand) + returnText;
                                }
                                else
                                {
                                    if (returnText != null && returnText.Length > 0)
                                    {
                                        returnText = returnText.Insert(index, CommandChecker(returnText[index - 1], checkedCommand));
                                    }
                                    else
                                    {
                                        returnText = CommandChecker(' ', checkedCommand);
                                    };
                                };
                            };
                                
                            commandDepth = 0;
                            commandStartIndex = 0;
                            --index;
                        };
                    };

                    if (returnText == null)
                    {
                        return null;
                    };
                };

                return returnText;
            }

            private static bool FinalConsonant(char wantCharacter)
            {
                if (wantCharacter < 44032 || wantCharacter > 55215)
                {
                    return false;
                };

                int checker = wantCharacter;

                checker -= 44032;

                return (checker % 28) > 0;
            }

            private static void CreateSelection(string wantContext, string wantOnSelect, string wantNotSelect)
            {
                if(currentSelectionNumber < currentSelection.Length)
                {
                    currentSelection[currentSelectionNumber] = new SelectInformation(wantContext, wantOnSelect, wantNotSelect);

                    ++currentSelectionNumber;
                };
            }

            private static void ChoiceSelection(int wantNumber)
            {
                if (!reading && wantNumber < currentSelectionNumber)
                {
                    for(int index = 0; index < currentSelectionNumber; ++index)
                    {
                        if(currentSelection[wantNumber] == null)
                        {
                            break;
                        };

                        if(index == wantNumber)
                        {
                            if(currentSelection[wantNumber].onSelectedAction != null)
                            {
                                CommandText(currentSelection[wantNumber].onSelectedAction);
                            };
                        }
                        else
                        {
                            if (currentSelection[wantNumber].notSelectedAction != null)
                            {
                                CommandText(currentSelection[wantNumber].notSelectedAction);
                            };
                        };

                        currentSelection[index] = null;
                    };

                    currentSelectionNumber = 0;

                    StartRead(nextReadPage);
                };
            }

            private static void ChangeName(string wantName)
            {
                talkName = wantName;

                Console.Clear();
                Console.WriteLine(talkName);
                Console.Write(showText);
            }
        }
    }

    public class SelectInformation
    {
        public string context;
        public string onSelectedAction;
        public string notSelectedAction;

        public SelectInformation(string wantContext, string wantOnSelectedAction, string wantNotSelectedAction)
        {
            context = wantContext;
            onSelectedAction = wantOnSelectedAction;
            notSelectedAction = wantNotSelectedAction;
        }
    }

    public class VariableList
    {
        public Variable start;
        public Variable end;

        public Variable lastContactVariable;

        public int count { get { return realCount; } }
        private int realCount;

        public VariableList()
        {
            start = null;
            end = null;
            lastContactVariable = null;
        }

        public void Set(string wantName, string wantValue)
        {
            Variable target = Find(wantName);

            if(target == null)
            {
                target = new Variable(wantName, wantValue);

                if (end != null)
                {
                    end.next = target;
                }
                else
                {
                    start = target;
                };

                end = target;
                lastContactVariable = target;

                ++realCount;
            }
            else
            {
                target.value = wantValue;
            };
        }

        public string Get(string wantName)
        {
            Variable target = Find(wantName);

            if (target != null)
            {
                return target.value;
            };

            return null;
        }

        public Variable Find(string wantName)
        {
            if (count <= 0)
            {
                return null;
            };

            if (lastContactVariable.name == wantName)
            {
                return lastContactVariable;
            };

            Variable check = start;

            for (int index = 0; index < count; ++index)
            {
                if (check != null)
                {
                    if (check.name == wantName)
                    {
                        lastContactVariable = check;
                        return check;
                    }
                    else
                    {
                        check = check.next;
                    };
                }
                else
                {
                    return null;
                };
            };

            return null;
        }
    }

    public class Variable
    {
        public string name;
        public string value;

        public Variable next;

        public Variable(string wantName, string wantValue)
        {
            name = wantName;
            value = wantValue;
            next = null;
        }
    }
}

'부품 설계도' 카테고리의 다른 글

[C#] 디아블로 스타일 인벤토리 전체 코드  (0) 2020.12.27
[C#]Bit_Builder 전체 코드  (0) 2020.11.15

+ Recent posts