Skip to content

Commit

Permalink
Merge pull request #210 from jpd236/no-solution
Browse files Browse the repository at this point in the history
Improve handling of puzzles without solutions.
  • Loading branch information
mrichards42 committed Oct 6, 2023
2 parents ce16297 + a1898a4 commit d5762ac
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
4 changes: 4 additions & 0 deletions puz/formats/ipuz/load_ipuz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ bool ipuzParser::DoLoadPuzzle(Puzzle * puz, json::Value * root)
}
});
}
else
{
puz->GetGrid().SetFlag(FLAG_NO_SOLUTION);
}

// User grid
if (doc->Contains(puzT("saved")))
Expand Down
9 changes: 8 additions & 1 deletion puz/formats/jpz/load_jpz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ bool jpzParser::DoLoadPuzzle(Puzzle * puz, xml::document & doc)
}

// Grid cells
bool has_solution = false;
xml::node cell = RequireChild(grid_node, "cell");
for (; cell; cell = cell.next_sibling("cell"))
{
Expand Down Expand Up @@ -260,7 +261,10 @@ bool jpzParser::DoLoadPuzzle(Puzzle * puz, xml::document & doc)
else // type == puzT("letter") || type == puzT("clue")
{
square->SetMissing(false);
square->SetSolution(GetAttribute(cell, "solution"));
string_t solution = GetAttribute(cell, "solution");
square->SetSolution(solution);
if (!solution.empty())
has_solution = true;
square->SetText(GetAttribute(cell, "solve-state"));
if (type == puzT("clue"))
square->SetAnnotation(true);
Expand Down Expand Up @@ -314,6 +318,9 @@ bool jpzParser::DoLoadPuzzle(Puzzle * puz, xml::document & doc)
image.child_value("encoded-image"));
}
}

if (!has_solution)
grid.SetFlag(FLAG_NO_SOLUTION);
}

// Words
Expand Down
28 changes: 16 additions & 12 deletions puz/formats/jpz/save_jpz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ void SaveJpz(Puzzle * puz, const std::string & filename, void * /* dummy */)

if (grid.IsScrambled())
throw ConversionError("Jpz does not support scrambled puzzles");
if (! grid.HasSolution())
throw ConversionError("Jpz does not support puzzles without a solution");
if (grid.GetType() == TYPE_DIAGRAMLESS)
throw ConversionError("Can't save a diagramless puzzle as jpz.");

Expand All @@ -88,16 +86,21 @@ void SaveJpz(Puzzle * puz, const std::string & filename, void * /* dummy */)

xml::node actions = settings.append_child("actions");
actions.append_attribute("buttons-layout") = "below";
actions.append_child("check").append_attribute("label") = "Check";
actions.append_child("reveal-letter").append_attribute("label") =
"Reveal Letter";
actions.append_child("reveal-word").append_attribute("label") =
"Reveal Word";
actions.append_child("revert").append_attribute("label") = "Clear All";
actions.append_child("solution").append_attribute("label") = "Solution";

xml::node completion = settings.append_child("completion");
completion.append_attribute("only-if-correct") = "true";
if (grid.HasSolution()) {
actions.append_child("check").append_attribute("label") = "Check";
actions.append_child("reveal-letter").append_attribute("label") =
"Reveal Letter";
actions.append_child("reveal-word").append_attribute("label") =
"Reveal Word";
actions.append_child("solution").append_attribute("label") = "Solution";
completion.append_attribute("only-if-correct") = "true";
}
else {
completion.append_attribute("only-if-correct") = "false";
}

string_t message = puz->GetMeta(puzT("completion"));
if (message.empty()) {
message = puzT("Congratulations, you have solved the puzzle!");
Expand Down Expand Up @@ -172,8 +175,9 @@ void SaveJpz(Puzzle * puz, const std::string & filename, void * /* dummy */)
{
if (square->IsAnnotation())
cell.append_attribute("type") = "clue";
cell.append_attribute("solution") =
encode_utf8(square->GetSolution()).c_str();
if (grid.HasSolution())
cell.append_attribute("solution") =
encode_utf8(square->GetSolution()).c_str();
if (square->HasNumber())
cell.append_attribute("number") =
encode_utf8(square->GetNumber()).c_str();
Expand Down
18 changes: 9 additions & 9 deletions src/XGridCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,24 +340,24 @@ XGridCtrl::UnscrambleSolution(unsigned short key)
// Helper for IsCorrect and GetStats
CorrectStatus GetCorrectStatus(const puz::Grid * grid, bool correct)
{
// We *can* test scrambled puzzles! Not sure why I didn't think of
// this before. (Inspired by Alex Boisvert:
// http://alexboisvert.com/software.html#check)
if (correct)
if (!grid->HasSolution())
{
return UNCHECKABLE_PUZZLE;
}
else if (correct)
{
return CORRECT_PUZZLE;
}
else if (grid->IsScrambled())
{
// We *can* test scrambled puzzles! Not sure why I didn't think of
// this before. (Inspired by Alex Boisvert:
// http://alexboisvert.com/software.html#check)
if (grid->CheckScrambledGrid())
return CORRECT_PUZZLE;
else
return INCORRECT_PUZZLE;
}
else if (! grid->HasSolution())
{
return UNCHECKABLE_PUZZLE;
}
else
{
return INCORRECT_PUZZLE;
Expand Down Expand Up @@ -403,7 +403,7 @@ XGridCtrl::GetStats(GridStats * stats) const
if (square->IsBlank())
{
++stats->blank;
if (square->IsSolutionBlank())
if (m_grid->HasSolution() && square->IsSolutionBlank())
++stats->blank_correct;
}
// If the puzzle is correct so far, and without blanks (that do
Expand Down

0 comments on commit d5762ac

Please sign in to comment.