148 lines
5.8 KiB
C#
148 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace Concilium.Bot
|
|
{
|
|
public class PredicateLogic
|
|
{
|
|
private static string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
|
public Dictionary<string, List<string>> Predicates;
|
|
|
|
public string Parse(string input)
|
|
{
|
|
if (Predicates == null)
|
|
Predicates = new Dictionary<string, List<string>>();
|
|
|
|
var lastQuestionMark = input.Last() == '?';
|
|
var firstQuestionMark = input.First() == '?';
|
|
var rand = new Random((int)DateTime.Now.TimeOfDay.TotalMilliseconds);
|
|
if (lastQuestionMark && firstQuestionMark)
|
|
{
|
|
bool randomPredicate = rand.Next(2) == 0;
|
|
if (randomPredicate)
|
|
{
|
|
var predicates = Predicates.Where(p => p.Value.Count > 0).ToList();
|
|
var index = rand.Next(predicates.Count);
|
|
var kvp = predicates.ElementAt(index);
|
|
return DisplayPredicate(kvp.Key);
|
|
}
|
|
else // randomUser
|
|
{
|
|
var users = Predicates.SelectMany(kvp => kvp.Value).Distinct().ToList();
|
|
var index = rand.Next(users.Count);
|
|
return DisplayUser(users[index]);
|
|
}
|
|
}
|
|
else if (lastQuestionMark)
|
|
{
|
|
var predicate = input.Substring(0, input.Length - 1).Trim();
|
|
|
|
if (!predicate.All(c => allowedChars.IndexOf(c) != -1))
|
|
return "Syntax error: unexpected character in predicate";
|
|
|
|
if (!Predicates.ContainsKey(predicate) || Predicates[predicate].Count == 0)
|
|
return "No one is " + predicate;
|
|
|
|
return DisplayPredicate(predicate);
|
|
}
|
|
else if (firstQuestionMark)
|
|
{
|
|
input = input.Substring(1);
|
|
|
|
var leftBracket = input.IndexOf('(');
|
|
var rightBracket = input.IndexOf(')');
|
|
|
|
if (leftBracket == -1)
|
|
return "Syntax error: expecting '('";
|
|
if (rightBracket == -1)
|
|
return "Syntax error: expecting ')'";
|
|
if (rightBracket < leftBracket)
|
|
return "Syntax error: unexpected ')', was expecting '('";
|
|
|
|
var parameter = input.Substring(leftBracket + 1, rightBracket - leftBracket - 1).Trim();
|
|
|
|
if (!parameter.Any(c => allowedChars.IndexOf(c) != -1))
|
|
return "Syntax error: unexpected character in parameter";
|
|
|
|
return DisplayUser(parameter);
|
|
}
|
|
else
|
|
{
|
|
var leftBracket = input.IndexOf('(');
|
|
var rightBracket = input.IndexOf(')');
|
|
if (leftBracket == -1)
|
|
return "Syntax error: expecting '('";
|
|
if (rightBracket == -1)
|
|
return "Syntax error: expecting ')'";
|
|
if (rightBracket < leftBracket)
|
|
return "Syntax error: unexpected ')', was expecting '('";
|
|
|
|
var predicate = input.Substring(0, leftBracket).Trim();
|
|
var parameter = input.Substring(leftBracket + 1, rightBracket - leftBracket - 1).Trim();
|
|
|
|
var inverse = predicate[0] == '!';
|
|
if (inverse)
|
|
predicate = predicate.Substring(1);
|
|
|
|
if (!predicate.All(c => allowedChars.IndexOf(c) != -1))
|
|
return "Syntax error: unexpected character in predicate";
|
|
|
|
if (!parameter.Any(c => allowedChars.IndexOf(c) != -1))
|
|
return "Syntax error: unexpected character in parameter";
|
|
|
|
if (!Predicates.ContainsKey(predicate))
|
|
Predicates[predicate] = new List<string>();
|
|
|
|
if (inverse)
|
|
{
|
|
if (Predicates[predicate].Contains(parameter))
|
|
{
|
|
Predicates[predicate].Remove(parameter);
|
|
return parameter + " is no longer " + predicate;
|
|
}
|
|
else
|
|
{
|
|
return parameter + " is not currently " + predicate;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Predicates[predicate].Contains(parameter))
|
|
{
|
|
return parameter + " is already " + predicate;
|
|
}
|
|
else
|
|
{
|
|
Predicates[predicate].Add(parameter);
|
|
return parameter + " is now " + predicate;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private string DisplayUser(string user)
|
|
{
|
|
var predicates = Predicates.Where(kvp => kvp.Value.Contains(user)).Select(kvp => kvp.Key);
|
|
if (predicates.Count() == 0)
|
|
return "I don't know nothing about " + user;
|
|
|
|
var list = string.Join(", ", predicates);
|
|
var lastComma = list.LastIndexOf(',');
|
|
if (lastComma != -1)
|
|
list = list.Substring(0, lastComma) + " and" + list.Substring(lastComma + 1, list.Length - lastComma - 1);
|
|
return user + " is " + list;
|
|
}
|
|
|
|
private string DisplayPredicate(string predicate)
|
|
{
|
|
var list = string.Join(", ", Predicates[predicate]);
|
|
var lastComma = list.LastIndexOf(',');
|
|
if (lastComma != -1)
|
|
list = list.Substring(0, lastComma) + " and" + list.Substring(lastComma + 1, list.Length - lastComma - 1);
|
|
return list + (Predicates[predicate].Count > 1 ? " are " : " is ") + predicate;
|
|
}
|
|
}
|
|
}
|