diff options
| -rw-r--r-- | generator/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | generator/generator.cpp | 107 | ||||
| -rw-r--r-- | generator/generator.h | 3 |
3 files changed, 110 insertions, 2 deletions
| diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 3b66720..fb5dc3c 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt | |||
| @@ -3,7 +3,7 @@ project (generator) | |||
| 3 | 3 | ||
| 4 | add_subdirectory(vendor/fmt) | 4 | add_subdirectory(vendor/fmt) |
| 5 | 5 | ||
| 6 | include_directories(../vendor/hkutil vendor/fmt/include) | 6 | include_directories(vendor/hkutil vendor/fmt/include) |
| 7 | 7 | ||
| 8 | add_executable(generator generator.cpp main.cpp) | 8 | add_executable(generator generator.cpp main.cpp) |
| 9 | set_property(TARGET generator PROPERTY CXX_STANDARD 17) | 9 | set_property(TARGET generator PROPERTY CXX_STANDARD 17) |
| diff --git a/generator/generator.cpp b/generator/generator.cpp index 49018c8..cd13051 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp | |||
| @@ -374,6 +374,10 @@ void generator::run() { | |||
| 374 | for (size_t f_id2 : all_forms) { | 374 | for (size_t f_id2 : all_forms) { |
| 375 | if (f_id1 != f_id2) { | 375 | if (f_id1 != f_id2) { |
| 376 | Form& form = forms_.at(f_id1); | 376 | Form& form = forms_.at(f_id1); |
| 377 | Form& form2 = forms_.at(f_id2); | ||
| 378 | if (form.anagram_set_id == form2.anagram_set_id) { | ||
| 379 | continue; | ||
| 380 | } | ||
| 377 | form.puzzles[kYellowTop].insert(f_id2); | 381 | form.puzzles[kYellowTop].insert(f_id2); |
| 378 | } | 382 | } |
| 379 | } | 383 | } |
| @@ -427,6 +431,9 @@ void generator::run() { | |||
| 427 | for (size_t f_id1 : pronunciation.form_ids) { | 431 | for (size_t f_id1 : pronunciation.form_ids) { |
| 428 | for (size_t f_id2 : all_forms) { | 432 | for (size_t f_id2 : all_forms) { |
| 429 | Form& form = forms_.at(f_id1); | 433 | Form& form = forms_.at(f_id1); |
| 434 | if (form.reverse_form_id == f_id2) { | ||
| 435 | continue; | ||
| 436 | } | ||
| 430 | form.puzzles[kBlackTop].insert(f_id2); | 437 | form.puzzles[kBlackTop].insert(f_id2); |
| 431 | } | 438 | } |
| 432 | } | 439 | } |
| @@ -573,6 +580,12 @@ void generator::run() { | |||
| 573 | for (size_t mero_form_id : merophone.form_ids) { | 580 | for (size_t mero_form_id : merophone.form_ids) { |
| 574 | Form& mero_form = forms_.at(mero_form_id); | 581 | Form& mero_form = forms_.at(mero_form_id); |
| 575 | 582 | ||
| 583 | if (holo_form.text.find(mero_form.text) != | ||
| 584 | std::string::npos) { | ||
| 585 | // We don't want top puzzles that are also middle puzzles. | ||
| 586 | continue; | ||
| 587 | } | ||
| 588 | |||
| 576 | bool word_overlap = false; | 589 | bool word_overlap = false; |
| 577 | for (size_t holo_word_id : holo_form.word_ids) { | 590 | for (size_t holo_word_id : holo_form.word_ids) { |
| 578 | for (size_t mero_word_id : mero_form.word_ids) { | 591 | for (size_t mero_word_id : mero_form.word_ids) { |
| @@ -844,6 +857,25 @@ void generator::run() { | |||
| 844 | } | 857 | } |
| 845 | } | 858 | } |
| 846 | 859 | ||
| 860 | // Orange addition | ||
| 861 | std::vector<std::string> orange_addition; | ||
| 862 | { | ||
| 863 | hatkirby::progress ppgs("Generating orange addition puzzles...", | ||
| 864 | wanderlust_.size()); | ||
| 865 | |||
| 866 | for (const auto& [cipher, form_id] : wanderlust_) { | ||
| 867 | for (const auto& [cipher2, form_id2] : wanderlust_) { | ||
| 868 | if (cipher2 >= cipher) { | ||
| 869 | break; | ||
| 870 | } | ||
| 871 | if (wanderlust_.count(cipher - cipher2)) { | ||
| 872 | orange_addition.push_back(fmt::format( | ||
| 873 | "[{},{},{}]", form_id2, wanderlust_[cipher - cipher2], form_id)); | ||
| 874 | } | ||
| 875 | } | ||
| 876 | } | ||
| 877 | } | ||
| 878 | |||
| 847 | // Count up all of the generated puzzles. | 879 | // Count up all of the generated puzzles. |
| 848 | int total_puzzles = 0; | 880 | int total_puzzles = 0; |
| 849 | int reusable_words = 0; | 881 | int reusable_words = 0; |
| @@ -903,6 +935,27 @@ void generator::run() { | |||
| 903 | std::ofstream output_file(outputPath_); | 935 | std::ofstream output_file(outputPath_); |
| 904 | output_file << "extends Node\n\nvar forms = [" | 936 | output_file << "extends Node\n\nvar forms = [" |
| 905 | << hatkirby::implode(form_entry, ",") << "]" << std::endl; | 937 | << hatkirby::implode(form_entry, ",") << "]" << std::endl; |
| 938 | |||
| 939 | std::vector<std::string> painting_entries; | ||
| 940 | { | ||
| 941 | std::list<std::string> paintings(readFile(datadirPath_ / "paintings.txt")); | ||
| 942 | for (const std::string& line : paintings) { | ||
| 943 | auto parts = hatkirby::split<std::vector<std::string>>(line, ","); | ||
| 944 | painting_entries.push_back( | ||
| 945 | fmt::format("[\"{}\",\"{}\"]", parts[0], parts[1])); | ||
| 946 | } | ||
| 947 | } | ||
| 948 | output_file << "var paintings = [" << hatkirby::implode(painting_entries, ",") | ||
| 949 | << "]" << std::endl; | ||
| 950 | |||
| 951 | std::vector<std::string> cipher_lines; | ||
| 952 | for (const auto& [cipher, form_id] : wanderlust_) { | ||
| 953 | cipher_lines.push_back(std::to_string(form_id)); | ||
| 954 | } | ||
| 955 | output_file << "var wanderlust = [" << hatkirby::implode(cipher_lines, ",") | ||
| 956 | << "]" << std::endl; | ||
| 957 | output_file << "var addition = [" << hatkirby::implode(orange_addition, ",") | ||
| 958 | << "]" << std::endl; | ||
| 906 | } | 959 | } |
| 907 | 960 | ||
| 908 | size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { | 961 | size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { |
| @@ -983,7 +1036,59 @@ size_t generator::LookupOrCreateForm(const std::string& word) { | |||
| 983 | } else { | 1036 | } else { |
| 984 | size_t form_id = forms_.size(); | 1037 | size_t form_id = forms_.size(); |
| 985 | form_by_text_[word] = form_id; | 1038 | form_by_text_[word] = form_id; |
| 986 | forms_.push_back({.id = form_id, .text = word}); | 1039 | std::optional<int> ciphered; |
| 1040 | if (std::all_of(word.begin(), word.end(), [](char ch) { | ||
| 1041 | return ch == 'w' || ch == 'a' || ch == 'n' || ch == 'd' || | ||
| 1042 | ch == 'e' || ch == 'r' || ch == 'l' || ch == 'u' || | ||
| 1043 | ch == 's' || ch == 't'; | ||
| 1044 | })) { | ||
| 1045 | ciphered = 0; | ||
| 1046 | std::string to_cipher = word; | ||
| 1047 | while (!to_cipher.empty()) { | ||
| 1048 | *ciphered *= 10; | ||
| 1049 | switch (to_cipher.back()) { | ||
| 1050 | case 'w': { | ||
| 1051 | *ciphered += 1; | ||
| 1052 | break; | ||
| 1053 | } | ||
| 1054 | case 'a': { | ||
| 1055 | *ciphered += 2; | ||
| 1056 | break; | ||
| 1057 | } | ||
| 1058 | case 'n': { | ||
| 1059 | *ciphered += 3; | ||
| 1060 | break; | ||
| 1061 | } | ||
| 1062 | case 'd': { | ||
| 1063 | *ciphered += 4; | ||
| 1064 | break; | ||
| 1065 | } | ||
| 1066 | case 'e': { | ||
| 1067 | *ciphered += 5; | ||
| 1068 | break; | ||
| 1069 | } | ||
| 1070 | case 'r': { | ||
| 1071 | *ciphered += 6; | ||
| 1072 | break; | ||
| 1073 | } | ||
| 1074 | case 'l': { | ||
| 1075 | *ciphered += 7; | ||
| 1076 | break; | ||
| 1077 | } | ||
| 1078 | case 'u': { | ||
| 1079 | *ciphered += 8; | ||
| 1080 | break; | ||
| 1081 | } | ||
| 1082 | case 's': { | ||
| 1083 | *ciphered += 9; | ||
| 1084 | break; | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | to_cipher.pop_back(); | ||
| 1088 | } | ||
| 1089 | wanderlust_[*ciphered] = form_id; | ||
| 1090 | } | ||
| 1091 | forms_.push_back({.id = form_id, .text = word, .ciphered = ciphered}); | ||
| 987 | 1092 | ||
| 988 | std::string sortedText = word; | 1093 | std::string sortedText = word; |
| 989 | std::sort(sortedText.begin(), sortedText.end()); | 1094 | std::sort(sortedText.begin(), sortedText.end()); |
| diff --git a/generator/generator.h b/generator/generator.h index f89bab9..ea30bd9 100644 --- a/generator/generator.h +++ b/generator/generator.h | |||
| @@ -92,6 +92,7 @@ class generator { | |||
| 92 | std::vector<size_t> pronunciation_ids; | 92 | std::vector<size_t> pronunciation_ids; |
| 93 | std::optional<size_t> anagram_set_id; | 93 | std::optional<size_t> anagram_set_id; |
| 94 | std::optional<size_t> reverse_form_id; | 94 | std::optional<size_t> reverse_form_id; |
| 95 | std::optional<int> ciphered; | ||
| 95 | 96 | ||
| 96 | std::unordered_map<PuzzleType, std::set<size_t>> puzzles; | 97 | std::unordered_map<PuzzleType, std::set<size_t>> puzzles; |
| 97 | }; | 98 | }; |
| @@ -124,6 +125,8 @@ class generator { | |||
| 124 | 125 | ||
| 125 | std::vector<std::vector<size_t>> synsets_; | 126 | std::vector<std::vector<size_t>> synsets_; |
| 126 | std::unordered_map<int, size_t> synset_by_wnid_; | 127 | std::unordered_map<int, size_t> synset_by_wnid_; |
| 128 | |||
| 129 | std::map<int, size_t> wanderlust_; | ||
| 127 | }; | 130 | }; |
| 128 | 131 | ||
| 129 | #endif /* end of include guard: GENERATOR_H_D5C6A724 */ \ No newline at end of file | 132 | #endif /* end of include guard: GENERATOR_H_D5C6A724 */ \ No newline at end of file |
