viresh-ratnakar / exolve

Online interactive crossword software in JavaScript
MIT License
71 stars 15 forks source link

Event when puzzle has been solved by the user #58

Closed splattne closed 3 years ago

splattne commented 3 years ago

Is there a way to know when the puzzle has been solved by the user? Perhaps an event I can attach a handler or the status of the puzzle?

By the way, thanks for this amazing application!

lenniebriscoe commented 3 years ago

see #46 for a similar question.

Also if you create your crossword with an exolve-id i.e. exolve-id: abc123 in your code (without having to use a customizeExolve function you can then use:

var exolve = (window as any).exolvePuzzles['abc123'];
if(exolve.checkAll(false, false)){
    console.log('solved');
}
viresh-ratnakar commented 3 years ago

You can do something like this:

function customizeExolve(puz) {
  puz.isSolved = puz.numCellsToFill == puz.numCellsFilled;
  // Override updateAndSaveState() to check transition of isSolved from F to T.
  puz.updateAndSaveState = (function() {
    const cachedUSS = puz.updateAndSaveState;
    return function() {
      cachedUSS.apply(this);
      const isSolved = puz.numCellsToFill == puz.numCellsFilled;
      if (!puz.isSolved && isSolved) {
        // Let the displayed cells get updated before showing the alert.
        setTimeout(function(){
          alert("You have finished solving the puzzle!");
        }, 0);
      }
      puz.isSolved = isSolved;
    }
  })();
}

In addition, as @lenniebriscoe says, you can call checkAll() within the above code if you want, if the solutions are available.

splattne commented 3 years ago

Thank you!

This works well, but there's one catch. It doesn't check if all solutions given by the users are correct. Is there a way to see if there are incorrect answers?

EDIT: Nevermind, I saw @lenniebriscoe 's answer. I guess I could do it that way.

splattne commented 3 years ago

I used the customizeExolve and used a modified version of checkAll. I couldn't use checkAll() because it would result in an endless recursion of updateAndSaveStatecalls.


function customizeExolve(puzzle) {
     puzzle.checkAllAnswers = function() {
         let allCorrect = true;

         for (let row = 0; row < this.gridHeight; row++) {
             for (let col = 0; col < this.gridWidth; col++) {
                 let gridCell = this.grid[row][col];
                 if (!gridCell.isLight && !gridCell.isDgmless) continue;
                 if (gridCell.currLetter === gridCell.solution) continue;

                 allCorrect = false;
             }
         }

         return allCorrect;
     }

     puzzle.isSolved = puzzle.numCellsToFill === puzzle.numCellsFilled && puzzle.checkAllAnswers();

     // Override updateAndSaveState() to check transition of isSolved from F to T.
     puzzle.updateAndSaveState = (function() {
         const cachedUss = puzzle.updateAndSaveState;

         return function() {
             cachedUss.apply(this);

             var isSolved = puzzle.numCellsToFill === puzzle.numCellsFilled && puzzle.checkAllAnswers();

             if (!puzzle.isSolved && isSolved) {
                 // Let the displayed cells get updated before showing the alert.
                 setTimeout(function(){
                     alert('❤️ Gratulation!\nSie haben das Rätsel korrekt gelöst.');
                 }, 100);
             }
              puzzle.isSolved = isSolved;
         }
     })();
 }```
viresh-ratnakar commented 2 years ago

Following up on this old thread: I checked in Exolve v1.18 today, which adds the firing of a completion event.

Details at: https://github.com/viresh-ratnakar/exolve/blob/master/README.md#completion-event