From 15d2ad6dd644fd958a5d30ed56d500b8e9d9013a Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 6 Jan 2024 18:53:42 -0500 Subject: Combo generation --- data/profane.txt | 4 +- generator/generator.cpp | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ generator/generator.h | 8 +++ 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/data/profane.txt b/data/profane.txt index b07b823..297b278 100644 --- a/data/profane.txt +++ b/data/profane.txt @@ -1160,4 +1160,6 @@ xxx yankee yellowman zigabo -zipperhead \ No newline at end of file +zipperhead +ass +arouse \ No newline at end of file diff --git a/generator/generator.cpp b/generator/generator.cpp index 435a63b..0017b24 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -882,6 +882,27 @@ void generator::run() { } } + FindComboPuzzles("Generating purple middle red middle combo puzzles...", + kPurpleMiddle, kRedMiddle); + FindComboPuzzles("Generating purple top purple top combo puzzles...", + kPurpleTop, kPurpleTop); + FindComboPuzzles("Generating black middle black bottom combo puzzles...", + kBlackMiddle, kBlackBottom); + FindComboPuzzles("Generating white bottom purple middle combo puzzles...", + kWhiteBottom, kPurpleMiddle); + FindComboPuzzles("Generating black bottom white bottom combo puzzles...", + kBlackBottom, kWhiteBottom); + FindComboPuzzles("Generating blue middle red middle combo puzzles...", + kBlueMiddle, kRedMiddle); + FindComboPuzzles("Generating white bottom white bottom combo puzzles...", + kWhiteBottom, kWhiteBottom); + FindComboPuzzles("Generating blue middle yellow middle combo puzzles...", + kBlueMiddle, kYellowMiddle); + FindComboPuzzles("Generating black bottom blue middle combo puzzles...", + kBlackBottom, kBlueMiddle); + FindComboPuzzles("Generating yellow top yellow middle combo puzzles...", + kYellowTop, kYellowMiddle); + // Count up all of the generated puzzles. int total_puzzles = 0; int reusable_words = 0; @@ -916,6 +937,26 @@ void generator::run() { std::cout << "Purple tops: " << per_puzzle_type[kPurpleTop] << std::endl; std::cout << "Purple middles: " << per_puzzle_type[kPurpleMiddle] << std::endl; + std::cout << "Purple middle red middle combos: " + << combos_[kPurpleMiddle][kRedMiddle].size() << std::endl; + std::cout << "Purple top purple top combos: " + << combos_[kPurpleTop][kPurpleTop].size() << std::endl; + std::cout << "Black middle black bottom combos: " + << combos_[kBlackMiddle][kBlackBottom].size() << std::endl; + std::cout << "White bottom purple middle combos: " + << combos_[kWhiteBottom][kPurpleMiddle].size() << std::endl; + std::cout << "Black bottom white bottom combos: " + << combos_[kBlackBottom][kWhiteBottom].size() << std::endl; + std::cout << "Blue middle red middle combos: " + << combos_[kBlueMiddle][kRedMiddle].size() << std::endl; + std::cout << "White bottom white bottom combos: " + << combos_[kWhiteBottom][kWhiteBottom].size() << std::endl; + std::cout << "Blue middle yellow middle combos: " + << combos_[kBlueMiddle][kYellowMiddle].size() << std::endl; + std::cout << "Black bottom blue middle combos: " + << combos_[kBlackBottom][kBlueMiddle].size() << std::endl; + std::cout << "Yellow top yellow middle combos: " + << combos_[kYellowTop][kYellowMiddle].size() << std::endl; std::vector form_entry; form_entry.reserve(forms_.size()); @@ -962,6 +1003,38 @@ void generator::run() { << "]" << std::endl; output_file << "var addition = [" << hatkirby::implode(orange_addition, ",") << "]" << std::endl; + + std::vector walls_entries; + { + std::list walls(readFile(datadirPath_ / "walls.txt")); + for (const std::string& line : walls) { + auto parts = hatkirby::split>(line, ","); + walls_entries.push_back( + fmt::format("[\"{}\",\"{}\"]", parts[0], parts[1])); + } + } + output_file << "var walls_puzzles = [" + << hatkirby::implode(walls_entries, ",") << "]" << std::endl; + + std::vector combo_entries; + for (const auto& [left_type, left_join] : combos_) { + std::vector left_entries; + for (const auto& [right_type, choices] : left_join) { + std::vector choice_entries; + for (const auto& [hint1, hint2, answer] : choices) { + choice_entries.push_back( + fmt::format("[{},{},{}]", hint1, hint2, answer)); + } + left_entries.push_back( + fmt::format("{}:[{}]", static_cast(right_type), + hatkirby::implode(choice_entries, ","))); + } + combo_entries.push_back(fmt::format("{}:{{{}}}]", + static_cast(left_type), + hatkirby::implode(left_entries, ","))); + } + output_file << "var combos = {" << hatkirby::implode(combo_entries, ",") + << "}" << std::endl; } size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { @@ -1111,6 +1184,7 @@ size_t generator::LookupOrCreateWord(const std::string& word) { size_t form_id = LookupOrCreateForm(word); words_.push_back({.id = word_id, .base_form_id = form_id}); AddFormToWord(form_id, word_id); + forms_[form_id].is_base_form = true; return word_id; } @@ -1163,3 +1237,55 @@ void generator::AddPronunciationToAnaphoneSet( pronunciations_[pronunciation_id].anaphone_set_id = anaphone_set_id; } } + +void generator::FindComboPuzzles(std::string text, PuzzleType left_type, + PuzzleType right_type) { + hatkirby::progress ppgs(text, forms_.size()); + + for (Form& left_form : forms_) { + ppgs.update(); + + if (left_form.text.size() < 3 || !left_form.puzzles.count(left_type)) + continue; + if (left_type == kWhiteBottom && left_form.puzzles[left_type].size() > 3) + continue; + + for (Form& right_form : forms_) { + if (right_type == kWhiteBottom && + right_form.puzzles[right_type].size() > 3) + continue; + if (right_form.text.size() >= 3 && right_form.puzzles.count(right_type) && + form_by_text_.count(left_form.text + right_form.text)) { + for (size_t left_hint_id : left_form.puzzles[left_type]) { + Form& left_hint = forms_[left_hint_id]; + for (size_t right_hint_id : right_form.puzzles[right_type]) { + Form& right_hint = forms_[right_hint_id]; + + if (left_hint.text.size() + right_hint.text.size() > 15) continue; + + if (left_type == kPurpleMiddle && + left_hint.text.size() != left_form.text.size()) + continue; + if (right_type == kPurpleMiddle && + right_hint.text.size() != right_form.text.size()) + continue; + if (right_type == kRedMiddle && + right_hint.text.size() - right_form.text.size() > 3) + continue; + + if (form_by_text_.count(left_hint.text + right_hint.text)) { + combos_[left_type][right_type].emplace_back( + form_by_text_[left_hint.text + right_hint.text], -1, + form_by_text_[left_form.text + right_form.text]); + } else if (left_hint.is_base_form && right_hint.is_base_form && + !(left_type == kPurpleTop && right_type == kPurpleTop)) { + combos_[left_type][right_type].emplace_back( + left_hint_id, right_hint_id, + form_by_text_[left_form.text + right_form.text]); + } + } + } + } + } + } +} diff --git a/generator/generator.h b/generator/generator.h index ea30bd9..cf304ea 100644 --- a/generator/generator.h +++ b/generator/generator.h @@ -61,6 +61,9 @@ class generator { void AddPronunciationToAnaphoneSet(size_t pronunciation_id, const std::string& sorted_phonemes); + void FindComboPuzzles(std::string text, PuzzleType left_type, + PuzzleType right_type); + // Input std::string agidPath_; @@ -88,6 +91,7 @@ class generator { struct Form { size_t id; std::string text; + bool is_base_form = false; std::vector word_ids; std::vector pronunciation_ids; std::optional anagram_set_id; @@ -127,6 +131,10 @@ class generator { std::unordered_map synset_by_wnid_; std::map wanderlust_; + + std::map>>> + combos_; }; #endif /* end of include guard: GENERATOR_H_D5C6A724 */ \ No newline at end of file -- cgit 1.4.1