summary refs log tree commit diff stats
path: root/lingo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lingo.cpp')
-rw-r--r--lingo.cpp499
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
17enum Height { 19enum 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
47enum FilterDirection {
48 kTowardSolution,
49 kTowardQuestion
50};
51
52verbly::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
45class lingo { 179class lingo {
46public: 180public:
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;