-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMachineLearning.cs
More file actions
323 lines (288 loc) · 9.47 KB
/
MachineLearning.cs
File metadata and controls
323 lines (288 loc) · 9.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Lily
{
public class MachineLearning
{
private class PrivateRegex
{
[JsonProperty(PropertyName = "$regex")]
public string Regex { get; set; }
public PrivateRegex(string s)
{
Regex = s;
}
}
// To contributors, and to GitHub:
// I do not own this website, forgive me for the offensive words.
// I am not a racist in any way.
const string feedLink = "https://discord-spam-nigga.herokuapp.com/update";
const string queryLink = "https://discord-spam-nigga.herokuapp.com/find";
private Channel _channel;
private Random _rand = new Random();
private HttpClient _client = new HttpClient();
public MachineLearning(Channel channel)
{
_channel = channel;
// _channel.MessageReceive += OnMessageReceive;
}
public void FeedSentence(string context, string content)
{
Console.WriteLine($"[Lily]: I'll memorize this sentence: {content}");
Console.WriteLine($"[Debug]: sentence: {content}");
var words = content.Split();
foreach (var word in words)
{
if (word.Contains("["))
{
continue;
}
if (word.Length == 0)
{
continue;
}
var realWord = string.Empty;
if (word[word.Length - 1] == '.')
{
realWord = word.Substring(0, word.Length - 1);
}
else
{
realWord = word;
}
realWord = realWord.ToLower();
Console.WriteLine($"[Debug]: Sending word {realWord} with context {context}");
var text = JsonConvert.SerializeObject(new {doc = new {word = realWord, category = "hangman_word_framgents", context = context}});
Console.WriteLine($"[Debug]: {text}");
_ = Feed(text);
}
}
private async Task Feed(string json)
{
var request = new HttpRequestMessage();
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(feedLink);
await _client.SendAsync(request);
}
public void FeedSentenceAnswer(string context, string sentence, string word)
{
Console.WriteLine($"[Lily]: I'll keep a note that the answer to: {sentence} is {word}");
var words = sentence.Split();
foreach (var wword in words)
{
if (wword.Contains("[a-zA-Z*]"))
{
sentence = sentence.Replace(wword, word);
}
}
var text = JsonConvert.SerializeObject(new {doc = new {question = sentence, answer = word, category = "hangman", context = context}});
Console.WriteLine($"[Debug]: {text}");
_ = Feed(text);
}
private string Sort(string str)
{
var arr = str.ToCharArray();
Array.Sort(arr);
return new string(arr);
}
public void FeedScrambledWordAnswer(string context, string scrambled, string unscrambled)
{
Console.WriteLine($"[Lily]: I'll remember that {scrambled} is actually {unscrambled}, no need to look up my dictionary now.");
scrambled = Sort(scrambled);
var text = JsonConvert.SerializeObject(new {doc = new {question = scrambled, answer = unscrambled, category = "unscramble", context = context}});
Console.WriteLine($"[Debug]: {text}");
_ = Feed(text);
}
/// <summary>
/// Queries the server for a find missing work challenge.
/// </summary>
/// <param name="context">The game context, such as fishing or working</param>
/// <param name="content">The sentence, as a regular expression.</param>
/// <returns></returns>
public async Task<(IEnumerable<string> Results, bool IsFromCloud)> QuerySentenceAsync(string context, string content)
{
Console.WriteLine($"[Lily]: Checking my notebooks, please wait.");
var arr = await Query(JsonConvert.SerializeObject(new
{
query = new
{
question = new PrivateRegex(content),
category = new PrivateRegex("hangman"),
context = new PrivateRegex(context)
}
}));
if (arr.Count != 0)
{
return (arr
.Select(token => token.Value<string>("question"))
.Where(x => x != null)
.Select(x => Extract(x, content)), true);
}
Console.WriteLine($"[Lily]: This one's tough, I'll randomize a word for now.");
return (FillRandom(content), false);
}
private string Extract(string original, string regexed)
{
var arr1 = original.Split();
var arr2 = regexed.Split();
for (int i = 0; i < arr2.Length; ++i)
{
if (arr2[i].Contains("["))
{
return arr1[i];
}
}
throw new InvalidOperationException("What's wrong with the database?");
}
public IEnumerable<string> FillRandom(string content)
{
// This is more programmer friendly
content = content.Replace("[a-zA-Z*]", "*");
var contents = content.Split();
content = contents.FirstOrDefault(str => str.Contains("*"));
while (true)
{
var arr = content.ToCharArray();
for (int i = 0; i < arr.Length; ++i)
{
if (arr[i] == '*')
{
arr[i] = (char)_rand.Next('a', 'z');
}
}
yield return new string(arr);
}
}
public async Task<(IEnumerable<string> Results, bool IsFromCloud)> QueryUnscrambleAsync(string context, string scrambled)
{
Console.WriteLine($"[Lily]: Checking my notebooks, please wait.");
try
{
var arr = await Query(JsonConvert.SerializeObject(new
{
query = new
{
question = new PrivateRegex(Sort(scrambled)),
category = new PrivateRegex("unscramble"),
context = new PrivateRegex(context)
}
}));
if (arr.Count != 0)
{
return (arr.Select(token => token.Value<string>("answer")).Where(x => x != null), true);
}
}
catch (Exception e)
{
Console.Error.WriteLine($"[Debug]: {e.GetType()}: {e.Message}");
}
// Must write the code here to use our async capabilities.
Console.WriteLine($"[Lily]: I haven't got this, consulting my dictionary...");
var httpRequest = new HttpRequestMessage();
httpRequest.RequestUri = new Uri($"https://wordunscrambler.me/unscramble/{scrambled}");
var response = await _client.SendAsync(httpRequest);
var text = await response.Content.ReadAsStringAsync();
var words = Regex.Matches(text, "data-word=\"[^\"]*\"");
Console.Error.WriteLine($"[Debug]: {words.Count} words found.");
return (UnscrambleFallback(scrambled, words
.Select(match => match.Value)
.Select(word => word.Substring("data-word=\"".Length, word.Length - 1 - "data-word=\"".Length))
.Where(word => word.Length == scrambled.Length)), false);
}
public IEnumerable<string> UnscrambleFallback(string scrambled, IEnumerable<string> suggestions)
{
foreach (var suggestion in suggestions)
{
yield return suggestion;
}
Console.WriteLine($"[Lily]: This one's tough, I'll randomize a word for now.");
var arr = scrambled.ToCharArray();
while (true)
{
Randomize(arr);
yield return new string(arr);
}
}
private async Task<JArray> Query(string json)
{
Console.Error.WriteLine($"[Debug]: {json}");
var request = new HttpRequestMessage();
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(queryLink);
var response = await _client.SendAsync(request);
var responseJson = await response.Content.ReadAsStringAsync();
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<JArray>(responseJson);
}
// private void OnMessageReceive(object sender, MessageReceiveEventArgs args)
// {
// args.Deferral.Lock();
// Console.Error.WriteLine("[Debug]: Machine Learning routines...");
// var message = args.Message;
// var content = message.Value<string>("content");
// var embeds = message.Value<JArray>("embed");
// if (content.Contains("missing word", StringComparison.InvariantCultureIgnoreCase) ||
// content.Contains("missing __word__", StringComparison.InvariantCultureIgnoreCase))
// {
// var matches = Regex.Matches(content, "`[^`]*`");
// foreach (Match match in matches)
// {
// var text = match.Value;
// if (!text.Contains("_")) continue;
// text = text.Substring(1, text.Length - 2);
// Console.WriteLine($"[Lily]: I'm sending this to my developers: {text}");
// }
// }
// SearchForHangmanAnswers(content);
// if (embeds != null)
// {
// // The answer may be embedded.
// foreach (var embed in embeds)
// {
// var description = embed.Value<string>("description");
// SearchForHangmanAnswers(description);
// }
// }
// Console.Error.WriteLine("[Debug]: Machine Learning done.");
// args.Deferral.Unlock();
// }
// void SearchForHangmanAnswers(string content)
// {
// const string prefix = "The word was `";
// const string suffix = "`";
// var matches = Regex.Matches(content, "The word was `[^`]*`");
// foreach (Match match in matches)
// {
// var word = match.Value;
// word = word.Substring(prefix.Length, word.Length - prefix.Length - suffix.Length);
// Console.WriteLine($"[Lily]: I'm sending this to my developers: {word}");
// }
// }
// public async Task<string> QueryHangmanAsync(string Question)
// {
// return string.Empty;
// }
// Stolen...
private void Randomize<T>(T[] items)
{
// For each spot in the array, pick
// a random item to swap into that spot.
for (int i = 0; i < items.Length - 1; i++)
{
int j = _rand.Next(i, items.Length);
T temp = items[i];
items[i] = items[j];
items[j] = temp;
}
}
}
}