namespace Yuuna.Contracts.Plugins { using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using Yuuna.Contracts.Interaction; using Yuuna.Contracts.Optimization; using Yuuna.Contracts.Patterns; using Yuuna.Contracts.Semantics; using Yuuna.Contracts.TextSegmention; using Yuuna.Contracts.Utilities; public sealed class Fake : PluginBase { protected override void BuildPatterns(IGroupManager g, IPatternBuilder p) { g.Define("open").AppendOrCreate(new[] { "打開", "開" }); g.Define("door").AppendOrCreate(new[] { "門", "房間門" }); g.Define("light").AppendOrCreate(new[] { "燈", "檯燈" }); //g.Define("browser").AppendOrCreate(new[] { "瀏覽器", "chrome" }); p.Build(g["open"], g["door"]).OnInvoke(score => { var DOOR = new { IS_OPENED = new[] { true, false, true, false }.RandomTakeOne() }; // 開門 if (!DOOR.IS_OPENED) return (Moods.Happy, "已經開好門囉 <3"); else return (Moods.Sad, "可是門本來就是開的欸 QAQ"); }); p.Build(g["open"], g["light"]).OnInvoke(score => { var LIGHT = new { IS_OPENED = new[] { true, false,true,false }.RandomTakeOne() }; // 開門 if (!LIGHT.IS_OPENED) return (Moods.Happy, "已經開好燈囉 <3"); else return (Moods.Sad, "可是燈本來就是開的欸 QAQ"); }); //p.Build(g["open"], g["browser"]).OnInvoke(score => //{ // var DOOR = new { IS_OPENED = true }; // // 開門 // if (!DOOR.IS_OPENED) // return (Moods.Happy, "已經開好門囉 <3"); // else // return (Moods.Sad, "可是門本來就是開的欸 QAQ"); //}); } } public class PluginHub { public PluginHub() { } public static void Main(string[] args) { // Send("打開門"); // Send("開燈"); // Send("打開燈"); } public static void Send(string text) { ITextSegmenter segmenter = new JiebaTextSegmenter(); var allPlugins = new PluginBase[] { new Fake() }; foreach (var item in allPlugins) { item.Initialize(segmenter); Console.WriteLine("已載入模組: "+item.GetType().AssemblyQualifiedName); } Console.WriteLine("我: " + text); var cutted = segmenter.Cut(text); Console.WriteLine($"來自分詞器 {segmenter.Name} 的分詞結果: [ {string.Join(", ",cutted)} ]"); var strategy = new DefaultStrategy(); var list = new List(); foreach (var p in allPlugins) list.AddRange(p.Evaluate(strategy, cutted)); list.Sort(ScoreComparer.Default); var sb = new StringBuilder("Bot: "); var best = list.LastOrDefault(); if (best is null) sb.Append("我不懂你的意思"); else if (best.IsCompacted) { var resp = best.Plugin.SelectBest(best).Invoke(best); Console.WriteLine( resp.Mood.ToString()); sb.Append(resp.Message); } else { var choices = list.Where(s => s.Missing.Count <= 1).ToImmutableArray(); switch (choices.Length) { case 1: { sb.Append("你" + new[] { "是想", "想要" }.RandomTakeOne() + " "); sb.Append(choices.Select(x => x.Contrast.ToImmutable().Aggregate(string.Empty, (s, g) => s += g.ToImmutable().RandomTakeOne().ToImmutable().RandomTakeOne()))); sb.Append(" 嗎?"); } break; case 2: { sb.Append("你" + new[] { "是想", "想要" }.RandomTakeOne() + " "); sb.AppendJoin(" 還是 ", choices.Select(x => x.Contrast.ToImmutable().Aggregate(string.Empty, (s, g) => s += g.ToImmutable().RandomTakeOne().ToImmutable().RandomTakeOne()))); sb.Append(" ?"); } break; default: sb.Append("我不太清楚你想做什麼"); break; } } Console.WriteLine(sb); } } public abstract class PluginBase { private readonly PatternBuilder _grammarSet; private readonly GroupManager _groupManager; public PluginBase() { this._grammarSet = new PatternBuilder(); this._groupManager = new GroupManager(); } protected virtual void PreInitialize(ITextSegmenter segmenter) { } internal void Initialize(ITextSegmenter textSegmenter) { this.PreInitialize(textSegmenter); this.BuildPatterns(this._groupManager, this._grammarSet); textSegmenter.Load(this._groupManager); this.OnInitialize(); } protected virtual void OnInitialize() { } protected abstract void BuildPatterns(IGroupManager groupManager, IPatternBuilder grammarBuilder); internal IImmutableList Evaluate(StrategyBase strategy, IImmutableList cutted) { return strategy.Assess(this, cutted, this._grammarSet); } internal Behaviour SelectBest(IScore score) { return this._grammarSet.TryGet(score.Contrast, out var b) ? b : null; } } }