Giter VIP home page Giter VIP logo

sudokujs's Introduction

#SudokuJS ##JavaScript Sudoku solver

Live demo on: https://jonassebastianohlsson.com/sudoku/

SudokuJS has a step by step solver that implements basic strategies, enough to solve (non evil) newspaper sudoku puzzles. The solver is built to mimic humans in that it attempts strategies in order from easiest to most difficult, in each step. So if you're stuck with a puzzle this solver will show you the minimal next step to continue.

SudokuJS comes with a basic GUI for the sudoku board - the board is rendered on the screen, and the board cells listen for keyboard input from a user.

SudokuJS can generate sudoku puzzles of the same difficulties that it can solve, ranging from Easy to Very hard.

SudokuJS currently requires jQuery (on TODO to remove this dependency).

Usage

Initialization

<script src='sudokuJS.js'></script>
<link rel='stylesheet' href='sudokuJS.css' />

<div id='sudoku'></div>

<script>

var mySudokuJS = $("#sudoku").sudokuJS({
    difficulty: "medium" ("easy"|"medium"|"hard"|"very hard")
});
</script>

You can also pass in your own board:

//array representing a standard sudoku puzzle of size 9
//use space for empty cells
var board = [
	, , ,4, ,8, ,2,9
	, , , , , , , , ,4
	,8,5, , ,2, , , ,7
	, , ,8,3,7,4,2, ,
	, ,2, , , , , , ,
	, , ,3,2,6,1,7, ,
	, , , , ,9,3,6,1,2
	,2, , , , , ,4, ,3
	,1,3, ,6,4,2, ,7,undefined
]
//NOTE: if last cell of board is empty, 'undefined' has to be used as value!
var mySudokuJS = $("#sudoku").sudokuJS({
		board: board
});

Solving

Let SudokuJS solve your puzzle - either step by step, or all in one go:

mySudokuJS.solveStep();
mySudokuJS.solveAll();

Analyzing the board

The solver can tell you info about the board.

var data = mySudokuJS.analyzeBoard();

//data.error -- board is incorrect
//data.finished === false -- board can't be solved because it requires more advanced strategies

//if no error, and data.finished === true
//data.level -- "easy"|"medium"|"hard"
//data.score -- int [experimental]
//data.usedStrategies -- [{title, freq}, ..],ranked by difficulty, easiest first

Board Generation

SudokuJS generate new sudoku puzzles on init when no board is passed in, and on generateBoard calls:

mySudokuJS.generateBoard('easy');
mySudokuJS.generateBoard('medium');
mySudokuJS.generateBoard('hard');
mySudokuJS.generateBoard('very hard');

The current implementation for board generation cannot guarantee hard or very hard puzzles generated on every try, so instead it continues over and over until is has succeeded. This means loading a very hard board can sometimes take up to a few seconds.

generateBoard accepts a callback function as a second paramater, that gets called when the new board is ready.

Candidates

Candidates are hidden when a board loads. To show/hide candidates:

mySudokuJS.showCandidates();
mySudokuJS.hideCandidates();

SudokuJS automatically removes impossible candidates on showCandidates(); candidates that can be eliminated via visualElimination (number already exists in same house).

Candidates can be edited on the board by setting SudokuJS to candidate editing mode:

mySudokuJS.setEditingCandidates(true);

Input changes on board cells will now toggle the candidates rather than changes the value.

Clear board

Useful before entering new puzzle, if using keyboard input in the GUI.

mySudokuJS.clearBoard();

Get/Set board

Get the board and save it away if you want. Set a new board and play with that one instead. Setting automatically resets everything back to init state.

mySudokuJS.getBoard();

var newBoard = [
	...
]

mySudokuJS.setBoard(newBoard);

Callbacks

boardUpdatedFn

Fires whenever the board is updated, whether by user or solver.

 $("#sudoku").sudokuJS({
	board: board
	,boardUpdatedFn: function(data){
		//data.cause: "user input" | name of strategy used
		//data.cellsUpdated: [] of indexes for cells updated
		alert("board was updated!");
	}
});

boardFinishedFn

Fires when the board has been completed.

 $("#sudoku").sudokuJS({
	board: board
	,boardFinishedFn: function(data){
		//ONLY IF board was solved by solver:
		//data.difficultyInfo {
		//	level: "easy", "medium", "hard"
		//	,score: int [experimental]
		//}
		alert("board was finished!");
	}
});

boardErrorFn

Fires whenever the board is found to be incorrect, f.e. if solver detects there is no solution to board, or if passed in board is of invalid size.

 $("#sudoku").sudokuJS({
	board: board
	,boardErrorFn: function(data){
		//data.msg -- f.e. "board incorrect"
		alert("board error!");
	}
});

candidateShowToggleFn

The solver automatically switches to showing candidates when a solve step was invoked which only updated the candidates on the board. To catch this change (for updating UI, etc), there is a callback:

 $("#sudoku").sudokuJS({
	board: board
	,candidateShowToggleFn: function(showingBoolean){
		alert("candidates showing: " + showingBoolean); //true|false
	}
}

Extra

The solver is board size agnostic, so you can pass in any valid sudoku sized board (f.e. 4x4, 9x9, 16x16) - however the CSS included only handles 9x9 boards. Currently you can't change boardSize after init.

License

MIT

Changelog

0.4.5 boardSize option, now working. Demos for board sizes 0.4.0 Candidate editing mode
0.3.0 Board generator, easy - very hard
0.2.0 Simple UI and better interface
0.1.0 Step by step sudoku solver

sudokujs's People

Contributors

pocketjoso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sudokujs's Issues

How to set the board from window.location.hash?

I wanna create url with generated sudoku and use only Javascript. I can create url like this: https://.../#3,,,8,,,1,9,7,,,,,,,,,,,8,,,,6,3,4,2,,3,,5,2,8,,,6,1,2,,,,,,,,6,,9,4,,,,8,,,,6,,8,1,7,,,,,,,,,4,,,7,,,,6,,8,,1, but Javascript thinks that it's string, not array. I tried for example this hash = Array.from(window.location.hash); mySudokuJS.setBoard(hash);. Also I tried create empty array, then insert values by push.

It works in PHP like this: https://.../?3,,,8,,,1,9,7,,,,,,,,,,,8,,,,6,3,4,2,,3,,5,2,8,,,6,1,2,,,,,,,,6,,9,4,,,,8,,,,6,,8,1,7,,,,,,,,,4,,,7,,,,6,,8,,1, and then var hash = ['.$_SERVER['QUERY_STRING'].']; mySudokuJS.setBoard(hash);. Is possible to do it only in Javascript?

How to start solving generated sudoku again?

I've got one little question. I want start solving again some sudoku. I'm triying to add button "Again" with delete all values in "highlight-val" classes - that's ok but script still thinks that there are values in these cells.
So how to delete "highlight-val" values and tell the script that these cells are empty?

Diagonal sudoku?

Hi,
your code is amazing, thank you for this! But is also possible to solve diagonal sudoku?

analyzeBoard is always returning "finished:True" inspite of errors and incomplete board

I'm trying to use your code for one of my project and after intializing the board, and clicking on analyze function, it is returning "finished:true" every time. If the board is incomplete or have errors, then also it is returning the same message.

`var mySudokuJS = $("#sudoku").sudokuJS({
difficulty: "easy"
});

function analyze()
{
var data = mySudokuJS.analyzeBoard();
console.log(data);
}
`

can u please help

please freeze cells

like this

$('.sudoku-board-cell').each(function(){
   var cell = $(this).find('input');
   if (parseInt(cell.attr('value'))>0) cell.attr('disabled','disabled');
});

solveAll() doesnt seem to work after using setBoard()

HI

I'm having a problem with solveAll() function. It doesnt seem to work after updating board with a different board. This is how my code looks like:

view:

<a href="#" data-sudoku="4, ,,,9,,,,5,5,3,,,8,,,9,1,,,7,5,,4, 3,,,7,8,,9,,2,,5,6,,,5,7,,8,9,,,2,9,,1,,5,,7,4,,,1,4,,9,6,,,3,7,,,2,,,1,9,6,,9,,7,,,,8">test</a>

javascript:

var board = [
    , , ,4, ,8, ,2,9
    , , , , , , , , ,4
    ,8,5, , ,2, , , ,7
    , , ,8,3,7,4,2, ,
    , ,2, , , , , , ,
    , , ,3,2,6,1,7, ,
    , , , , ,9,3,6,1,2
    ,2, , , , , ,4, ,3
    ,1,3, ,6,4,2, ,7,undefined
]
//NOTE: if last cell of board is empty, 'undefined' has to be used as value!
var mySudokuJS = $("#sudoku").sudokuJS({
        board: board
})


$('#different-sudokus a[href]').on('click', function (e) {

var elemstring = $(this).attr('data-sudoku').split(",");

    var empty = [

         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,   ,
         ,   ,   ,   ,   ,   ,   ,   ,undefined
    ];

    for (i = 0; i < empty.length; i++) {
        var numberOfscotss = parseInt(elemstring[i]);
        if(!(isNaN(numberOfscotss))) {
            empty.splice(i,1,numberOfscotss);
        } 
    }

      mySudokuJS .setBoard(empty );

    $(".solve-my-sudoku").on("click", mySudokuJS .solveAll);

this is how it looks in view:
image

Solving/Checking sudoku correctness

Hi,
I was wondering how come you are solving the sudoku while you already generated all results at the start? I am trying to implement a check function, which If i understand correctly just compares input values with $board values, or am I missing something? Is it maybe for users who are passing the board on their own?

PS: Dunno how to mark this "issue" as a question :)

mySudokuJS.getBoard() Retrieve Array of Objects

Hi,

As you already know mySudokuJS.getBoard() returns Array of Objects with size of 81. It is as below

Array.length = 81
[1] Object {val: 1, candidates: Array[9]}
..........
......
......
[81] Object {val: 1, candidates: Array[9]}

Like this I have 81 Objects. I am trying to pass this Array from HTML file hidden field to mongoose schema, but when I am trying to save this array it is getting saved as String in MongoDB, something like this

"[object Object],[object Object],[object Object],[object Object]............"

So I cannot evaluate this while I want to retrieve this data and use it in mySudokuJS,setBoard().

Mongoose Schema is as below

 var tbl_GameData = new mongoose.Schema({
    LevelID : {type: Number},
    Data : {type: Array} 
  });

and saving from HTML file is like as below

 app.post('/saveGame', function(req, res) {
        var gameData = new database.GameData({
      LevelID : 1,
      Data : req.body.gameData
 });

 gameData.save(function(err) {
if(err){
	console.log(err);
}

req.login(gameData, function(err){
	if(err){
		req.redirect('/login');
	}
	else {
		res.render('startGame',{ user: req.user ,title:"Sudoku Online Match"});
	}
      });	
 });
 });

I dont know how to save this in DB so that I can retrieve it back as an array. Can you please help!

multiple solution

Hello, I am using the version v0.4.4
I was able to generate a board with multiple solutions :
[{"val":3},{"val":4},{"val":9},{"val":6},{"val":1},{"val":8},{"val":5},{"val":7},{"val":2},{"val":7},{"val":8},{"val":2},{"val":3},{"val":5},{"val":9},{"val":null,"candidates":[null,null,null,4,null,6,null,null,null,null]},{"val":null,"candidates":[1,null,null,4,null,null,null,null,null,null]},{"val":null,"candidates":[1,null,null,null,null,6,null,null,null,null]},{"val":6},{"val":5},{"val":1},{"val":7},{"val":4},{"val":2},{"val":3},{"val":8},{"val":9},{"val":2},{"val":7},{"val":3},{"val":8},{"val":9},{"val":5},{"val":null,"candidates":[null,null,null,4,null,6,null,null,null,null]},{"val":null,"candidates":[1,null,null,4,null,null,null,null,null,null]},{"val":null,"candidates":[1,null,null,null,null,6,null,null,null,null]},{"val":1},{"val":9},{"val":5},{"val":4},{"val":7},{"val":6},{"val":2},{"val":3},{"val":8},{"val":8},{"val":6},{"val":4},{"val":2},{"val":3},{"val":1},{"val":9},{"val":5},{"val":7},{"val":5},{"val":2},{"val":7},{"val":1},{"val":6},{"val":4},{"val":8},{"val":9},{"val":3},{"val":9},{"val":1},{"val":8},{"val":5},{"val":2},{"val":3},{"val":7},{"val":6},{"val":4},{"val":4},{"val":3},{"val":6},{"val":9},{"val":8},{"val":7},{"val":1},{"val":2},{"val":5}]

Is there a way to avoid this?
Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.