Building a Sudoku web app (part2, JavaScript client)

Building a Sudoku web app (part2, JavaScript client)

Introduction

JavaScript implementation of a Sudoku puzzle. Uses a back-end PHP API.

Note: These experiments are part of the CodingSummer21 activities and their goal is not to provide a perfect solution, but some solution simple to understand so that students can fork and improve.

GitHub: github.com/codingsummer21/sudoku-js

Start Game

Clicking the New Game button will fetch a random Sudoku puzzle from the PHP back-end API:

function getPuzzle() {
    fetch('http://localhost/cs21/sudoku.back/api/v1/get_sudoku.php')
        .then(response => response.json())
        .then(data => {
            sudoku = data
            puzzlePlaying = data['puzzle']
            displayPuzzle()
            displayButtons()
            document.getElementById("result").innerHTML = " "
        })
}

will update the following variables:
sudoku: Holds the object provided from the API. The puzzle id is useful for any future request to the API.
puzlePlaying: A copy of the puzzle string which will be updated each time the user selects a value.

and will display the puzzle, display the buttons with 1-9 values which are used to play, and will clear any message from a previous game.

The displayPuzzle function uses the puzzlePlaying variable and the original puzzle in sudoku variable in order to display the puzzle:

function displayPuzzle() {
    let puzzle = sudoku['puzzle']
    let tbl = '<tr>'
    for(let i = 0; i < puzzle.length; i++) {
        if(i % 9 == 0 && i > 0) {
            tbl += '</tr><tr>'
        }
        let ch = puzzle.charAt(i);
        let chPlaying = puzzlePlaying.charAt(i)
        if(chPlaying == 0) {
            tbl += '<td onclick="tdClicked(this.id)"  id="td' + i + '">&nbsp;</td>'
        }
        else if(ch == 0) {
            tbl += '<td id="td' + i + '">' + ch + '</td>'
        }
        else {
            tbl += '<td class="initial-value">' + ch + '</td>'
        }
    }
    tbl += '</tr>'
    document.getElementById("sudoku-table").innerHTML = tbl
}

If a value is 0 in the puzzlePlaying the cell is empty.
Else if it was 0 in the original puzzle it displays the current value.
Else, if the cell contains a value provided initially by the puzzle, it displays the original value with different style and the cell is not clickable.

Play

Clicking on any of the buttons with number values (1-9) the selectButton function is called and will set the selectedValue variable. Also, it will reset any previous selected button to the default value, and will set the currently clicked button as selected.
After that, clicking on any Sudoku cell will call the tdClick function which will assign the selected value to this cell, will update the puzzlePlaying variable with the current status of the puzzle, and then, if there are no empty cells left will ask the backend solved.php API if the solution is correct or not.

fetch('http://localhost/cs21/sudoku.back/api/v1/solved.php', {
    method: 'POST',
    headers: {
           'Accept': 'application/json',
           'Content-type': 'application/json',
    },
    body: JSON.stringify({id: sudoku.id, solution: puzzlePlaying})
}

The data sent to the API are JSON formatted.

Use this project

Clone or Fork/Clone the GitHub repository. You may just double click on the html file and run in your browser. A better approach is to clone the project in your htdocs folder (if you are using a local web server) and run using localhost and the path to the project.

Ideas for improvement:

  • Add undo action.
  • Add a button to clear the selected cell.
  • Display how many times this puzzle has been played and how many times it was solved.
  • Highlight selected cell and use keyboard to provide the number to be set there.
  • Provide immediate feedback for the selected number (e.g. using colour).
  • Provide the ability for 'hints'.
  • Build a Sudoku solver extension, able to solve any Sudoku puzzle.