summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--generate_orange.rb56
-rw-r--r--lingo.cpp70
2 files changed, 119 insertions, 7 deletions
diff --git a/generate_orange.rb b/generate_orange.rb new file mode 100644 index 0000000..310f823 --- /dev/null +++ b/generate_orange.rb
@@ -0,0 +1,56 @@
1require 'sqlite3'
2
3db = SQLite3::Database.open ARGV[0]
4form_rows = db.query "SELECT form FROM forms WHERE proper = 0"
5
6wanderlust = {}
7wanderlust["w"] = "1"
8wanderlust["a"] = "2"
9wanderlust["n"] = "3"
10wanderlust["d"] = "4"
11wanderlust["e"] = "5"
12wanderlust["r"] = "6"
13wanderlust["l"] = "7"
14wanderlust["u"] = "8"
15wanderlust["s"] = "9"
16wanderlust["t"] = "0"
17
18forms = form_rows.map {|row| row[0].downcase}
19orange_forms = forms.reject {|form| /^[wanderlust]*$/.match(form).nil?}.select {|form| form.length >= 3}
20words = orange_forms.map do |form|
21 oranged = form.chars.map {|letter| wanderlust[letter]}.join
22 [form, oranged, oranged.to_i]
23 end
24words.sort_by! {|word| word[2]}
25
26puts words.length
27puts words[10]
28puts words.sample
29puts ""
30
31oranges_by_num = {}
32puzzles = []
33words.each do |vals|
34 oranges_by_num.each do |num, form|
35 opposite = (vals[2] - num.to_i).to_s
36 if oranges_by_num.include? opposite
37 puzzles << ["#{form} + #{oranges_by_num[opposite]}", vals[0]]
38 puzzles << ["#{oranges_by_num[opposite]} + #{form}", vals[0]]
39 end
40 opposite = "0" + opposite
41 if oranges_by_num.include? opposite
42 puzzles << ["#{form} + #{oranges_by_num[opposite]}", vals[0]]
43 puzzles << ["#{oranges_by_num[opposite]} + #{form}", vals[0]]
44 end
45 end
46 oranges_by_num[vals[1]] = vals[0]
47end
48
49puts puzzles.length
50puts puzzles.sample
51
52File.open("wanderlust.txt", "w") do |f|
53 puzzles.each do |puzzle|
54 f.write("#{puzzle[0]}\n#{puzzle[1]}\n")
55 end
56end
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)