이 글은 대화창 만들기에서 설명을 드린 곳에 들어간
실행기를 만든 전체 CS파일을 복사해서 올려드린 글입니다.
설명은 아래에서 보실 수 있습니다.
[C#] 문자열로 조작 가능! 대화창 만들기!
안녕하십니까. 밤말팅입니다! 저번 시간에는 [은/는] 과 같이 앞 글자에 영향을 받는 조사를 변환시켜 보았는데요! [C#]은는이가 타파!! 자연스러운 문장 만들기! 안녕하십니까 밤말팅입니다! 오
game-part-factory.tistory.com
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 |