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.cpp70
1 files changed, 63 insertions, 7 deletions
diff --git a/lingo.cpp b/lingo.cpp index c2f36af..12471d1 100644 --- a/lingo.cpp +++ b/lingo.cpp
@@ -37,6 +37,7 @@ enum Colour {
37 kBrown, 37 kBrown,
38 kYellow, 38 kYellow,
39 kGreen, 39 kGreen,
40 kOrange,
40 kColourCount 41 kColourCount
41}; 42};
42 43
@@ -48,7 +49,8 @@ const std::string COLOUR_EMOJIS[kColourCount] = {
48 "🟪", 49 "🟪",
49 "🟫", 50 "🟫",
50 "🟨", 51 "🟨",
51 "🟩" 52 "🟩",
53 "🟧",
52}; 54};
53 55
54const std::string NONE_EMOTE = "<:xx:1047267830535557180>"; 56const std::string NONE_EMOTE = "<:xx:1047267830535557180>";
@@ -61,7 +63,8 @@ const std::string COLOUR_EMOTES[kColourCount] = {
61 "<:pr:1047262146926489691>", 63 "<:pr:1047262146926489691>",
62 "<:bn:1047262139187998790>", 64 "<:bn:1047262139187998790>",
63 "<:yw:1047262152781737986>", 65 "<:yw:1047262152781737986>",
64 "<:gn:1047262141914304633>" 66 "<:gn:1047262141914304633>",
67 "<:or:1047262144934182983>",
65}; 68};
66 69
67enum FilterDirection { 70enum FilterDirection {
@@ -272,6 +275,33 @@ verbly::filter makeHintFilter(verbly::filter subfilter, Height height, Colour co
272 return {}; 275 return {};
273} 276}
274 277
278class wanderlust {
279public:
280 explicit wanderlust(const std::string& filename)
281 {
282 std::ifstream file(filename);
283 std::string line;
284 while (std::getline(file, line))
285 {
286 std::string line2;
287 if (!std::getline(file, line2))
288 {
289 throw std::invalid_argument("Wanderlust file is malformed.");
290 }
291
292 puzzles_.emplace_back(line, line2);
293 }
294 }
295
296 std::tuple<std::string, std::string> getPuzzle(std::mt19937& rng) const
297 {
298 return puzzles_.at(std::uniform_int_distribution<int>(0, puzzles_.size()-1)(rng));
299 }
300
301private:
302 std::vector<std::tuple<std::string, std::string>> puzzles_;
303};
304
275class lingo { 305class lingo {
276public: 306public:
277 lingo(std::mt19937& rng) : rng_(rng) {} 307 lingo(std::mt19937& rng) : rng_(rng) {}
@@ -380,6 +410,7 @@ public:
380 410
381 database_ = std::make_unique<verbly::database>(config["verbly_datafile"].as<std::string>()); 411 database_ = std::make_unique<verbly::database>(config["verbly_datafile"].as<std::string>());
382 imagenet_ = std::make_unique<imagenet>(config["imagenet"].as<std::string>()); 412 imagenet_ = std::make_unique<imagenet>(config["imagenet"].as<std::string>());
413 wanderlust_ = std::make_unique<wanderlust>(config["wanderlust"].as<std::string>());
383 414
384 scoreboard_endpoint_ = config["scoreboard_endpoint"].as<std::string>(); 415 scoreboard_endpoint_ = config["scoreboard_endpoint"].as<std::string>();
385 scoreboard_secret_code_ = config["scoreboard_secret_code"].as<std::string>(); 416 scoreboard_secret_code_ = config["scoreboard_secret_code"].as<std::string>();
@@ -407,6 +438,7 @@ private:
407 {kMiddle, kBlue}, 438 {kMiddle, kBlue},
408 {kMiddle, kPurple}, 439 {kMiddle, kPurple},
409 {kMiddle, kGreen}, 440 {kMiddle, kGreen},
441 {kMiddle, kOrange},
410 {kBottom, kWhite}, 442 {kBottom, kWhite},
411 {kBottom, kBlack}, 443 {kBottom, kBlack},
412 {kBottom, kRed}, 444 {kBottom, kRed},
@@ -447,6 +479,7 @@ private:
447 int expensive_uses = 0; 479 int expensive_uses = 0;
448 int moderate_uses = 0; 480 int moderate_uses = 0;
449 int green_uses = 0; 481 int green_uses = 0;
482 int orange_uses = 0;
450 std::array<std::optional<Colour>, kHeightCount> parts; 483 std::array<std::optional<Colour>, kHeightCount> parts;
451 for (int height = 0; height < static_cast<int>(kHeightCount); height++) { 484 for (int height = 0; height < static_cast<int>(kHeightCount); height++) {
452 if (std::bernoulli_distribution(0.5)(rng_)) { 485 if (std::bernoulli_distribution(0.5)(rng_)) {
@@ -472,6 +505,10 @@ private:
472 { 505 {
473 green_uses++; 506 green_uses++;
474 } 507 }
508 if (colour == kOrange)
509 {
510 orange_uses++;
511 }
475 512
476 std::cout << COLOUR_EMOJIS[colour]; 513 std::cout << COLOUR_EMOJIS[colour];
477 } else { 514 } else {
@@ -503,6 +540,13 @@ private:
503 continue; 540 continue;
504 } 541 }
505 542
543 std::string orange_clue;
544 std::string orange_solution;
545 if (orange_uses > 0)
546 {
547 std::tie(orange_clue, orange_solution) = wanderlust_->getPuzzle(rng_);
548 }
549
506 verbly::filter forwardFilter = cleanFilter && wordFilter; 550 verbly::filter forwardFilter = cleanFilter && wordFilter;
507 for (int i=0; i<static_cast<int>(kHeightCount); i++) { 551 for (int i=0; i<static_cast<int>(kHeightCount); i++) {
508 Height height = static_cast<Height>(i); 552 Height height = static_cast<Height>(i);
@@ -510,7 +554,12 @@ private:
510 if (!colour.has_value()) { 554 if (!colour.has_value()) {
511 continue; 555 continue;
512 } 556 }
513 forwardFilter &= makeHintFilter(wordFilter, height, *colour, kTowardSolution); 557 if (*colour == kOrange)
558 {
559 forwardFilter &= (verbly::form::text == orange_solution);
560 } else {
561 forwardFilter &= makeHintFilter(wordFilter, height, *colour, kTowardSolution);
562 }
514 } 563 }
515 564
516 verbly::form solution = database_->forms(forwardFilter).first(); 565 verbly::form solution = database_->forms(forwardFilter).first();
@@ -523,11 +572,17 @@ private:
523 Height height = static_cast<Height>(i); 572 Height height = static_cast<Height>(i);
524 std::optional<Colour>& colour = parts[i]; 573 std::optional<Colour>& colour = parts[i];
525 if (colour.has_value()) { 574 if (colour.has_value()) {
526 verbly::filter questionFilter = makeHintFilter(solution, height, *colour, kTowardQuestion); 575 if (*colour == kOrange)
527 verbly::form questionPart = database_->forms(questionFilter && cleanFilter && wordFilter).first(); 576 {
528 msg_stream << COLOUR_EMOTES[*colour] << " " << questionPart.getText() << std::endl; 577 msg_stream << COLOUR_EMOTES[*colour] << " " << orange_clue << std::endl;
578 admissible &= (verbly::form::text == orange_solution);
579 } else {
580 verbly::filter questionFilter = makeHintFilter(solution, height, *colour, kTowardQuestion);
581 verbly::form questionPart = database_->forms(questionFilter && cleanFilter && wordFilter).first();
582 msg_stream << COLOUR_EMOTES[*colour] << " " << questionPart.getText() << std::endl;
529 583
530 admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution); 584 admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution);
585 }
531 } else { 586 } else {
532 msg_stream << NONE_EMOTE << std::endl; 587 msg_stream << NONE_EMOTE << std::endl;
533 } 588 }
@@ -596,6 +651,7 @@ private:
596 std::mutex answers_mutex_; 651 std::mutex answers_mutex_;
597 std::string scoreboard_endpoint_; 652 std::string scoreboard_endpoint_;
598 std::string scoreboard_secret_code_; 653 std::string scoreboard_secret_code_;
654 std::unique_ptr<wanderlust> wanderlust_;
599}; 655};
600 656
601int main(int argc, char** argv) 657int main(int argc, char** argv)