From 26aa11444ca03571a2bf1ea14d54402094b5c15f Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Fri, 17 Feb 2023 09:51:36 -0500 Subject: many changes (should stop doing this) max_len_diff is an attempt to make mid blue and mid purple more reasonable. It maybe works for blue, but it is not good enough for purple. what we will need to do is limit on how much of the word can be removed, and that's going to require a change to verbly to allow that kind of query. copy_hidden was added for the champion's rest colour pairs. The solution to the pair is found at champion's rest, and the corresponding colour pair has a hint that is just question marks. must_be_broad forces a generated word to be targettable by bottom white/red/blue. this + reusing solution for most bottom white/red/blue puzzles makes those puzzles much more reasonable (though still hard). an attempt to randomise cross tower was made, but I'm not happy with it. hyphens in obscured hints will no longer be obscured. I think obscured hints tend to be too obscured sometimes though, especially when it comes to the number hunt and uncommon words. middle red triviality check: middle red two word puzzles should not just remove one of the words middle yellow triviality check: middle yellow two word puzzles should not just swap the words top yellow triviality check: top yellow should not be able to swap two phonemes that are identical other than stress and say that it rearranged the word. the colorful is partially randomised. champion's rest is as randomsied as it could be (it is likely not reasonable to randomise the red/blue/yellow panels behind the walls. the fearless is partially randomised (besides the chain puzzles). the challenge is partially randomised. --- generator.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 2 deletions(-) (limited to 'generator.cpp') diff --git a/generator.cpp b/generator.cpp index d0ef1a9..c4dd76f 100644 --- a/generator.cpp +++ b/generator.cpp @@ -1,6 +1,9 @@ #include "generator.h" #include #include +#include +#include +#include verbly::filter Generator::MakeHintFilter(verbly::filter subfilter, Height height, Colour colour, FilterDirection filter_direction) { @@ -262,6 +265,11 @@ bool Generator::GenerateSinglePanelImpl(std::string name, Height height, Colour solution = database_->forms(verbly::form::text == word).first(); } else { verbly::filter forward = MakeHintFilter({}, height, colour, kTowardSolution); + if (options.must_be_broad) { + forward &= MakeHintFilter({}, kBottom, kWhite, kTowardSolution); + forward &= MakeHintFilter({}, kBottom, kRed, kTowardSolution); + forward &= MakeHintFilter({}, kBottom, kBlue, kTowardSolution); + } std::vector solutions = database_->forms(forward && GetWordFilter(kTowardSolution, options)).all(); solution = solutions.front();//solutions.at(std::uniform_int_distribution(0, solutions.size())(rng_)); } @@ -282,6 +290,12 @@ bool Generator::GenerateSinglePanelImpl(std::string name, Height height, Colour // Finish early if this is a middle white. if (height == kMiddle && colour == kWhite) { SavePanel(name, solution.getText(), solution.getText(), options); + if (!options.copy_to.empty()) { + SavePanel(options.copy_to, solution.getText(), solution.getText(), options); + } + if (!options.copy_hidden.empty()) { + SavePanel(options.copy_hidden, std::string(solution.getText().size(), '?'), solution.getText(), options); + } return true; } @@ -293,6 +307,9 @@ bool Generator::GenerateSinglePanelImpl(std::string name, Height height, Colour if (IsClueTrivial(height, colour, question, solution)) { return false; } + if (options.max_len_diff >= 0 && std::abs(static_cast(question.getText().size() - solution.getText().size())) > options.max_len_diff) { + return false; + } SavePanel(name, question.getText(), solution.getText(), options); if (!options.copy_to.empty()) { @@ -314,6 +331,11 @@ bool Generator::GenerateDoublePanelImpl(std::string name1, std::string name2, He solution = database_->forms(verbly::form::text == word).first(); } else { verbly::filter forward = MakeHintFilter({}, height, colour, kTowardSolution); + if (options.must_be_broad) { + forward &= MakeHintFilter({}, kBottom, kWhite, kTowardSolution); + forward &= MakeHintFilter({}, kBottom, kRed, kTowardSolution); + forward &= MakeHintFilter({}, kBottom, kBlue, kTowardSolution); + } std::vector solutions = database_->forms(forward && GetWordFilter(kTowardSolution, options)).all(); solution = solutions.front();//solutions.at(std::uniform_int_distribution(0, solutions.size())(rng_)); } @@ -338,6 +360,12 @@ bool Generator::GenerateDoublePanelImpl(std::string name1, std::string name2, He if (IsClueTrivial(height, colour, questions[0], solution) || IsClueTrivial(height, colour, questions[1], solution)) { return false; } + if (options.max_len_diff >= 0) { + if (std::abs(static_cast(questions[0].getText().size() - solution.getText().size())) > options.max_len_diff + || std::abs(static_cast(questions[1].getText().size() - solution.getText().size())) > options.max_len_diff) { + return false; + } + } SavePanel(name1, questions[0].getText(), solution.getText(), options); SavePanel(name2, questions[1].getText(), solution.getText(), options); @@ -370,6 +398,12 @@ bool Generator::GenerateCohintedPanelsImpl(std::string name1, std::string name2, if (IsClueTrivial(height, colour, question, solutions[0]) || IsClueTrivial(height, colour, question, solutions[1])) { return false; } + if (options.max_len_diff >= 0) { + if (std::abs(static_cast(question.getText().size() - solutions[0].getText().size())) > options.max_len_diff + || std::abs(static_cast(question.getText().size() - solutions[1].getText().size())) > options.max_len_diff) { + return false; + } + } SavePanel(name1, question.getText(), solutions[0].getText(), options); SavePanel(name2, question.getText(), solutions[1].getText(), options); @@ -408,6 +442,12 @@ bool Generator::GeneratePairedPanelsImpl(std::string name1, std::string name2, H } } + if (options.max_len_diff >= 0) { + if (std::abs(static_cast(question.getText().size() - solution.getText().size())) > options.max_len_diff) { + return false; + } + } + if (height == kMiddle && colour == kWhite) { SavePanel(name1, question.getText(), question.getText(), options); SavePanel(name2, solution.getText(), solution.getText(), options); @@ -587,7 +627,30 @@ void Generator::GenerateCrossTower( std::string west_other_name3) { std::vector> sets = cross_tower_->GetPuzzleSet(rng_); - + + SavePanel(north_tower_name, "", sets[0][0]); + SavePanel(north_lookout_name, "", sets[0][0]); + SavePanel(north_other_name1, sets[0][1], sets[0][1]); + SavePanel(north_other_name2, sets[0][2], sets[0][2]); + SavePanel(north_other_name3, sets[0][3], sets[0][3]); + + SavePanel(south_tower_name, "", sets[1][0]); + SavePanel(south_lookout_name, "", sets[1][0]); + SavePanel(south_other_name1, sets[1][1], sets[1][1]); + SavePanel(south_other_name2, sets[1][2], sets[1][2]); + SavePanel(south_other_name3, sets[1][3], sets[1][3]); + + SavePanel(east_tower_name, "", sets[2][0]); + SavePanel(east_lookout_name, "", sets[2][0]); + SavePanel(east_other_name1, sets[2][1], sets[2][1]); + SavePanel(east_other_name2, sets[2][2], sets[2][2]); + SavePanel(east_other_name3, sets[2][3], sets[2][3]); + + SavePanel(west_tower_name, "", sets[3][0]); + SavePanel(west_lookout_name, "", sets[3][0]); + SavePanel(west_other_name1, sets[3][1], sets[3][1]); + SavePanel(west_other_name2, sets[3][2], sets[3][2]); + SavePanel(west_other_name3, sets[3][3], sets[3][3]); } void Generator::SavePanel(std::string name, std::string question, std::string answer, GenerateOptions options) { @@ -606,7 +669,7 @@ void Generator::SavePanel(std::string name, std::string question, std::string an std::shuffle(indicies.begin(), indicies.end(), rng_); for (int i=0; iforms((verbly::filter)clue && (verbly::form::merographs %= solution)).all().empty() || !database_->forms((verbly::filter)clue && (verbly::form::holographs %= solution)).all().empty(); + } else if (height == kMiddle && colour == kRed) { + if (clue.getComplexity() == 2 && solution.getComplexity() == 1) { + auto words = hatkirby::split>(clue.getText(), " "); + for (const auto& word : words) { + if (word == solution.getText()) { + return true; + } + } + } + } else if (height == kMiddle && colour == kYellow) { + if (clue.getComplexity() == solution.getComplexity()) { + auto clueWords = hatkirby::split>(clue.getText(), " "); + auto solutionWords = hatkirby::split>(solution.getText(), " "); + std::sort(clueWords.begin(), clueWords.end()); + std::sort(solutionWords.begin(), solutionWords.end()); + if (clueWords == solutionWords) { + return true; + } + } + } else if (height == kTop && colour == kYellow) { + std::set hint_stressless; + for (const verbly::pronunciation& pronunciation : clue.getPronunciations()) { + std::string stressed = hatkirby::implode(pronunciation.getPhonemes(), " "); + std::string stressless; + std::remove_copy_if(stressed.begin(), stressed.end(), std::back_inserter(stressless), &isDigitWrapper); + hint_stressless.insert(stressless); + } + for (const verbly::pronunciation& pronunciation : solution.getPronunciations()) { + std::string stressed = hatkirby::implode(pronunciation.getPhonemes(), " "); + std::string stressless; + std::remove_copy_if(stressed.begin(), stressed.end(), std::back_inserter(stressless), &isDigitWrapper); + if (hint_stressless.count(stressless)) { + return true; + } + } } return false; } -- cgit 1.4.1