Files
Concilium/Concilium/Bot/PredicateLogic.cs
2026-04-19 01:09:29 +02:00

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;
}
}
}