summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lingo.cpp133
1 files changed, 86 insertions, 47 deletions
diff --git a/lingo.cpp b/lingo.cpp index cd68814..077bc3c 100644 --- a/lingo.cpp +++ b/lingo.cpp
@@ -428,6 +428,22 @@ public:
428 428
429private: 429private:
430 430
431 bool isClueTrivial(Height height, Colour colour, const verbly::form& clue, const verbly::form& solution) const
432 {
433 if (height == kTop && colour == kWhite)
434 {
435 return !database_->forms((verbly::filter)clue && (verbly::word::synonyms %= solution)).all().empty();
436 } else if (height == kBottom && colour == kWhite)
437 {
438 return !database_->forms((verbly::filter)clue && (verbly::form::pronunciations %= solution)).all().empty();
439 } else if (height == kBottom && colour == kBlack)
440 {
441 return !database_->forms((verbly::filter)clue && (verbly::form::merographs %= solution)).all().empty()
442 || !database_->forms((verbly::filter)clue && (verbly::form::holographs %= solution)).all().empty();
443 }
444 return false;
445 }
446
431 void generatePuzzle() 447 void generatePuzzle()
432 { 448 {
433 std::cout << "Generating puzzle..." << std::endl; 449 std::cout << "Generating puzzle..." << std::endl;
@@ -568,70 +584,93 @@ private:
568 } 584 }
569 585
570 verbly::form solution = database_->forms(forwardFilter).first(); 586 verbly::form solution = database_->forms(forwardFilter).first();
571 verbly::filter admissible = cleanFilter && (verbly::form::proper == false);
572 587
573 std::cout << "Solution decided: " << solution.getText() << std::endl; 588 std::cout << "Solution decided: " << solution.getText() << std::endl;
574 589
575 std::ostringstream msg_stream; 590 bool made_puzzle = false;
576 for (int i=0; i<static_cast<int>(kHeightCount); i++) { 591 for (int i=0; i<10; i++)
577 Height height = static_cast<Height>(i); 592 {
578 std::optional<Colour>& colour = parts[i]; 593 verbly::filter admissible = cleanFilter && (verbly::form::proper == false) && (verbly::form::length == static_cast<int>(solution.getText().size()));
579 if (colour.has_value()) { 594 std::ostringstream msg_stream;
580 if (*colour == kOrange) 595 bool trivial = false;
581 { 596 for (int i=0; i<static_cast<int>(kHeightCount); i++) {
582 msg_stream << COLOUR_EMOTES[*colour] << " " << orange_clue << std::endl; 597 Height height = static_cast<Height>(i);
583 admissible &= (verbly::form::text == orange_solution); 598 std::optional<Colour>& colour = parts[i];
599 if (colour.has_value()) {
600 if (*colour == kOrange)
601 {
602 msg_stream << COLOUR_EMOTES[*colour] << " " << orange_clue << std::endl;
603 admissible &= (verbly::form::text == orange_solution);
604 } else {
605 verbly::filter questionFilter = makeHintFilter(solution, height, *colour, kTowardQuestion);
606 verbly::form questionPart = database_->forms(questionFilter && cleanFilter && wordFilter).first();
607 msg_stream << COLOUR_EMOTES[*colour] << " " << questionPart.getText() << std::endl;
608
609 if (isClueTrivial(height, *colour, questionPart, solution))
610 {
611 trivial = true;
612 break;
613 }
614
615 admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution);
616 }
584 } else { 617 } else {
585 verbly::filter questionFilter = makeHintFilter(solution, height, *colour, kTowardQuestion); 618 msg_stream << NONE_EMOTE << std::endl;
586 verbly::form questionPart = database_->forms(questionFilter && cleanFilter && wordFilter).first();
587 msg_stream << COLOUR_EMOTES[*colour] << " " << questionPart.getText() << std::endl;
588
589 admissible &= makeHintFilter(questionPart, height, *colour, kTowardSolution);
590 } 619 }
591 } else {
592 msg_stream << NONE_EMOTE << std::endl;
593 } 620 }
594 }
595 auto byspace = hatkirby::split<std::list<std::string>>(solution.getText(), " ");
596 std::list<std::string> lens;
597 for (const std::string& wordpart : byspace)
598 {
599 lens.push_back(std::to_string(wordpart.size()));
600 }
601 621
602 msg_stream << "(" << hatkirby::implode(std::begin(lens), std::end(lens), " ") << ")"; 622 if (trivial)
603 623 {
604 std::string message_text = msg_stream.str(); 624 std::cout << "Puzzle is trivial." << std::endl;
605 std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl; 625 continue;
626 }
606 627
607 std::vector<verbly::form> admissibleResults = database_->forms(admissible, {}, 10).all(); 628 auto byspace = hatkirby::split<std::list<std::string>>(solution.getText(), " ");
608 if (green_uses > 0 || (admissibleResults.size() <= (hints == 1 ? 2 : 5))) 629 std::list<std::string> lens;
609 { 630 for (const std::string& wordpart : byspace)
610 genpuzzle = std::make_unique<puzzle>();
611 genpuzzle->message = message_text;
612 genpuzzle->solution = hatkirby::lowercase(solution.getText());
613 while (genpuzzle->solution.find(" ") != std::string::npos)
614 { 631 {
615 genpuzzle->solution.erase(genpuzzle->solution.find(" "), 1); 632 lens.push_back(std::to_string(wordpart.size()));
616 } 633 }
617 634
618 if (green_uses > 0) 635 msg_stream << "(" << hatkirby::implode(std::begin(lens), std::end(lens), " ") << ")";
636
637 std::string message_text = msg_stream.str();
638 std::cout << message_text << std::endl << std::endl << solution.getText() << std::endl;
639
640 std::vector<verbly::form> admissibleResults = database_->forms(admissible, {}, 10).all();
641 if (green_uses > 0 || (admissibleResults.size() <= (hints == 1 ? 2 : 5)))
619 { 642 {
620 verbly::notion notion = database_->notions( 643 genpuzzle = std::make_unique<puzzle>();
621 (verbly::notion::numOfImages > 1) && solution).first(); 644 genpuzzle->message = message_text;
622 auto [image, extension] = imagenet_->getImageForNotion(notion.getId(), rng_); 645 genpuzzle->solution = hatkirby::lowercase(solution.getText());
623 if (image.empty()) 646 while (genpuzzle->solution.find(" ") != std::string::npos)
624 { 647 {
625 throw std::runtime_error("Could not find image for green hint."); 648 genpuzzle->solution.erase(genpuzzle->solution.find(" "), 1);
626 } 649 }
627 650
628 genpuzzle->attachment_name = std::string("SPOILER_image.") + extension; 651 if (green_uses > 0)
629 genpuzzle->attachment_content = std::move(image); 652 {
630 } 653 verbly::notion notion = database_->notions(
654 (verbly::notion::numOfImages > 1) && solution).first();
655 auto [image, extension] = imagenet_->getImageForNotion(notion.getId(), rng_);
656 if (image.empty())
657 {
658 throw std::runtime_error("Could not find image for green hint.");
659 }
631 660
661 genpuzzle->attachment_name = std::string("SPOILER_image.") + extension;
662 genpuzzle->attachment_content = std::move(image);
663 }
664
665 made_puzzle = true;
666 break;
667 } else {
668 std::cout << "Too many (" << admissibleResults.size() << ") results." << std::endl;
669 }
670 }
671 if (made_puzzle)
672 {
632 break; 673 break;
633 } else {
634 std::cout << "Too many (" << admissibleResults.size() << ") results." << std::endl;
635 } 674 }
636 } catch (const std::exception& ex) { 675 } catch (const std::exception& ex) {
637 std::cout << ex.what() << std::endl; 676 std::cout << ex.what() << std::endl;