Updated trivia comparison to be more lenient

This commit is contained in:
micmorris 2016-01-22 22:56:49 -08:00
parent 6c7a0fb4fe
commit 13022c78e9

View File

@ -6,9 +6,11 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers; using System.Timers;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Collections;
namespace NadekoBot namespace NadekoBot
{ {
@ -117,6 +119,10 @@ namespace NadekoBot
private bool active = false; private bool active = false;
//represents the min size to judge levDistance with
private List<Tuple<int, int>> strictness;
private int maxStringLength;
private Timer timeout; private Timer timeout;
private Stopwatch stopwatch; private Stopwatch stopwatch;
private bool isQuit = false; private bool isQuit = false;
@ -130,6 +136,14 @@ namespace NadekoBot
oldQuestions = new List<string>(); oldQuestions = new List<string>();
client.MessageReceived += PotentialGuess; client.MessageReceived += PotentialGuess;
strictness = new List<Tuple<int, int>>();
strictness.Add(new Tuple<int, int>(6, 0));
strictness.Add(new Tuple<int, int>(9, 1));
strictness.Add(new Tuple<int, int>(13, 2));
strictness.Add(new Tuple<int, int>(16, 3));
strictness.Add(new Tuple<int, int>(21, 4));
maxStringLength = 22;
timeout = new Timer(); timeout = new Timer();
timeout.Interval = 30000; timeout.Interval = 30000;
stopwatch = new Stopwatch(); stopwatch = new Stopwatch();
@ -144,12 +158,15 @@ namespace NadekoBot
if (e.Server.Id != _serverId || !active) if (e.Server.Id != _serverId || !active)
return; return;
if (e.User.Id == client.CurrentUser.Id)
return;
if (e.Message.Text.ToLower().Equals("idfk")) { if (e.Message.Text.ToLower().Equals("idfk")) {
GetHint(e); GetHint(e);
return; return;
} }
if (e.Message.Text.ToLower() == currentQuestion.Answer.ToLower()) if (IsAnswerCorrect(e.Message.Text.ToLower(), currentQuestion.Answer.ToLower()))
{ {
active = false; //start pause between rounds active = false; //start pause between rounds
timeout.Enabled = false; timeout.Enabled = false;
@ -174,6 +191,99 @@ namespace NadekoBot
} }
} }
private bool IsAnswerCorrect(string guess, string answer)
{
if(guess.Equals(answer))
{
return true;
}
guess = CleanString(guess);
answer = CleanString(answer);
if (guess.Equals(answer))
{
return true;
}
int levDistance = ComputeLevenshteinDistance(guess, answer);
return Judge(guess.Length, answer.Length, levDistance);
}
private bool Judge(int guessLength, int answerLength, int levDistance)
{
foreach(Tuple<int, int> level in strictness)
{
if(guessLength <= level.Item1 || answerLength <= level.Item1)
{
if (levDistance <= level.Item2)
return true;
else
return false;
}
}
return false;
}
private string CleanString(string str)
{
str = " " + str + " ";
str = Regex.Replace(str, "\\s+", " ");
str = Regex.Replace(str, "[^\\w\\d\\s]", "");
//Here's where custom modification can be done
str = Regex.Replace(str, "\\s(a|an|the|of|in|for|to|as|at|be)\\s", " ");
//End custom mod and cleanup whitespace
str = Regex.Replace(str, "^\\s+", "");
str = Regex.Replace(str, "\\s+$", "");
//Trim the really long answers
str = str.Length <= maxStringLength ? str : str.Substring(0, maxStringLength);
return str;
}
//http://www.dotnetperls.com/levenshtein
private int ComputeLevenshteinDistance(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
public async void GetHint(MessageEventArgs e) { public async void GetHint(MessageEventArgs e) {
if (timeout != null && !isQuit && stopwatch.ElapsedMilliseconds > 10000) if (timeout != null && !isQuit && stopwatch.ElapsedMilliseconds > 10000)
await e.Send( currentQuestion.Answer.Scramble()); await e.Send( currentQuestion.Answer.Scramble());