summary refs log tree commit diff stats
path: root/lingo.cpp
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2023-02-18 09:30:20 -0500
committerStar Rauchenberger <fefferburbia@gmail.com>2023-02-18 09:30:20 -0500
commit1cf317067d40fd64219b18e19c0772748affd726 (patch)
tree0759dd6a8742081e4565258f11f6efa1b71740d7 /lingo.cpp
parentf6c99467e83b7735bf4c6b13736726adc2d01d62 (diff)
downloadlingo-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.cpp55
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