public void CombineAdd(CardCombine c, int point) { for (int i = 0; i < combines.Count; i++) { if (combines[i] == c) { Debug.Log("same"); combines[i].bias += point; return; } } c.bias += point; combines.Add(c); }
public void Combine(Deck.CombineMethod method) { int index = 0; CardCombine combine = deck.Combine(method); List <CardOnDeck> list = deck.Sort(); foreach (CardGroup group in combine.members) { if (index < 14 && (index + group.members.Count) > 13) { while (index < 14) { deck.slots[index] = null; index++; } } foreach (CardOnDeck card in group.members) { list.Remove(card); deck.slots[index] = card.card; index++; } deck.slots[index] = null; index++; } while (index < 28) { deck.slots[index] = null; index++; } while (list.Count > 0) { index--; CardOnDeck card = list.Last(); list.Remove(card); deck.slots[index] = card.card; } }
// 카드 이름 입력 완료 public void Typed() { // 카드 이름 저장하는 함수 if (input.text == "" || input.text.Trim() == "") { Debug.Log("none of text"); } else if (selectedCards.Count == 1) { // 선택한 카드가 하나일 경우 -> 카드의 조합형만 저장 int i = System.Convert.ToInt32(selectedCards[0].name.Split('_')[1]), j = System.Convert.ToInt32(selectedCards[0].name.Split('_')[2]); if (GameManager.instance.cards[i - 1][j - 1].name == "") { GameManager.instance.cards[i - 1][j - 1].name = input.text; } CardCombine cc = new CardCombine(input.text, false, -1, false, input.text.Trim()); GameManager.instance.cards[i - 1][j - 1].CombineAdd(cc, 3); } else { // 선택한 카드가 여러 개일 경우 GameManager.instance.MultiCardLearning(selectedCards, input.text, false); } // 후처리 foreach (var c in selectedCards) { c.GetComponent <Card>().Unselect(); } selectedCards.Clear(); input.gameObject.SetActive(false); message.text = "낱말카드를 선택하세요"; message.GetComponent <TextBlinking>().enable = true; cardCam.gameObject.SetActive(false); input.text = ""; GameManager.instance.SaveData(); }
// 문장 학습 결과 public void Result(int a) { switch (a) { case 0: // OK resultWindow.SetActive(false); for (int i = 0; i < selectedCards.Count; i++) { int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); int mf = -1, mr = -1; if (i != 0) { mf = System.Convert.ToInt32(selectedCards[i - 1].name.Split('_')[1]); } else if (i != selectedCards.Count - 1) { mr = System.Convert.ToInt32(selectedCards[i + 1].name.Split('_')[1]); } if (selectedCards.Count == 1) { break; } if (i != 0) // 앞쪽 { CardCombine cc = new CardCombine(usedCombines[i].style, true, mf, i == selectedCards.Count - 1, usedCombines[i].root); GameManager.instance.cards[m - 1][n - 1].CombineAdd(cc, 5); string front = cc.style.Split(new[] { cc.root }, StringSplitOptions.None)[0].TrimStart(); // 형태소 추가 bool morpfound = false; foreach (Morpheme morp in GameManager.instance.morphemes) { if (morp.name == cc.root) { morpfound = true; if (front != "") { morp.Connects(front, mf, true); } break; } } if (!morpfound) { GameManager.instance.morphemes.Add(new Morpheme(cc.root, m, n)); if (front != "") { GameManager.instance.morphemes[GameManager.instance.morphemes.Count - 1].Connects(front, mf, true); } } } if (i != selectedCards.Count - 1) // 뒷쪽 { CardCombine cc = new CardCombine(usedCombines[i].style, false, mr, false, usedCombines[i].root); GameManager.instance.cards[m - 1][n - 1].CombineAdd(cc, 5); string rear = cc.style.Split(new[] { cc.root }, StringSplitOptions.None)[1].TrimEnd(); // 형태소 추가 bool morpfound = false; foreach (Morpheme morp in GameManager.instance.morphemes) { if (morp.name == cc.root) { morpfound = true; if (rear != "") { morp.Connects(rear, mr, false); } break; } } if (!morpfound) { GameManager.instance.morphemes.Add(new Morpheme(cc.root, m, n)); if (rear != "") { GameManager.instance.morphemes[GameManager.instance.morphemes.Count - 1].Connects(rear, mr, false); } } } } EndofTesting(); break; case 1: // SOSO for (int i = 0; i < selectedCards.Count; i++) { int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); int mf = -1, mr = -1; if (i != 0) { mf = System.Convert.ToInt32(selectedCards[i - 1].name.Split('_')[1]); } else if (i != selectedCards.Count - 1) { mr = System.Convert.ToInt32(selectedCards[i + 1].name.Split('_')[1]); } if (selectedCards.Count == 1) { break; } if (i != 0) // 앞쪽 { CardCombine cc = new CardCombine(usedCombines[i].style, true, mf, i == selectedCards.Count - 1, usedCombines[i].root); GameManager.instance.cards[m - 1][n - 1].CombineAdd(cc, 1); } if (i != selectedCards.Count - 1) // 뒷쪽 { CardCombine cc = new CardCombine(usedCombines[i].style, false, mr, false, usedCombines[i].root); GameManager.instance.cards[m - 1][n - 1].CombineAdd(cc, 1); } } decisions.SetActive(false); reorders.SetActive(true); break; case 2: // NO decisions.SetActive(false); reorders.SetActive(true); break; case 3: // Force Exit resultWindow.SetActive(false); EndofTesting(); break; } }
void MakeSentence() { result = ""; if (usedCombines.Count == 0) { for (int i = 0; i < selectedCards.Count; i++) { usedCombines.Add(new CardCombine()); } } // 선택된 카드가 하나라면 if (selectedCards.Count == 1) { int m = System.Convert.ToInt32(selectedCards[0].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[0].name.Split('_')[2]); resultWindow.transform.GetChild(1).GetComponent <Text>().text = GameManager.instance.cards[m - 1][n - 1].name; usedCombines[0] = new CardCombine(GameManager.instance.cards[m - 1][n - 1].name, true, -1, true, GameManager.instance.cards[m - 1][n - 1].name); return; } for (int i = 0; i < selectedCards.Count; i++) { // 맨 끝인 경우 if (i == 0) { result += orderedCombines[i][selectedCombines[i]].combine.style; usedCombines[i] = orderedCombines[i][selectedCombines[i]].combine; } else if (i == selectedCards.Count - 1) { result += orderedCombines[i * 2 - 1][selectedCombines[i * 2 - 1]].combine.style; usedCombines[i] = orderedCombines[i * 2 - 1][selectedCombines[i * 2 - 1]].combine; } else { CardCombine f = orderedCombines[i * 2 - 1][selectedCombines[i * 2 - 1]].combine; // 앞 CardCombine b = orderedCombines[i * 2][selectedCombines[i * 2]].combine; // 뒤 // 모두 원형 = 둘이 같음 if (f.combinedWith == -2 && b.combinedWith == -2) { result += f.style; usedCombines[i] = f; } // 둘 중 하나가 원형 = 원형 아닌 쪽 else if (f.combinedWith == -2 || b.combinedWith == -2) { result += f.combinedWith == -2 ? b.style : f.style; usedCombines[i] = (f.combinedWith == -2 ? b : f); } else { // 앞과 뒤가 같음 if (f == b) { result += f.style; usedCombines.Add(f); } // 앞과 뒤가 다름 = 가중치가 큰 쪽 else { result += f.bias > b.bias ? f.style : b.style; usedCombines[i] = (f.bias > b.bias ? f : b); } } } } resultWindow.transform.GetChild(1).GetComponent <Text>().text = result; }
// 카드 선택 완료 public void Done() { // 미학습 카드 에러 foreach (var c in selectedCards) { int m = System.Convert.ToInt32(c.name.Split('_')[1]), n = System.Convert.ToInt32(c.name.Split('_')[2]); if (GameManager.instance.cards[m - 1][n - 1].name == "") { cardCanvas.GetComponent <CardCanvas>().TestError(); foreach (var d in selectedCards) { d.GetComponent <Card>().Unselect(); } OnDisable(); return; } } done.SetActive(false); resultWindow.SetActive(true); // 우선순위 리스트 제작 for (int i = 0; i < selectedCards.Count; i++) { // 리스트 생성 준비 orderedCombines.Add(new List <TestCombine>()); if (i > 0 && i < selectedCards.Count - 1) { orderedCombines.Add(new List <TestCombine>()); } int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); string originalName = GameManager.instance.cards[m - 1][n - 1].name; // 리스트에 넣고 정렬 if (i * 2 - 1 != -1) { // 홀수 - 앞 int mf = System.Convert.ToInt32(selectedCards[i - 1].name.Split('_')[1]); // 조합식들 투입 for (int j = 0; j < GameManager.instance.cards[m - 1][n - 1].combines.Count; j++) { if (GameManager.instance.cards[m - 1][n - 1].combines[j].position) { orderedCombines[i * 2 - 1].Add(new TestCombine(GameManager.instance.cards[m - 1][n - 1].combines[j], j)); // 만약 띄어쓰기가 있는 언어인 상황에서 현재 조합식에 띄어쓰기가 없는 경우, 띄어쓰기가 있는 버전도 투입 if (GameManager.instance.spacing && GameManager.instance.cards[m - 1][n - 1].combines[j].style[0] != ' ') { CardCombine c = GameManager.instance.cards[m - 1][n - 1].combines[j]; CardCombine cc = new CardCombine(" " + c.style, c.position, c.combinedWith, c.isEnd, c.root); orderedCombines[i * 2 - 1].Add(new TestCombine(cc, -1)); } } } // 원래 이름(-2) 투입 orderedCombines[i * 2 - 1].Add(new TestCombine(new CardCombine( GameManager.instance.GetSpacing() ? " " + originalName : originalName, true, -2, i == selectedCards.Count - 1 ? true : false, originalName), -1)); orderedCombines[i * 2 - 1].Sort(delegate(TestCombine x, TestCombine y) { // 맞는 -> 다른 -> -2 // end는 상황에 따라 최상위 or 최하위 if (x.combine.isEnd && !y.combine.isEnd) { return(i == selectedCards.Count - 1 ? -1 : 1); } else if (!x.combine.isEnd && y.combine.isEnd) { return(i == selectedCards.Count - 1 ? 1 : -1); } if (x.combine.combinedWith == -2 && x.combine.combinedWith != -2) { return(1); } else if (x.combine.combinedWith != -2 && x.combine.combinedWith == -2) { return(-1); } if (x.combine.combinedWith == mf && y.combine.combinedWith != mf) { return(-1); } else if (x.combine.combinedWith != mf && y.combine.combinedWith == mf) { return(1); } else { return(x.combine.bias.CompareTo(y.combine.bias) * -1); } }); // 현재 조합 관계가 아닌 것들 중에서 중복된 게 있을 경우 제거 List <string> exist = new List <string>(); List <TestCombine> remove = new List <TestCombine>(); foreach (var tc in orderedCombines[i * 2 - 1]) { if (!exist.Contains(tc.combine.style)) { exist.Add(tc.combine.style); } else { if (tc.combine.combinedWith != mf) { remove.Add(tc); } } } foreach (var r in remove) { orderedCombines[i * 2 - 1].Remove(r); } foreach (var tc in orderedCombines[i * 2 - 1]) { print(tc.combine.ToString()); } } if (i * 2 < (selectedCards.Count - 1) * 2) { // 짝수 - 뒤 int mr = System.Convert.ToInt32(selectedCards[i + 1].name.Split('_')[1]); // 조합식들 투입 for (int j = 0; j < GameManager.instance.cards[m - 1][n - 1].combines.Count; j++) { if (!GameManager.instance.cards[m - 1][n - 1].combines[j].position) { orderedCombines[i * 2].Add(new TestCombine(GameManager.instance.cards[m - 1][n - 1].combines[j], j)); } } // 원래 이름(-2) 투입 orderedCombines[i * 2].Add(new TestCombine(new CardCombine( i != 0 && GameManager.instance.GetSpacing() ? " " + originalName : originalName, false, -2, false, originalName), -1)); orderedCombines[i * 2].Sort(delegate(TestCombine x, TestCombine y) { // 맞는 -> 다른 -> -2 if (x.combine.combinedWith == -2 && x.combine.combinedWith != -2) { return(1); } else if (x.combine.combinedWith != -2 && x.combine.combinedWith == -2) { return(-1); } if (x.combine.combinedWith == mr && y.combine.combinedWith != mr) { return(-1); } else if (x.combine.combinedWith != mr && y.combine.combinedWith == mr) { return(1); } else { return(x.combine.bias.CompareTo(y.combine.bias) * -1); } }); // 현재 조합 관계가 아닌 것들 중에서 중복된 게 있을 경우 제거 List <string> exist = new List <string>(); List <TestCombine> remove = new List <TestCombine>(); foreach (var tc in orderedCombines[i * 2]) { if (!exist.Contains(tc.combine.style)) { exist.Add(tc.combine.style); } else { if (tc.combine.combinedWith != mr) { remove.Add(tc); } } } foreach (var r in remove) { orderedCombines[i * 2].Remove(r); } foreach (var tc in orderedCombines[i * 2]) { print(tc.combine.ToString()); } } // 지난 우선순위 표시기 초기화 reservedCombines.Add(new List <int>()); for (int j = 0; j < 3; j++) { reservedCombines[i].Add(0); } } // 선택된 우선순위 표시기 초기화 foreach (var p in orderedCombines) { selectedCombines.Add(0); } // 문장 만드는 함수 MakeSentence(); }
public TestCombine(CardCombine c, int idx) { combine = c; index = idx; }
// 카드 데이터 불러오기 public void CardLoad() { cards.Clear(); morphemes.Clear(); spacing = false; CardCheck(); FileInfo fi = new FileInfo("cardData" + slot + ".data"); if (!fi.Exists) { FileStream fs = File.Create("cardData" + slot + ".data"); fs.Close(); StreamWriter sw = new StreamWriter("cardData" + slot + ".data"); sw.WriteLine("--------"); sw.Close(); } else { StreamReader sr = new StreamReader("cardData" + slot + ".data"); string s; int g = 0, n = 0; // 카드와 조합식 저장 while ((s = sr.ReadLine()) != "--------") { // 숫자면 해당 번호에 (줄바꿈) 이름 저장 if (char.IsDigit(s[0])) { g = Convert.ToInt32(s.Split(' ')[0]); n = Convert.ToInt32(s.Split(' ')[1]); s = sr.ReadLine(); cards[g - 1][n - 1].name = s; } // "면 지금 번호에 조합식 저장 else if (s[0] == '"') { CardCombine c = new CardCombine(); c.style = s.Split('"')[1]; if (!spacing && c.style[0] == ' ') { spacing = true; } string p = s.Split('"')[2]; c.position = p.Split(' ')[0] == "f" ? true : false; c.combinedWith = Convert.ToInt32(p.Split(' ')[1]); c.bias = Convert.ToInt32(p.Split(' ')[2]); c.position = p.Split(' ')[3] == "e" ? true : false; c.root = p.Split('#')[1]; cards[g - 1][n - 1].combines.Add(c); } // §면 다음 번호로 else if (s[0] == '§') { continue; } } // 형태소 저장 while ((s = sr.ReadLine()) != null) { // §면 다음 번호로 if (s[0] == '§') { continue; } // "면 지금 형태소에 조합 저장 else if (s[0] == '"') { string p = s.Split('"')[1]; string q = s.Split('"')[2]; int b = Convert.ToInt32(q.Split(' ')[1]); MorphemeConnect mc = new MorphemeConnect(); mc.bias = b; string[] k = sr.ReadLine().Split(' '); foreach (string kk in k) { if (kk != "") { mc.connectWith.Add(Convert.ToInt32(kk)); } } if (q.Split(' ')[0] == "f") { morphemes[morphemes.Count - 1].fronts.Add(p, mc); } else { morphemes[morphemes.Count - 1].backs.Add(p, mc); } } // 아니면 새로운 형태소로 저장 else { string name = s; string c = sr.ReadLine(); int group = Convert.ToInt32(c.Split(' ')[0]); int num = Convert.ToInt32(c.Split(' ')[1]); Morpheme mm = new Morpheme(name, group, num); morphemes.Add(mm); } } sr.Close(); } }
// 어근 변형 자동학습 void AutoRoot(int main, int num, int sub, bool dir) { // 현재 카드에서 생성된 어근이 다른 모든 조합식 추출 List <CardCombine> currentCombines = new List <CardCombine>(); // 같은 카드군의 다른 카드에서 현재 카드군 조합의 어근이 다른 조합식 추출 List <CardCombine> otherSameCombines = new List <CardCombine>(); // 같은 카드군의 다른 카드에서 현재 카드군 조합이 아닌 어근이 다른 조합식 추출 List <CardCombine> otherDiffCombines = new List <CardCombine>(); // 조건에 맞는 조합식 추출 // 그 과정에서 현재 카드의 붙는 카드군, 방향이 같은 조합식을 발견하면 모두 가중치를 올려주고 학습 중단 for (int i = 0; i < cards[main - 1].Count; i++) { bool find = false; foreach (CardCombine c in cards[main - 1][i].combines) { if (c.root != cards[main - 1][i].name && c.position == dir) { if (i == num - 1) { if (c.combinedWith == sub) { c.bias++; find = true; } else { currentCombines.Add(c); } } else { if (c.combinedWith == sub) { otherSameCombines.Add(c); } else { otherDiffCombines.Add(c); } } } } if (find) { return; } } // 만약 현재 카드의 어근 변화 사례 또는 다른 카드의 어근 변화 사례가 없으면 학습 미진행 if (otherDiffCombines.Count == 0 || currentCombines.Count == 0) { return; } // 자동학습 // 같은 카드군의 다른 카드에서 생성된 어근 변화 사례 중 현재 카드군과의 조합식 형태가 다른 카드군과의 조합에도 등장하는 경우를 뽑아 리스트를 만들고, // 현재 카드의 어근 변화 사례 중 리스트의 조합식과 조합되는 카드군이 같은 것이 발견될 경우 그 조합식을 현재 카드군 조합으로 학습 List <CardCombine> matchedCombines = new List <CardCombine>(); foreach (CardCombine os in otherSameCombines) { foreach (CardCombine od in otherDiffCombines) { if (os.style == od.style) { matchedCombines.Add(od); } } } foreach (CardCombine mc in matchedCombines) { foreach (CardCombine cc in currentCombines) { if (mc.combinedWith == cc.combinedWith) { CardCombine cn = new CardCombine(cc.style, dir, sub, cc.isEnd, cc.root); cards[main - 1][num - 1].CombineAdd(cn, 1); } } } }
// 구문/문장 학습 public void MultiCardLearning(List <GameObject> selectedCards, string input, bool mode) { int[,] cardRange = new int[selectedCards.Count, 2]; // 조합식 영역 int[,] originalRange = new int[selectedCards.Count, 2]; // 원래 단어 영역 bool[] isOriginal = new bool[selectedCards.Count]; // 조합된 형태가 원본인가?(카드군 자동 학습에 필요) // 2-1. 단어 원본 찾기 - V for (int i = 0; i < selectedCards.Count; i++) { cardRange[i, 0] = -1; cardRange[i, 1] = -1; isOriginal[i] = false; // 초기 상태 int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); // 카드군-번호 따기 string currentName = cards[m - 1][n - 1].name; // 현재 카드 단어 원본 if (currentName == "") // 이름이 없으면 패스 { continue; } for (int j = cardRange[i == 0 ? i : i - 1, 1] + 1; j <= input.Length - currentName.Length; j++) { if (input.Substring(j, currentName.Length) == currentName) // 원본 발견? { cardRange[i, 0] = j; cardRange[i, 1] = j + currentName.Length - 1; isOriginal[i] = true; break; } } } // 2-3. 조합식으로 탐색 - V for (int i = 0; i < selectedCards.Count; i++) { if (cardRange[i, 0] == -1) { int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); foreach (var c in cards[m - 1][n - 1].combines) // 조합식 순회 { string currentName = c.style; // 현재 조합식 if (currentName == "") { continue; } for (int j = cardRange[i == 0 ? i : i - 1, 1] + 1; j <= input.Length - currentName.Length; j++) { if (input.Substring(j, currentName.Length) == currentName) // 조합식 발견? { cardRange[i, 0] = j; cardRange[i, 1] = j + currentName.Length - 1; break; } } if (cardRange[i, 0] != -1) { break; } } } } // 2-4. 한글 종성 체크(맨앞글자) - V for (int i = 0; i < selectedCards.Count; i++) { if (cardRange[i, 0] == -1) { int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); if (cards[m - 1][n - 1].name.Length > 1 && (cards[m - 1][n - 1].name[0] - 44032) % 28 == 0) // 카드 이름이 한 글자 이상이고 맨 앞글자가 받침 없는 한글인가? { string currentName = cards[m - 1][n - 1].name; for (int j = cardRange[i == 0 ? i : i - 1, 1] + 1; j <= input.Length - currentName.Length; j++) { string p = input.Substring(j, currentName.Length); p = ((char)(p[0] - ((p[0] - 44032) % 28))).ToString() + p.Substring(1); if (p == currentName) { cardRange[i, 0] = j; cardRange[i, 1] = j + currentName.Length - 1; break; } } } } } // 2-5. 앞 글자들만 검색 - V for (int i = 0; i < selectedCards.Count; i++) { if (cardRange[i, 0] == -1) { int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); string origin = cards[m - 1][n - 1].name; // 원래 단어 if (origin.Length > 1) { for (int k = 1; k < origin.Length; k++) // 단어 길이 줄여가기 { string cut = origin.Substring(0, origin.Length - k); // 알파벳 1글자면 패스 if (cut.Length == 1 && cut[0] < 256) { break; } for (int j = cardRange[i == 0 ? i : i - 1, 1] + 1; j <= input.Length - cut.Length; j++) { if (input.Substring(j, cut.Length) == cut) { cardRange[i, 0] = j; cardRange[i, 1] = j + cut.Length - 1; break; } } } } } } // 2-6. 전 단어 다음 글자 - V for (int i = 0; i < selectedCards.Count; i++) { if (cardRange[i, 0] == -1) { if (i == 0) { cardRange[i, 0] = cardRange[i, 1] = 0; } else { cardRange[i, 0] = cardRange[i, 1] = cardRange[i - 1, 1] + 1; } } } // 겹친 구역 최종 보정(앞쪽 우선) for (int i = 1; i < selectedCards.Count; i++) { if (cardRange[i, 0] < cardRange[i - 1, 1]) { cardRange[i, 0] = cardRange[i - 1, 1] + 1; if (cardRange[i, 0] > cardRange[i, 1]) { cardRange[i, 1] = cardRange[i, 0]; } } } cardRange[0, 0] = 0; cardRange[selectedCards.Count - 1, 1] = input.Length - 1; // 3-1. 조합형 우측 확장 for (int i = 0; i < selectedCards.Count - 1; i++) { while (input[cardRange[i, 1] + 1] != ' ' && cardRange[i, 1] + 1 != cardRange[i + 1, 0]) { cardRange[i, 1]++; } //if (cardRange[i, 1] > cardRange[i, 0]) // cardRange[i, 1] = cardRange[i, 0]; } // 3-3. 조합형 좌측 확장 for (int i = 1; i < selectedCards.Count; i++) { cardRange[i, 0] = cardRange[i - 1, 1] + 1; } // 저장 for (int i = 0; i < selectedCards.Count; i++) { Debug.LogFormat("{0}:{1}-{2}", i, cardRange[i, 0], cardRange[i, 1]); int s = cardRange[i, 0], l = cardRange[i, 1] - cardRange[i, 0] + 1; if (l <= 0) { continue; } int m = System.Convert.ToInt32(selectedCards[i].name.Split('_')[1]), n = System.Convert.ToInt32(selectedCards[i].name.Split('_')[2]); // 어근 확정 originalRange[i, 0] = originalRange[i, 1] = -1; string origin = cards[m - 1][n - 1].name; bool get = false; if (origin.Length > 1) { for (int k = 0; k < origin.Length; k++) // 단어 길이 줄여가기 { string cut = origin.Substring(0, origin.Length - k); for (int j = originalRange[i == 0 ? i : i - 1, 1] + 1; j <= input.Length - cut.Length; j++) { if (input.Substring(j, cut.Length) == cut) { originalRange[i, 0] = j; originalRange[i, 1] = j + cut.Length - 1; get = true; break; } } if (get) { break; } } } if (originalRange[i, 0] == -1) // 단어로 어근을 찾지 못했다면 전 조합식 뒤의 공백 이후 첫 글자로 찾기 { int ss = s; while (input[ss] == ' ') { ss++; } originalRange[i, 0] = originalRange[i, 1] = ss; } string combine = input.Substring(s, l); // 조합 string root = input.Substring(originalRange[i, 0], originalRange[i, 1] - originalRange[i, 0] + 1); // 어근 string front = combine.Split(new[] { root }, StringSplitOptions.None)[0].TrimStart(); // 앞쪽 형태소 string rear = combine.Split(new[] { root }, StringSplitOptions.None)[1].TrimEnd(); // 뒤쪽 형태소 // 조합식 및 형태소 저장 // 없는 이름 등록 if (cards[m - 1][n - 1].name == "") { cards[m - 1][n - 1].name = (combine[0] == ' ' ? combine.Substring(1) : combine); } // 띄어쓰기 탐지 if (!spacing && combine[0] == ' ') { spacing = true; } // 앞쪽으로 저장 if (i != 0) { int mf = System.Convert.ToInt32(selectedCards[i - 1].name.Split('_')[1]); // 조합식 CardCombine c = new CardCombine(combine, true, mf, mode && i == selectedCards.Count - 1 ? true : false, root); cards[m - 1][n - 1].CombineAdd(c, 2); if (isOriginal[i]) // 유사 형태 형태소 자동학습 - 지금 조합하려는 카드가 원본으로 사용된다면 { for (int j = 0; j < cards[m - 1].Count; j++) // 카드군의 카드 순회하기 { if (j == n - 1 || cards[m - 1][j].name == "") { continue; } string am = AutoMorpheme(m, mf, cards[m - 1][j].name, true); // 붙는 어근에 자동학습 알고리즘 적용 string newstring = (combine[0] == ' ' ? " " : "") + am + cards[m - 1][j].name; if (am == "§") { newstring = combine.Replace(cards[m - 1][n - 1].name, cards[m - 1][j].name); // 초기 학습 상태라면 입력된 조합식을 이용해 초기 자동학습 } CardCombine cn = new CardCombine(newstring, true, mf, mode && i == selectedCards.Count - 1 ? true : false, cards[m - 1][j].name); // 새로운 조합식 cards[m - 1][j].CombineAdd(cn, 1); // 저장 } } else // 변형 어근 자동학습 - 원본으로 사용되지 않는다면 { for (int j = 0; j < cards[m - 1].Count; j++) { if (j != n - 1) { AutoRoot(m, j, mf, true); } } } // 형태소 bool morpfound = false; foreach (Morpheme morp in morphemes) { if (morp.name == root) { morpfound = true; if (front != "") { morp.Connects(front, mf, true); } } } if (!morpfound) { morphemes.Add(new Morpheme(root, m, n)); if (front != "") { morphemes[morphemes.Count - 1].Connects(front, mf, true); } } } // 뒷쪽으로 저장 if (i != selectedCards.Count - 1) { int mr = System.Convert.ToInt32(selectedCards[i + 1].name.Split('_')[1]); // 조합식 CardCombine c = new CardCombine(combine, false, mr, false, root); cards[m - 1][n - 1].CombineAdd(c, 2); if (isOriginal[i]) // 유사 형태 형태소 자동학습 { for (int j = 0; j < cards[m - 1].Count; j++) { if (j == n - 1 || cards[m - 1][j].name == "") { continue; } string am = AutoMorpheme(m, mr, cards[m - 1][j].name, false); // 붙는 어근에 자동학습 알고리즘 적용 string newstring = (combine[0] == ' ' ? " " : "") + cards[m - 1][j].name + am; if (am == "§") { newstring = combine.Replace(cards[m - 1][n - 1].name, cards[m - 1][j].name); // 초기 학습 상태라면 입력된 조합식을 이용해 초기 자동학습 } CardCombine cn = new CardCombine(newstring, false, mr, false, cards[m - 1][j].name); cards[m - 1][j].CombineAdd(cn, 1); } } else // 변형 어근 자동학습 { for (int j = 0; j < cards[m - 1].Count; j++) { if (j != n - 1) { AutoRoot(m, j, mr, false); } } } // 형태소 bool morpfound = false; foreach (Morpheme morp in morphemes) { if (morp.name == root) { morpfound = true; if (rear != "") { morp.Connects(rear, mr, false); } } } if (!morpfound) { morphemes.Add(new Morpheme(root, m, n)); if (rear != "") { morphemes[morphemes.Count - 1].Connects(rear, mr, false); } } } } }