diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2023-02-18 09:30:20 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2023-02-18 09:30:20 -0500 |
commit | 1cf317067d40fd64219b18e19c0772748affd726 (patch) | |
tree | 0759dd6a8742081e4565258f11f6efa1b71740d7 /lingo.cpp | |
parent | f6c99467e83b7735bf4c6b13736726adc2d01d62 (diff) | |
download | lingo-1cf317067d40fd64219b18e19c0772748affd726.tar.gz lingo-1cf317067d40fd64219b18e19c0772748affd726.tar.bz2 lingo-1cf317067d40fd64219b18e19c0772748affd726.zip |
Some better triviality checks
If a hint is identical to the solution, it is trivial. If a multi-word hint contains a single word solution, or vice versa, it is trivial.
Diffstat (limited to 'lingo.cpp')
-rw-r--r-- | lingo.cpp | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lingo.cpp b/lingo.cpp index ea4697d..4c95fcf 100644 --- a/lingo.cpp +++ b/lingo.cpp | |||
@@ -465,6 +465,33 @@ private: | |||
465 | 465 | ||
466 | bool isClueTrivial(Height height, Colour colour, const verbly::form& clue, const verbly::form& solution) const | 466 | bool isClueTrivial(Height height, Colour colour, const verbly::form& clue, const verbly::form& solution) const |
467 | { | 467 | { |
468 | if (height == kMiddle && colour == kWhite) { | ||
469 | // Triviality is checked elsewhere. | ||
470 | return false; | ||
471 | } | ||
472 | |||
473 | if (clue.getText() == solution.getText()) { | ||
474 | return true; | ||
475 | } | ||
476 | |||
477 | if (clue.getComplexity() > 1 && solution.getComplexity() == 1) { | ||
478 | auto words = hatkirby::split<std::vector<std::string>>(clue.getText(), " "); | ||
479 | for (const auto& word : words) { | ||
480 | if (word == solution.getText()) { | ||
481 | return true; | ||
482 | } | ||
483 | } | ||
484 | } | ||
485 | |||
486 | if (clue.getComplexity() == 1 && solution.getComplexity() > 1) { | ||
487 | auto words = hatkirby::split<std::vector<std::string>>(solution.getText(), " "); | ||
488 | for (const auto& word : words) { | ||
489 | if (word == clue.getText()) { | ||
490 | return true; | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | |||
468 | if (height == kTop && colour == kWhite) | 495 | if (height == kTop && colour == kWhite) |
469 | { | 496 | { |
470 | return !database_->forms((verbly::filter)clue && (verbly::word::synonyms %= solution)).all().empty(); | 497 | return !database_->forms((verbly::filter)clue && (verbly::word::synonyms %= solution)).all().empty(); |
@@ -481,17 +508,8 @@ private: | |||
481 | } else if (height == kTop && colour == kPurple) | 508 | } else if (height == kTop && colour == kPurple) |
482 | { | 509 | { |
483 | return clue.getId() == solution.getId(); | 510 | return clue.getId() == solution.getId(); |
484 | } else if (height == kMiddle && colour == kRed) { | ||
485 | if (clue.getComplexity() == 2 && solution.getComplexity() == 1) { | ||
486 | auto words = hatkirby::split<std::vector<std::string>>(clue.getText(), " "); | ||
487 | for (const auto& word : words) { | ||
488 | if (word == solution.getText()) { | ||
489 | return true; | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | } else if (height == kMiddle && colour == kYellow) { | 511 | } else if (height == kMiddle && colour == kYellow) { |
494 | if (clue.getComplexity() == solution.getComplexity()) { | 512 | if (clue.getComplexity() > 1 && clue.getComplexity() == solution.getComplexity()) { |
495 | auto clueWords = hatkirby::split<std::vector<std::string>>(clue.getText(), " "); | 513 | auto clueWords = hatkirby::split<std::vector<std::string>>(clue.getText(), " "); |
496 | auto solutionWords = hatkirby::split<std::vector<std::string>>(solution.getText(), " "); | 514 | auto solutionWords = hatkirby::split<std::vector<std::string>>(solution.getText(), " "); |
497 | std::sort(clueWords.begin(), clueWords.end()); | 515 | std::sort(clueWords.begin(), clueWords.end()); |
@@ -709,6 +727,7 @@ private: | |||
709 | std::ostringstream msg_stream; | 727 | std::ostringstream msg_stream; |
710 | bool trivial = false; | 728 | bool trivial = false; |
711 | bool profane = false; | 729 | bool profane = false; |
730 | std::string bad_hint; | ||
712 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { | 731 | for (int i=0; i<static_cast<int>(kHeightCount); i++) { |
713 | Height height = static_cast<Height>(i); | 732 | Height height = static_cast<Height>(i); |
714 | std::optional<Colour>& colour = parts[i]; | 733 | std::optional<Colour>& colour = parts[i]; |
@@ -736,6 +755,12 @@ private: | |||
736 | } | 755 | } |
737 | 756 | ||
738 | chosenHints[i] = question; | 757 | chosenHints[i] = question; |
758 | |||
759 | if (chosenHints[i] == questionPart.getText()) { | ||
760 | trivial = true; | ||
761 | bad_hint = questionPart.getText(); | ||
762 | break; | ||
763 | } | ||
739 | } else { | 764 | } else { |
740 | chosenHints[i] = questionPart.getText(); | 765 | chosenHints[i] = questionPart.getText(); |
741 | } | 766 | } |
@@ -743,10 +768,13 @@ private: | |||
743 | if (isClueTrivial(height, *colour, questionPart, solution)) | 768 | if (isClueTrivial(height, *colour, questionPart, solution)) |
744 | { | 769 | { |
745 | trivial = true; | 770 | trivial = true; |
771 | bad_hint = questionPart.getText(); | ||
746 | break; | 772 | break; |
747 | } | 773 | } |
748 | if (isProfane(questionPart)) { | 774 | if (isProfane(questionPart)) { |
749 | profane = true; | 775 | profane = true; |
776 | bad_hint = questionPart.getText(); | ||
777 | break; | ||
750 | } | 778 | } |
751 | 779 | ||
752 | admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution); | 780 | admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution); |
@@ -756,12 +784,12 @@ private: | |||
756 | 784 | ||
757 | if (trivial) | 785 | if (trivial) |
758 | { | 786 | { |
759 | std::cout << "Puzzle is trivial." << std::endl; | 787 | std::cout << "Puzzle is trivial (" << bad_hint << ")." << std::endl; |
760 | continue; | 788 | continue; |
761 | } | 789 | } |
762 | if (profane) | 790 | if (profane) |
763 | { | 791 | { |
764 | std::cout << "Puzzle is profane." << std::endl; | 792 | std::cout << "Puzzle is profane (" << bad_hint << ")." << std::endl; |
765 | continue; | 793 | continue; |
766 | } | 794 | } |
767 | 795 | ||
@@ -848,8 +876,7 @@ private: | |||
848 | std::cout << ex.what() << std::endl; | 876 | std::cout << ex.what() << std::endl; |
849 | } | 877 | } |
850 | 878 | ||
851 | std::cout << "Waiting five seconds then trying again..." << std::endl; | 879 | std::cout << "Trying again..." << std::endl; |
852 | std::this_thread::sleep_for(std::chrono::seconds(5)); | ||
853 | } | 880 | } |
854 | 881 | ||
855 | // generatePuzzle is only called when there is no cached puzzle and there | 882 | // generatePuzzle is only called when there is no cached puzzle and there |