diff options
Diffstat (limited to 'lingo.cpp')
-rw-r--r-- | lingo.cpp | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/lingo.cpp b/lingo.cpp index 439bab5..5f8a025 100644 --- a/lingo.cpp +++ b/lingo.cpp | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <optional> | 13 | #include <optional> |
14 | #include <map> | 14 | #include <map> |
15 | #include <array> | 15 | #include <array> |
16 | #include "imagenet.h" | ||
16 | 17 | ||
17 | #define ENABLE_BOT | 18 | #define ENABLE_BOT |
18 | 19 | ||
@@ -31,6 +32,7 @@ enum Colour { | |||
31 | kPurple, | 32 | kPurple, |
32 | kBrown, | 33 | kBrown, |
33 | kYellow, | 34 | kYellow, |
35 | kGreen, | ||
34 | kColourCount | 36 | kColourCount |
35 | }; | 37 | }; |
36 | 38 | ||
@@ -41,7 +43,8 @@ const std::string COLOUR_EMOJIS[kColourCount] = { | |||
41 | "🟦", | 43 | "🟦", |
42 | "🟪", | 44 | "🟪", |
43 | "🟫", | 45 | "🟫", |
44 | "🟨" | 46 | "🟨", |
47 | "🟩" | ||
45 | }; | 48 | }; |
46 | 49 | ||
47 | const std::string NONE_EMOTE = "<:xx:1047267830535557180>"; | 50 | const std::string NONE_EMOTE = "<:xx:1047267830535557180>"; |
@@ -53,7 +56,8 @@ const std::string COLOUR_EMOTES[kColourCount] = { | |||
53 | "<:bl:1047262138202325042>", | 56 | "<:bl:1047262138202325042>", |
54 | "<:pr:1047262146926489691>", | 57 | "<:pr:1047262146926489691>", |
55 | "<:bn:1047262139187998790>", | 58 | "<:bn:1047262139187998790>", |
56 | "<:yw:1047262152781737986>" | 59 | "<:yw:1047262152781737986>", |
60 | "<:gn:1047262141914304633>" | ||
57 | }; | 61 | }; |
58 | 62 | ||
59 | enum FilterDirection { | 63 | enum FilterDirection { |
@@ -195,6 +199,50 @@ verbly::filter makeHintFilter(verbly::filter subfilter, Height height, Colour co | |||
195 | } | 199 | } |
196 | break; | 200 | break; |
197 | } | 201 | } |
202 | case kGreen: { | ||
203 | if (filter_direction == kTowardSolution) | ||
204 | { | ||
205 | verbly::filter whitelist = | ||
206 | (verbly::notion::wnid == 109287968) // Geological formations | ||
207 | || (verbly::notion::wnid == 109208496) // Asterisms (collections of stars) | ||
208 | || (verbly::notion::wnid == 109239740) // Celestial bodies | ||
209 | || (verbly::notion::wnid == 109277686) // Exterrestrial objects (comets and meteroids) | ||
210 | || (verbly::notion::wnid == 109403211) // Radiators (supposedly natural radiators but actually these are just pictures of radiators) | ||
211 | || (verbly::notion::wnid == 109416076) // Rocks | ||
212 | || (verbly::notion::wnid == 105442131) // Chromosomes | ||
213 | || (verbly::notion::wnid == 100324978) // Tightrope walking | ||
214 | || (verbly::notion::wnid == 100326094) // Rock climbing | ||
215 | || (verbly::notion::wnid == 100433458) // Contact sports | ||
216 | || (verbly::notion::wnid == 100433802) // Gymnastics | ||
217 | || (verbly::notion::wnid == 100439826) // Track and field | ||
218 | || (verbly::notion::wnid == 100440747) // Skiing | ||
219 | || (verbly::notion::wnid == 100441824) // Water sport | ||
220 | || (verbly::notion::wnid == 100445351) // Rowing | ||
221 | || (verbly::notion::wnid == 100446980) // Archery | ||
222 | // TODO: add more sports | ||
223 | || (verbly::notion::wnid == 100021939) // Artifacts | ||
224 | || (verbly::notion::wnid == 101471682) // Vertebrates | ||
225 | ; | ||
226 | |||
227 | verbly::filter blacklist = | ||
228 | (verbly::notion::wnid == 106883725) // swastika | ||
229 | || (verbly::notion::wnid == 104416901) // tetraskele | ||
230 | || (verbly::notion::wnid == 102512053) // fish | ||
231 | || (verbly::notion::wnid == 103575691) // instrument of execution | ||
232 | || (verbly::notion::wnid == 103829563) // noose | ||
233 | || (verbly::notion::wnid == 103663910) // life support | ||
234 | ; | ||
235 | |||
236 | return subfilter | ||
237 | && (verbly::notion::fullHypernyms %= whitelist) | ||
238 | && !(verbly::notion::fullHypernyms %= blacklist) | ||
239 | && (verbly::notion::partOfSpeech == verbly::part_of_speech::noun) | ||
240 | && (verbly::notion::numOfImages >= 1); | ||
241 | } else { | ||
242 | return (verbly::form::text == "picture"); | ||
243 | } | ||
244 | break; | ||
245 | } | ||
198 | default: break; // Not supported yet. | 246 | default: break; // Not supported yet. |
199 | } | 247 | } |
200 | return {}; | 248 | return {}; |
@@ -255,6 +303,7 @@ public: | |||
255 | dpp::snowflake channel(config["discord_channel"].as<uint64_t>()); | 303 | dpp::snowflake channel(config["discord_channel"].as<uint64_t>()); |
256 | 304 | ||
257 | database_ = std::make_unique<verbly::database>(config["verbly_datafile"].as<std::string>()); | 305 | database_ = std::make_unique<verbly::database>(config["verbly_datafile"].as<std::string>()); |
306 | imagenet_ = std::make_unique<imagenet>(config["imagenet"].as<std::string>()); | ||
258 | 307 | ||
259 | for (;;) | 308 | for (;;) |
260 | { | 309 | { |
@@ -278,10 +327,12 @@ private: | |||
278 | {kMiddle, kRed}, | 327 | {kMiddle, kRed}, |
279 | {kMiddle, kBlue}, | 328 | {kMiddle, kBlue}, |
280 | {kMiddle, kPurple}, | 329 | {kMiddle, kPurple}, |
330 | {kMiddle, kGreen}, | ||
281 | {kBottom, kWhite}, | 331 | {kBottom, kWhite}, |
282 | {kBottom, kBlack}, | 332 | {kBottom, kBlack}, |
283 | {kBottom, kRed}, | 333 | {kBottom, kRed}, |
284 | {kBottom, kBlue}, | 334 | {kBottom, kBlue}, |
335 | {kBottom, kGreen}, | ||
285 | }; | 336 | }; |
286 | 337 | ||
287 | std::set<std::tuple<Height, Colour>> expensive_hints = { | 338 | std::set<std::tuple<Height, Colour>> expensive_hints = { |
@@ -313,6 +364,7 @@ private: | |||
313 | int non_purple_uses = 0; | 364 | int non_purple_uses = 0; |
314 | int expensive_uses = 0; | 365 | int expensive_uses = 0; |
315 | int moderate_uses = 0; | 366 | int moderate_uses = 0; |
367 | int green_uses = 0; | ||
316 | std::array<std::optional<Colour>, kHeightCount> parts; | 368 | std::array<std::optional<Colour>, kHeightCount> parts; |
317 | for (int height = 0; height < static_cast<int>(kHeightCount); height++) { | 369 | for (int height = 0; height < static_cast<int>(kHeightCount); height++) { |
318 | if (std::bernoulli_distribution(0.5)(rng_)) { | 370 | if (std::bernoulli_distribution(0.5)(rng_)) { |
@@ -334,6 +386,10 @@ private: | |||
334 | { | 386 | { |
335 | moderate_uses++; | 387 | moderate_uses++; |
336 | } | 388 | } |
389 | if (colour == kGreen) | ||
390 | { | ||
391 | green_uses++; | ||
392 | } | ||
337 | 393 | ||
338 | std::cout << COLOUR_EMOJIS[colour]; | 394 | std::cout << COLOUR_EMOJIS[colour]; |
339 | } else { | 395 | } else { |
@@ -359,6 +415,11 @@ private: | |||
359 | std::cout << "Moderate hints can't be combined with an expensive hint." << std::endl; | 415 | std::cout << "Moderate hints can't be combined with an expensive hint." << std::endl; |
360 | continue; | 416 | continue; |
361 | } | 417 | } |
418 | if (green_uses != 1) | ||
419 | { | ||
420 | std::cout << "Too many green hints." << std::endl; | ||
421 | continue; | ||
422 | } | ||
362 | 423 | ||
363 | verbly::filter forwardFilter = cleanFilter && (verbly::form::proper == false); | 424 | verbly::filter forwardFilter = cleanFilter && (verbly::form::proper == false); |
364 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { | 425 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { |
@@ -401,10 +462,24 @@ private: | |||
401 | std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl; | 462 | std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl; |
402 | 463 | ||
403 | std::vector<verbly::form> admissibleResults = database_->forms(admissible, {}, 10).all(); | 464 | std::vector<verbly::form> admissibleResults = database_->forms(admissible, {}, 10).all(); |
404 | if (admissibleResults.size() <= (hints == 1 ? 2 : 5)) | 465 | if (green_uses > 0 || (admissibleResults.size() <= (hints == 1 ? 2 : 5))) |
405 | { | 466 | { |
406 | #ifdef ENABLE_BOT | 467 | #ifdef ENABLE_BOT |
407 | dpp::message message(channel, message_text); | 468 | dpp::message message(channel, message_text); |
469 | |||
470 | if (green_uses > 0) | ||
471 | { | ||
472 | verbly::notion notion = database_->notions( | ||
473 | (verbly::notion::numOfImages > 1) && solution).first(); | ||
474 | auto [image, extension] = imagenet_->getImageForNotion(notion.getId(), rng_); | ||
475 | if (image.empty()) | ||
476 | { | ||
477 | throw std::runtime_error("Could not find image for green hint."); | ||
478 | } | ||
479 | |||
480 | message.add_file(std::string("SPOILER_image.") + extension, image); | ||
481 | } | ||
482 | |||
408 | bot_->message_create(message, [this, &solution](const dpp::confirmation_callback_t& userdata) { | 483 | bot_->message_create(message, [this, &solution](const dpp::confirmation_callback_t& userdata) { |
409 | const auto& posted_msg = std::get<dpp::message>(userdata.value); | 484 | const auto& posted_msg = std::get<dpp::message>(userdata.value); |
410 | std::lock_guard answer_lock(answers_mutex_); | 485 | std::lock_guard answer_lock(answers_mutex_); |
@@ -432,6 +507,7 @@ private: | |||
432 | std::mt19937& rng_; | 507 | std::mt19937& rng_; |
433 | std::unique_ptr<dpp::cluster> bot_; | 508 | std::unique_ptr<dpp::cluster> bot_; |
434 | std::unique_ptr<verbly::database> database_; | 509 | std::unique_ptr<verbly::database> database_; |
510 | std::unique_ptr<imagenet> imagenet_; | ||
435 | std::map<uint64_t, std::string> answer_by_message_; | 511 | std::map<uint64_t, std::string> answer_by_message_; |
436 | std::mutex answers_mutex_; | 512 | std::mutex answers_mutex_; |
437 | }; | 513 | }; |