/// <summary> /// 从本地和网络查找答案 /// 并转发给对应的ws客户端 /// </summary> /// <param name="session">会话</param> /// <returns></returns> private static async Task SearchAnswerAsync(Session session) { session.utilDecodeRequest(); session.utilDecodeResponse(); var requestBody = Encoding.UTF8.GetString(session.RequestBody); var responseBody = Encoding.UTF8.GetString(session.ResponseBody); var kingQuestion = KingQuestion.Parse(responseBody); if (kingQuestion == null || kingQuestion.IsValidate() == false) { return; } var beginTime = DateTime.Now; var data = await SearchHistoryDataAsync(session, withAnswer); const double offsetSecondes = 3.7d; var delay = beginTime.AddSeconds(offsetSecondes).Subtract(DateTime.Now); var notifyData = new WsNotifyData <WsGameAnswer> { Cmd = WsCmd.GameAnser, Data = new WsGameAnswer { SearchResult = data.SearchResult, GameDelayMSeconds = (int)delay.TotalMilliseconds } }; WsNotifyByClientIP(notifyData, session.clientIP); if (withAnswer == true) { var qData = data.QuestionData; if (data.SearchResult.Best != null) { var index = data.SearchResult.Best.Index; qData.quiz = qData.quiz + $" [{(char)('A' + index)}]"; qData.options[index] = qData.options[index] + "[√]"; } var q = new KingQuestion { data = qData }; var json = JsonConvert.SerializeObject(q); session.utilSetResponseBody(json); } }
/// <summary> /// 从本地和网络查找答案 /// 返回正确选项的索引 /// </summary> /// <param name="session">会话</param> /// <returns></returns> private static int GetOptionIndex(Session session, out KingQuestion kingQuestion) { kingQuestion = KingQuestion.FromSession(session); if (kingQuestion == null || kingQuestion.IsValidate() == false) { return(-1); } KingContextTable.Add(new KingContext { KingQuestion = kingQuestion, KingRequest = KingRequest.FromSession(session) }); // 找答案 return(SearchOptionIndex(kingQuestion)); }
/// <summary> /// 从本地和网络查找答案 /// 并转发给对应的ws客户端 /// </summary> /// <param name="session">会话</param> /// <param name="sync">是否同步</param> /// <returns></returns> private static async Task <HistoryData> SearchHistoryDataAsync(Session session, bool sync) { session.utilDecodeRequest(); session.utilDecodeResponse(); var requestBody = Encoding.UTF8.GetString(session.RequestBody); var responseBody = Encoding.UTF8.GetString(session.ResponseBody); var kingQuestion = KingQuestion.Parse(responseBody); if (kingQuestion == null || kingQuestion.IsValidate() == false) { return(null); } var kingRequest = KingRequest.Parse(requestBody); var title = kingQuestion.data.quiz; var beginTime = DateTime.Now; var history = HistoryDataTable.TryGet(title); if (history == null) { history = new HistoryData { QuestionData = kingQuestion.data, KingRequest = KingRequest.Parse(requestBody), SearchResult = await BaiduSearcher.SearchAsync(kingQuestion, withAnswer) }; HistoryDataTable.TryAdd(history); } var data = JsonConvert.DeserializeObject <HistoryData>(JsonConvert.SerializeObject(history)); data.KingRequest = kingRequest; data.QuestionData = kingQuestion.data; data.SearchResult = history.SearchResult.CreateNewByQuestionData(kingQuestion.data); return(data); }
/// <summary> /// 从正确的答案选项 /// </summary> /// <param name="question">问题</param> /// <returns></returns> public static async Task <SearchResult> SearchAsync(KingQuestion question, bool sync) { // 从badidu找出原始结论 var title = question.data.quiz; var sourceAnswer = sync ? SearchSourceAnswers(title) : await SearchSourceAnswersAsync(title); // 各个选项和结论的匹配次数 var options = question.data.options.Select((item, i) => new OptionMatchs { Index = i, Options = item, Matchs = GetMatchCount(sourceAnswer, item) }).ToArray(); var best = options.OrderByDescending(item => item.Matchs).FirstOrDefault(); if (title.Contains("不") || title.Contains("没")) { // 计算匹配次数平均值,找出和匹配次数均值差异最大的 var avg = options.Average(item => item.Matchs); best = options.OrderByDescending(item => Math.Pow(item.Matchs - avg, 2)).FirstOrDefault(); } var result = new SearchResult { Title = title, Options = options, Best = best }; // 两个相同的结果,表示没有答案 if (options.Any(item => item != best && item.Matchs == best.Matchs)) { result.Best = null; } return(result); }
/// <summary> /// 查找问题答案并保存到db /// </summary> /// <param name="kingQuestion">问题</param> /// <returns></returns> private static int SearchOptionIndex(KingQuestion kingQuestion) { using (var sqlLite = new SqlliteContext()) { var quiz = kingQuestion.data.quiz; var quizAnswer = sqlLite.QuizAnswer.FirstOrDefault(item => item.Quiz == quiz); if (quizAnswer != null) { Console.WriteLine($"从db中找到记录:{Environment.NewLine}{quizAnswer}"); var answer = quizAnswer.Answer?.Trim(); return(Array.FindIndex(kingQuestion.data.options, item => item?.Trim() == answer)); } // 搜索 var best = Searcher.Search(kingQuestion); if (best == null) { Console.WriteLine($"找不到答案:{kingQuestion.data.quiz}"); return(-1); } if (sqlLite.QuizAnswer.Any(item => item.Quiz == quiz) == false) { quizAnswer = new QuizAnswer { Answer = best.Option, Quiz = quiz, OptionsJson = JsonConvert.SerializeObject(kingQuestion.data.options) }; sqlLite.QuizAnswer.Add(quizAnswer); sqlLite.SaveChanges(); Console.WriteLine($"保存网络答案到db:{Environment.NewLine}{quizAnswer}"); } return(best.Index); } }
/// <summary> /// 搜索问题 /// </summary> /// <param name="question">问题</param> /// <returns></returns> public static BestOption Search(KingQuestion question) { return(searchEngine.Search(question)); }