Created
January 4, 2018 15:15
-
-
Save Xmerr/9ae10593b1889a8780ec191ad2242d28 to your computer and use it in GitHub Desktop.
Sodoku Solver - created for websudoku.com but can altered to work for any sodoku website.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(){ | |
/** | |
* A single sodoku cell | |
*/ | |
var cell = function(col, row) { | |
this.col = col; | |
this.row = row; | |
this.block = (Math.floor(col / 3) * 10) + Math.floor(row / 3); | |
this.id = "f" + col + "" + row; | |
this.value = document.getElementById(this.id).value; | |
this.value = this.value.indexOf(',') !== -1 ? "" : this.value; | |
this.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]; | |
}; | |
cells = []; | |
/** | |
* Sets the cells value | |
*/ | |
cell.prototype.setValue = function(val) { | |
var dom = document.getElementById(this.id); | |
var valChange = dom.value !== val; | |
dom.value = val; | |
dom.onkeyup(); | |
return valChange; | |
}; | |
/** | |
* Returns all cells on this row | |
*/ | |
cell.prototype.cellRow = function() { | |
var thatRow = this.row; | |
return cells.filter(function(ob) { | |
return ob.row === thatRow; | |
}); | |
}; | |
/** | |
* Returns all cells on this column | |
*/ | |
cell.prototype.cellCol = function() { | |
var thatCol = this.col; | |
return cells.filter(function(ob) { | |
return ob.col === thatCol; | |
}); | |
}; | |
/** | |
* Returns all cells in this block | |
*/ | |
cell.prototype.cellBlock = function() { | |
var thatBlock = this.block; | |
return cells.filter(function(ob) { | |
return ob.block === thatBlock; | |
}); | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If there is only one possible number, that must be the answer | |
*/ | |
cell.prototype.cellGuess = function() { | |
var myCells = [...this.cellRow(), ...this.cellCol(), ...this.cellBlock()]; | |
for(var i = myCells.length - 1; i >= 0; i--) | |
this.numbers = checkCell(myCells[i], this.numbers); | |
if(this.numbers.length === 1) { | |
this.setValue(this.numbers.toString()); | |
this.value = this.numbers.toString(); | |
changed = true; | |
} | |
else if(this.setValue(this.numbers.join(','))) | |
changed = true; | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If this cell is the only one that can hold this number, that number must belong to this cell | |
*/ | |
cell.prototype.numberGuess = function () { | |
var myCells = [this.cellRow(), this.cellCol(), this.cellBlock()]; | |
for(var k = myCells.length - 1; k >= 0; k--) { | |
for(var j = this.numbers.length - 1; j >= 0; j--) { | |
var found = false; | |
for(var i = myCells[k].length - 1; i >= 0; i--) { | |
if(myCells[k][i].id !== this.id && checkNumber(myCells[k][i], this.numbers[j])) { | |
found = true; | |
break; | |
} | |
} | |
if(!found){ | |
this.setValue(this.numbers[j]); | |
this.value = this.numbers[j]; | |
changed = true; | |
return; | |
} | |
} | |
} | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If there is only one possible number, that must be the answer | |
*/ | |
var checkCell = function(c, numbers) { | |
if(c.value) | |
return numbers.filter(function(num) { | |
return num !== parseInt(c.value); | |
}); | |
return numbers; | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If this cell is the only one that can hold this number, that number must belong to this cell | |
*/ | |
var checkNumber = function(c, number) { | |
if(c.value) | |
return c.value == number; | |
return c.numbers.indexOf(number) !== -1; | |
}; | |
/** | |
* Gets all the cells in an array | |
*/ | |
for(var i = 0; i <= 8; i++) | |
for(var j = 0; j <= 8; j++) | |
cells.push(new cell(i, j)); | |
var changed = false; | |
/** | |
* Attempts to solve the puzzle | |
*/ | |
var solve = function () { | |
cellGuess(); | |
var count = 0; | |
while(changed && count < 100) { | |
count++; | |
changed = false; | |
cellGuess(); | |
numberGuess(); | |
} | |
if(changed) { | |
console.log("ERROR 1"); | |
return; | |
} | |
for(var i = cells.length - 1; i >= 0; i--) { | |
if(!cells[i].value) { | |
console.log("could not solve"); | |
return; | |
} | |
} | |
console.log('solved in ' + count + ' iterations'); | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If there is only one possible number, that must be the answer | |
*/ | |
var cellGuess = function () { | |
for(var i = cells.length - 1; i >= 0; i--) { | |
if(cells[i].value) | |
continue; | |
cells[i].cellGuess(); | |
} | |
}; | |
/** | |
* Guesses the cells value based on possible numbers. | |
* If this cell is the only one that can hold this number, that number must belong to this cell | |
*/ | |
var numberGuess = function () { | |
for(var i = cells.length - 1; i >= 0; i--) { | |
if(cells[i].value) | |
continue; | |
cells[i].numberGuess(); | |
} | |
}; | |
solve(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment