diff options
Diffstat (limited to 'lingo.cpp')
-rw-r--r-- | lingo.cpp | 499 |
1 files changed, 148 insertions, 351 deletions
diff --git a/lingo.cpp b/lingo.cpp index 5cef99b..e4f3236 100644 --- a/lingo.cpp +++ b/lingo.cpp | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <map> | 14 | #include <map> |
15 | #include <array> | 15 | #include <array> |
16 | 16 | ||
17 | #define ENABLE_BOT | ||
18 | |||
17 | enum Height { | 19 | enum Height { |
18 | kTop, | 20 | kTop, |
19 | kMiddle, | 21 | kMiddle, |
@@ -42,6 +44,138 @@ const std::string COLOUR_EMOJIS[kColourCount] = { | |||
42 | "🟨" | 44 | "🟨" |
43 | }; | 45 | }; |
44 | 46 | ||
47 | enum FilterDirection { | ||
48 | kTowardSolution, | ||
49 | kTowardQuestion | ||
50 | }; | ||
51 | |||
52 | verbly::filter makeHintFilter(verbly::filter subfilter, Height height, Colour colour, FilterDirection filter_direction) | ||
53 | { | ||
54 | switch (colour) { | ||
55 | case kWhite: { | ||
56 | switch (height) { | ||
57 | case kBottom: { | ||
58 | return (verbly::word::synonyms %= subfilter); | ||
59 | } | ||
60 | case kTop: { | ||
61 | return (verbly::form::pronunciations %= | ||
62 | verbly::filter("homophones", false, | ||
63 | (verbly::pronunciation::forms %= (subfilter && verbly::filter( | ||
64 | verbly::form::id, | ||
65 | verbly::filter::comparison::field_does_not_equal, | ||
66 | verbly::form::id))))); | ||
67 | } | ||
68 | default: break; // Not supported yet. | ||
69 | } | ||
70 | break; | ||
71 | } | ||
72 | case kBlack: { | ||
73 | switch (height) { | ||
74 | case kBottom: { | ||
75 | return (verbly::word::antonyms %= subfilter); | ||
76 | } | ||
77 | default: break; // Not supported yet. | ||
78 | } | ||
79 | break; | ||
80 | } | ||
81 | case kBrown: { | ||
82 | break; // Not supported yet. | ||
83 | } | ||
84 | case kRed: { | ||
85 | switch (height) { | ||
86 | case kTop: { | ||
87 | if (filter_direction == kTowardSolution) | ||
88 | { | ||
89 | return (verbly::pronunciation::merophones %= subfilter); | ||
90 | } else { | ||
91 | return (verbly::pronunciation::holophones %= subfilter); | ||
92 | } | ||
93 | } | ||
94 | case kMiddle: { | ||
95 | if (filter_direction == kTowardSolution) | ||
96 | { | ||
97 | return (verbly::form::merographs %= subfilter); | ||
98 | } else { | ||
99 | return (verbly::form::holographs %= subfilter); | ||
100 | } | ||
101 | } | ||
102 | case kBottom: { | ||
103 | if (filter_direction == kTowardSolution) | ||
104 | { | ||
105 | return (verbly::notion::partMeronyms %= subfilter); | ||
106 | } else { | ||
107 | return (verbly::notion::partHolonyms %= subfilter); | ||
108 | } | ||
109 | } | ||
110 | default: break; // Not supported yet. | ||
111 | } | ||
112 | break; | ||
113 | } | ||
114 | case kBlue: { | ||
115 | switch (height) { | ||
116 | case kTop: { | ||
117 | if (filter_direction == kTowardSolution) | ||
118 | { | ||
119 | return (verbly::pronunciation::holophones %= subfilter); | ||
120 | } else { | ||
121 | return (verbly::pronunciation::merophones %= subfilter); | ||
122 | } | ||
123 | } | ||
124 | case kMiddle: { | ||
125 | if (filter_direction == kTowardSolution) | ||
126 | { | ||
127 | return (verbly::form::holographs %= subfilter); | ||
128 | } else { | ||
129 | return (verbly::form::merographs %= subfilter); | ||
130 | } | ||
131 | } | ||
132 | case kBottom: { | ||
133 | if (filter_direction == kTowardSolution) | ||
134 | { | ||
135 | return (verbly::notion::partHolonyms %= subfilter); | ||
136 | } else { | ||
137 | return (verbly::notion::partMeronyms %= subfilter); | ||
138 | } | ||
139 | } | ||
140 | default: break; // Not supported yet. | ||
141 | } | ||
142 | break; | ||
143 | } | ||
144 | case kPurple: { | ||
145 | switch (height) { | ||
146 | case kMiddle: { | ||
147 | return (verbly::form::merographs %= (verbly::form::length >= 4 && (verbly::form::holographs %= subfilter))); | ||
148 | } | ||
149 | case kTop: { | ||
150 | return (verbly::pronunciation::rhymes %= subfilter); | ||
151 | } | ||
152 | default: break; // Not supported yet. | ||
153 | } | ||
154 | break; | ||
155 | } | ||
156 | case kYellow: { | ||
157 | switch (height) { | ||
158 | case kTop: { | ||
159 | return (verbly::pronunciation::anaphones %= (subfilter && verbly::filter( | ||
160 | verbly::pronunciation::id, | ||
161 | verbly::filter::comparison::field_does_not_equal, | ||
162 | verbly::pronunciation::id))); | ||
163 | } | ||
164 | case kMiddle: { | ||
165 | return (verbly::form::anagrams %= (subfilter && verbly::filter( | ||
166 | verbly::form::id, | ||
167 | verbly::filter::comparison::field_does_not_equal, | ||
168 | verbly::form::id))); | ||
169 | } | ||
170 | default: break; // Not supported yet. | ||
171 | } | ||
172 | break; | ||
173 | } | ||
174 | default: break; // Not supported yet. | ||
175 | } | ||
176 | return {}; | ||
177 | } | ||
178 | |||
45 | class lingo { | 179 | class lingo { |
46 | public: | 180 | public: |
47 | lingo(std::mt19937& rng) : rng_(rng) {} | 181 | lingo(std::mt19937& rng) : rng_(rng) {} |
@@ -49,6 +183,8 @@ public: | |||
49 | void run(const std::string& configpath) | 183 | void run(const std::string& configpath) |
50 | { | 184 | { |
51 | YAML::Node config = YAML::LoadFile(configpath); | 185 | YAML::Node config = YAML::LoadFile(configpath); |
186 | |||
187 | #ifdef ENABLE_BOT | ||
52 | bot_ = std::make_unique<dpp::cluster>(config["discord_token"].as<std::string>()); | 188 | bot_ = std::make_unique<dpp::cluster>(config["discord_token"].as<std::string>()); |
53 | 189 | ||
54 | bot_->on_ready([this](const dpp::ready_t& event) { | 190 | bot_->on_ready([this](const dpp::ready_t& event) { |
@@ -90,6 +226,7 @@ public: | |||
90 | }); | 226 | }); |
91 | 227 | ||
92 | bot_->start(); | 228 | bot_->start(); |
229 | #endif | ||
93 | 230 | ||
94 | dpp::snowflake channel(config["discord_channel"].as<uint64_t>()); | 231 | dpp::snowflake channel(config["discord_channel"].as<uint64_t>()); |
95 | 232 | ||
@@ -164,366 +301,24 @@ private: | |||
164 | if (!colour.has_value()) { | 301 | if (!colour.has_value()) { |
165 | continue; | 302 | continue; |
166 | } | 303 | } |
167 | switch (*colour) { | 304 | forwardFilter &= makeHintFilter(wordFilter, height, *colour, kTowardSolution); |
168 | case kWhite: { | ||
169 | switch (height) { | ||
170 | case kBottom: { | ||
171 | forwardFilter &= (verbly::word::synonyms %= wordFilter); | ||
172 | break; | ||
173 | } | ||
174 | case kTop: { | ||
175 | forwardFilter &= (verbly::form::pronunciations %= | ||
176 | verbly::filter("homophones", false, | ||
177 | (verbly::pronunciation::forms %= (wordFilter && verbly::filter( | ||
178 | verbly::form::id, | ||
179 | verbly::filter::comparison::field_does_not_equal, | ||
180 | verbly::form::id))))); | ||
181 | break; | ||
182 | } | ||
183 | default: break; // Not supported yet. | ||
184 | } | ||
185 | break; | ||
186 | } | ||
187 | case kBlack: { | ||
188 | switch (height) { | ||
189 | case kBottom: { | ||
190 | forwardFilter &= (verbly::word::antonyms %= wordFilter); | ||
191 | break; | ||
192 | } | ||
193 | default: break; // Not supported yet. | ||
194 | } | ||
195 | break; | ||
196 | } | ||
197 | case kBrown: { | ||
198 | switch (height) { | ||
199 | case kBottom: { | ||
200 | forwardFilter &= (verbly::notion::causes %= wordFilter); | ||
201 | break; | ||
202 | } | ||
203 | default: break; // Not supported yet. | ||
204 | } | ||
205 | break; | ||
206 | } | ||
207 | case kRed: { | ||
208 | switch (height) { | ||
209 | case kTop: { | ||
210 | forwardFilter &= (verbly::pronunciation::holophones %= wordFilter); | ||
211 | break; | ||
212 | } | ||
213 | case kMiddle: { | ||
214 | forwardFilter &= (verbly::form::holographs %= wordFilter); | ||
215 | break; | ||
216 | } | ||
217 | case kBottom: { | ||
218 | forwardFilter &= (verbly::notion::partMeronyms %= wordFilter); | ||
219 | break; | ||
220 | } | ||
221 | default: break; // Not supported yet. | ||
222 | } | ||
223 | break; | ||
224 | } | ||
225 | case kBlue: { | ||
226 | switch (height) { | ||
227 | case kTop: { | ||
228 | forwardFilter &= (verbly::pronunciation::merophones %= wordFilter); | ||
229 | break; | ||
230 | } | ||
231 | case kMiddle: { | ||
232 | forwardFilter &= (verbly::form::merographs %= wordFilter); | ||
233 | break; | ||
234 | } | ||
235 | case kBottom: { | ||
236 | forwardFilter &= (verbly::notion::partHolonyms %= wordFilter); | ||
237 | break; | ||
238 | } | ||
239 | default: break; // Not supported yet. | ||
240 | } | ||
241 | break; | ||
242 | } | ||
243 | case kPurple: { | ||
244 | switch (height) { | ||
245 | case kMiddle: { | ||
246 | forwardFilter &= (verbly::form::merographs %= (verbly::form::length >= 4 && (verbly::form::holographs %= wordFilter))); | ||
247 | break; | ||
248 | } | ||
249 | case kTop: { | ||
250 | forwardFilter &= (verbly::pronunciation::rhymes %= wordFilter); | ||
251 | break; | ||
252 | } | ||
253 | default: break; // Not supported yet. | ||
254 | } | ||
255 | break; | ||
256 | } | ||
257 | case kYellow: { | ||
258 | switch (height) { | ||
259 | case kTop: { | ||
260 | forwardFilter &= (verbly::pronunciation::anaphones %= (wordFilter && verbly::filter( | ||
261 | verbly::pronunciation::id, | ||
262 | verbly::filter::comparison::field_does_not_equal, | ||
263 | verbly::pronunciation::id))); | ||
264 | break; | ||
265 | } | ||
266 | case kMiddle: { | ||
267 | forwardFilter &= (verbly::form::anagrams %= (wordFilter && verbly::filter( | ||
268 | verbly::form::id, | ||
269 | verbly::filter::comparison::field_does_not_equal, | ||
270 | verbly::form::id))); | ||
271 | break; | ||
272 | } | ||
273 | default: break; // Not supported yet. | ||
274 | } | ||
275 | break; | ||
276 | } | ||
277 | default: break; // Not supported yet. | ||
278 | } | ||
279 | } | 305 | } |
280 | 306 | ||
281 | verbly::form solution = database_->forms(forwardFilter).first(); | 307 | verbly::form solution = database_->forms(forwardFilter).first(); |
282 | verbly::filter admissable = cleanFilter && (verbly::form::proper == false); | 308 | verbly::filter admissible = cleanFilter && (verbly::form::proper == false); |
309 | |||
310 | std::cout << "Solution decided: " << solution.getText() << std::endl; | ||
283 | 311 | ||
284 | std::ostringstream msg_stream; | 312 | std::ostringstream msg_stream; |
285 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { | 313 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { |
286 | Height height = static_cast<Height>(i); | 314 | Height height = static_cast<Height>(i); |
287 | std::optional<Colour>& colour = parts[i]; | 315 | std::optional<Colour>& colour = parts[i]; |
288 | if (colour.has_value()) { | 316 | if (colour.has_value()) { |
289 | verbly::filter questionFilter; | 317 | verbly::filter questionFilter = makeHintFilter(solution, height, *colour, kTowardQuestion); |
290 | switch (*colour) { | ||
291 | case kWhite: { | ||
292 | switch (height) { | ||
293 | case kBottom: { | ||
294 | questionFilter = (verbly::word::synonyms %= solution); | ||
295 | break; | ||
296 | } | ||
297 | case kTop: { | ||
298 | questionFilter = (verbly::form::pronunciations %= | ||
299 | verbly::filter("homophones", false, | ||
300 | (verbly::pronunciation::forms %= ((verbly::filter)solution && verbly::filter( | ||
301 | verbly::form::id, | ||
302 | verbly::filter::comparison::field_does_not_equal, | ||
303 | verbly::form::id))))); | ||
304 | break; | ||
305 | } | ||
306 | default: break; // Not supported yet. | ||
307 | } | ||
308 | break; | ||
309 | } | ||
310 | case kBlack: { | ||
311 | switch (height) { | ||
312 | case kBottom: { | ||
313 | questionFilter = (verbly::word::antonyms %= solution); | ||
314 | break; | ||
315 | } | ||
316 | default: break; // Not supported yet. | ||
317 | } | ||
318 | break; | ||
319 | } | ||
320 | case kBrown: { | ||
321 | switch (height) { | ||
322 | case kBottom: { | ||
323 | questionFilter = (verbly::notion::effects %= solution); | ||
324 | break; | ||
325 | } | ||
326 | default: break; // Not supported yet. | ||
327 | } | ||
328 | break; | ||
329 | } | ||
330 | case kBlue: { | ||
331 | switch (height) { | ||
332 | case kTop: { | ||
333 | questionFilter = (verbly::pronunciation::holophones %= solution); | ||
334 | break; | ||
335 | } | ||
336 | case kMiddle: { | ||
337 | questionFilter = (verbly::form::holographs %= solution); | ||
338 | break; | ||
339 | } | ||
340 | case kBottom: { | ||
341 | /*questionFilter = ((verbly::notion::fullMemberHolonyms %= solution) | ||
342 | || (verbly::notion::fullPartHolonyms %= solution) | ||
343 | || (verbly::notion::fullSubstanceHolonyms %= solution));*/ | ||
344 | //questionFilter &= !(verbly::notion::words %= solution); | ||
345 | questionFilter = (verbly::notion::partMeronyms %= solution); | ||
346 | break; | ||
347 | } | ||
348 | default: break; // Not supported yet. | ||
349 | } | ||
350 | break; | ||
351 | } | ||
352 | case kRed: { | ||
353 | switch (height) { | ||
354 | case kTop: { | ||
355 | questionFilter = (verbly::pronunciation::merophones %= solution); | ||
356 | break; | ||
357 | } | ||
358 | case kMiddle: { | ||
359 | questionFilter = (verbly::form::merographs %= solution); | ||
360 | break; | ||
361 | } | ||
362 | case kBottom: { | ||
363 | /*questionFilter = ((verbly::notion::fullMemberMeronyms %= solution) | ||
364 | || (verbly::notion::fullPartMeronyms %= solution) | ||
365 | || (verbly::notion::fullSubstanceMeronyms %= solution));*/ | ||
366 | questionFilter = (verbly::notion::partHolonyms %= solution); | ||
367 | //questionFilter &= !(verbly::notion::words %= solution); | ||
368 | break; | ||
369 | } | ||
370 | default: break; // Not supported yet. | ||
371 | } | ||
372 | break; | ||
373 | } | ||
374 | case kPurple: { | ||
375 | switch (height) { | ||
376 | case kTop: { | ||
377 | questionFilter = (verbly::pronunciation::rhymes %= solution); | ||
378 | break; | ||
379 | } | ||
380 | case kMiddle: { | ||
381 | questionFilter = (verbly::form::merographs %= (verbly::form::length >= 4 && (verbly::form::holographs %= solution))); | ||
382 | break; | ||
383 | } | ||
384 | default: break; // Not supported yet. | ||
385 | } | ||
386 | break; | ||
387 | } | ||
388 | case kYellow: { | ||
389 | switch (height) { | ||
390 | case kTop: { | ||
391 | questionFilter = (verbly::pronunciation::anaphones %= ((verbly::filter)solution && verbly::filter( | ||
392 | verbly::pronunciation::id, | ||
393 | verbly::filter::comparison::field_does_not_equal, | ||
394 | verbly::pronunciation::id))); | ||
395 | break; | ||
396 | } | ||
397 | case kMiddle: { | ||
398 | questionFilter = (verbly::form::anagrams %= ((verbly::filter)solution && verbly::filter( | ||
399 | verbly::form::id, | ||
400 | verbly::filter::comparison::field_does_not_equal, | ||
401 | verbly::form::id))); | ||
402 | break; | ||
403 | } | ||
404 | default: break; // Not supported yet. | ||
405 | } | ||
406 | break; | ||
407 | } | ||
408 | default: break; // Not supported yet. | ||
409 | } | ||
410 | verbly::form questionPart = database_->forms(questionFilter && cleanFilter).first(); | 318 | verbly::form questionPart = database_->forms(questionFilter && cleanFilter).first(); |
411 | msg_stream << COLOUR_EMOJIS[*colour] << " " << questionPart.getText() << std::endl; | 319 | msg_stream << COLOUR_EMOJIS[*colour] << " " << questionPart.getText() << std::endl; |
412 | 320 | ||
413 | verbly::filter addedClause = (verbly::form::text == questionPart.getText()); | 321 | admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution); |
414 | |||
415 | switch (*colour) { | ||
416 | case kWhite: { | ||
417 | switch (height) { | ||
418 | case kBottom: { | ||
419 | admissable &= (verbly::word::synonyms %= addedClause); | ||
420 | break; | ||
421 | } | ||
422 | case kTop: { | ||
423 | admissable &= (verbly::form::pronunciations %= | ||
424 | verbly::filter("homophones", false, | ||
425 | (verbly::pronunciation::forms %= (addedClause && verbly::filter( | ||
426 | verbly::form::id, | ||
427 | verbly::filter::comparison::field_does_not_equal, | ||
428 | verbly::form::id))))); | ||
429 | break; | ||
430 | } | ||
431 | default: break; // Not supported yet. | ||
432 | } | ||
433 | break; | ||
434 | } | ||
435 | case kBlack: { | ||
436 | switch (height) { | ||
437 | case kBottom: { | ||
438 | admissable &= (verbly::word::antonyms %= addedClause); | ||
439 | break; | ||
440 | } | ||
441 | default: break; // Not supported yet. | ||
442 | } | ||
443 | break; | ||
444 | } | ||
445 | case kBrown: { | ||
446 | switch (height) { | ||
447 | case kBottom: { | ||
448 | admissable &= (verbly::notion::causes %= addedClause); | ||
449 | break; | ||
450 | } | ||
451 | default: break; // Not supported yet. | ||
452 | } | ||
453 | break; | ||
454 | } | ||
455 | case kRed: { | ||
456 | switch (height) { | ||
457 | case kTop: { | ||
458 | admissable &= (verbly::pronunciation::holophones %= addedClause); | ||
459 | break; | ||
460 | } | ||
461 | case kMiddle: { | ||
462 | admissable &= (verbly::form::holographs %= addedClause); | ||
463 | break; | ||
464 | } | ||
465 | case kBottom: { | ||
466 | admissable &= (verbly::notion::partMeronyms %= addedClause); | ||
467 | break; | ||
468 | } | ||
469 | default: break; // Not supported yet. | ||
470 | } | ||
471 | break; | ||
472 | } | ||
473 | case kBlue: { | ||
474 | switch (height) { | ||
475 | case kTop: { | ||
476 | admissable &= (verbly::pronunciation::merophones %= addedClause); | ||
477 | break; | ||
478 | } | ||
479 | case kMiddle: { | ||
480 | admissable &= (verbly::form::merographs %= addedClause); | ||
481 | break; | ||
482 | } | ||
483 | case kBottom: { | ||
484 | admissable &= (verbly::notion::partHolonyms %= addedClause); | ||
485 | break; | ||
486 | } | ||
487 | default: break; // Not supported yet. | ||
488 | } | ||
489 | break; | ||
490 | } | ||
491 | case kPurple: { | ||
492 | switch (height) { | ||
493 | case kMiddle: { | ||
494 | admissable &= (verbly::form::merographs %= (verbly::form::length >= 4 && (verbly::form::holographs %= addedClause))); | ||
495 | break; | ||
496 | } | ||
497 | case kTop: { | ||
498 | admissable &= (verbly::pronunciation::rhymes %= addedClause); | ||
499 | break; | ||
500 | } | ||
501 | default: break; // Not supported yet. | ||
502 | } | ||
503 | break; | ||
504 | } | ||
505 | case kYellow: { | ||
506 | switch (height) { | ||
507 | case kTop: { | ||
508 | admissable &= (verbly::pronunciation::anaphones %= (addedClause && verbly::filter( | ||
509 | verbly::pronunciation::id, | ||
510 | verbly::filter::comparison::field_does_not_equal, | ||
511 | verbly::pronunciation::id))); | ||
512 | break; | ||
513 | } | ||
514 | case kMiddle: { | ||
515 | admissable &= (verbly::form::anagrams %= (addedClause && verbly::filter( | ||
516 | verbly::form::id, | ||
517 | verbly::filter::comparison::field_does_not_equal, | ||
518 | verbly::form::id))); | ||
519 | break; | ||
520 | } | ||
521 | default: break; // Not supported yet. | ||
522 | } | ||
523 | break; | ||
524 | } | ||
525 | default: break; // Not supported yet. | ||
526 | } | ||
527 | } else { | 322 | } else { |
528 | msg_stream << "▪️" << std::endl; | 323 | msg_stream << "▪️" << std::endl; |
529 | } | 324 | } |
@@ -539,9 +334,10 @@ private: | |||
539 | std::string message_text = msg_stream.str(); | 334 | std::string message_text = msg_stream.str(); |
540 | std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl; | 335 | std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl; |
541 | 336 | ||
542 | std::vector<verbly::form> admissableResults = database_->forms(admissable).all(); | 337 | std::vector<verbly::form> admissibleResults = database_->forms(admissible).all(); |
543 | if (admissableResults.size() <= (hints == 1 ? 2 : 5)) | 338 | if (admissibleResults.size() <= (hints == 1 ? 2 : 5)) |
544 | { | 339 | { |
340 | #ifdef ENABLE_BOT | ||
545 | dpp::message message(channel, message_text); | 341 | dpp::message message(channel, message_text); |
546 | bot_->message_create(message, [this, &solution](const dpp::confirmation_callback_t& userdata) { | 342 | bot_->message_create(message, [this, &solution](const dpp::confirmation_callback_t& userdata) { |
547 | const auto& posted_msg = std::get<dpp::message>(userdata.value); | 343 | const auto& posted_msg = std::get<dpp::message>(userdata.value); |
@@ -552,10 +348,11 @@ private: | |||
552 | } | 348 | } |
553 | answer_by_message_[posted_msg.id] = solution.getText(); | 349 | answer_by_message_[posted_msg.id] = solution.getText(); |
554 | }); | 350 | }); |
351 | #endif | ||
555 | 352 | ||
556 | generated = true; | 353 | generated = true; |
557 | } else { | 354 | } else { |
558 | std::cout << "Too many (" << admissableResults.size() << ") results." << std::endl; | 355 | std::cout << "Too many (" << admissibleResults.size() << ") results." << std::endl; |
559 | } | 356 | } |
560 | } catch (const std::exception& ex) { | 357 | } catch (const std::exception& ex) { |
561 | std::cout << ex.what() << std::endl; | 358 | std::cout << ex.what() << std::endl; |