PluginBase.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. 
  2. namespace Yuuna.Contracts.Plugins
  3. {
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Collections.Immutable;
  7. using System.Linq;
  8. using System.Runtime.CompilerServices;
  9. using System.Text;
  10. using Yuuna.Contracts.Interaction;
  11. using Yuuna.Contracts.Optimization;
  12. using Yuuna.Contracts.Patterns;
  13. using Yuuna.Contracts.Semantics;
  14. using Yuuna.Contracts.TextSegmention;
  15. using Yuuna.Contracts.Utilities;
  16. public sealed class Fake : PluginBase
  17. {
  18. protected override void BuildPatterns(IGroupManager g, IPatternBuilder p)
  19. {
  20. g.Define("open").AppendOrCreate(new[] { "打開", "開" });
  21. g.Define("door").AppendOrCreate(new[] { "門", "房間門" });
  22. g.Define("light").AppendOrCreate(new[] { "燈", "檯燈" });
  23. //g.Define("browser").AppendOrCreate(new[] { "瀏覽器", "chrome" });
  24. p.Build(g["open"], g["door"]).OnInvoke(score =>
  25. {
  26. var DOOR = new { IS_OPENED = new[] { true, false, true, false }.RandomTakeOne() };
  27. // 開門
  28. if (!DOOR.IS_OPENED)
  29. return (Moods.Happy, "已經開好門囉 <3");
  30. else
  31. return (Moods.Sad, "可是門本來就是開的欸 QAQ");
  32. });
  33. p.Build(g["open"], g["light"]).OnInvoke(score =>
  34. {
  35. var LIGHT = new { IS_OPENED = new[] { true, false,true,false }.RandomTakeOne() };
  36. // 開門
  37. if (!LIGHT.IS_OPENED)
  38. return (Moods.Happy, "已經開好燈囉 <3");
  39. else
  40. return (Moods.Sad, "可是燈本來就是開的欸 QAQ");
  41. });
  42. //p.Build(g["open"], g["browser"]).OnInvoke(score =>
  43. //{
  44. // var DOOR = new { IS_OPENED = true };
  45. // // 開門
  46. // if (!DOOR.IS_OPENED)
  47. // return (Moods.Happy, "已經開好門囉 <3");
  48. // else
  49. // return (Moods.Sad, "可是門本來就是開的欸 QAQ");
  50. //});
  51. }
  52. }
  53. public class PluginHub
  54. {
  55. public PluginHub()
  56. {
  57. }
  58. public static void Main(string[] args)
  59. {
  60. // Send("打開門");
  61. // Send("開燈");
  62. // Send("打開燈");
  63. }
  64. public static void Send(string text)
  65. {
  66. ITextSegmenter segmenter = new JiebaTextSegmenter();
  67. var allPlugins = new PluginBase[] { new Fake() };
  68. foreach (var item in allPlugins)
  69. {
  70. item.Initialize(segmenter);
  71. Console.WriteLine("已載入模組: "+item.GetType().AssemblyQualifiedName);
  72. }
  73. Console.WriteLine("我: " + text);
  74. var cutted = segmenter.Cut(text);
  75. Console.WriteLine($"來自分詞器 {segmenter.Name} 的分詞結果: [ {string.Join(", ",cutted)} ]");
  76. var strategy = new DefaultStrategy();
  77. var list = new List<IScore>();
  78. foreach (var p in allPlugins)
  79. list.AddRange(p.Evaluate(strategy, cutted));
  80. list.Sort(ScoreComparer.Default);
  81. var sb = new StringBuilder("Bot: ");
  82. var best = list.LastOrDefault();
  83. if (best is null)
  84. sb.Append("我不懂你的意思");
  85. else if (best.IsCompacted)
  86. {
  87. var resp = best.Plugin.SelectBest(best).Invoke(best);
  88. Console.WriteLine( resp.Mood.ToString());
  89. sb.Append(resp.Message);
  90. }
  91. else
  92. {
  93. var choices = list.Where(s => s.Missing.Count <= 1).ToImmutableArray();
  94. switch (choices.Length)
  95. {
  96. case 1:
  97. {
  98. sb.Append("你" + new[] { "是想", "想要" }.RandomTakeOne() + " ");
  99. sb.Append(choices.Select(x => x.Contrast.ToImmutable().Aggregate(string.Empty, (s, g) => s += g.ToImmutable().RandomTakeOne().ToImmutable().RandomTakeOne())));
  100. sb.Append(" 嗎?");
  101. }
  102. break;
  103. case 2:
  104. {
  105. sb.Append("你" + new[] { "是想", "想要" }.RandomTakeOne() + " ");
  106. sb.AppendJoin(" 還是 ", choices.Select(x => x.Contrast.ToImmutable().Aggregate(string.Empty, (s, g) => s += g.ToImmutable().RandomTakeOne().ToImmutable().RandomTakeOne())));
  107. sb.Append(" ?");
  108. }
  109. break;
  110. default:
  111. sb.Append("我不太清楚你想做什麼");
  112. break;
  113. }
  114. }
  115. Console.WriteLine(sb);
  116. }
  117. }
  118. public abstract class PluginBase
  119. {
  120. private readonly PatternBuilder _grammarSet;
  121. private readonly GroupManager _groupManager;
  122. public PluginBase()
  123. {
  124. this._grammarSet = new PatternBuilder();
  125. this._groupManager = new GroupManager();
  126. }
  127. protected virtual void PreInitialize(ITextSegmenter segmenter)
  128. {
  129. }
  130. internal void Initialize(ITextSegmenter textSegmenter)
  131. {
  132. this.PreInitialize(textSegmenter);
  133. this.BuildPatterns(this._groupManager, this._grammarSet);
  134. textSegmenter.Load(this._groupManager);
  135. this.OnInitialize();
  136. }
  137. protected virtual void OnInitialize()
  138. {
  139. }
  140. protected abstract void BuildPatterns(IGroupManager groupManager, IPatternBuilder grammarBuilder);
  141. internal IImmutableList<IScore> Evaluate(StrategyBase strategy, IImmutableList<string> cutted)
  142. {
  143. return strategy.Assess(this, cutted, this._grammarSet);
  144. }
  145. internal Behaviour SelectBest(IScore score)
  146. {
  147. return this._grammarSet.TryGet(score.Contrast, out var b) ? b : null;
  148. }
  149. }
  150. }