📄 sudoku.js
字号:
boxes_to_check.push(5,6,7);
}
break;
case 5 : boxes_to_check.push(2,4);
if(full_check) {
boxes_to_check.push(6,8);
}
break;
case 6 : boxes_to_check.push(3,4,5);
if(full_check) {
boxes_to_check.push(9);
}
break;
case 7 : boxes_to_check.push(1,4);
if(full_check) {
boxes_to_check.push(8,9);
}
break;
case 8 : boxes_to_check.push(2,5,7);
if(full_check) {
boxes_to_check.push(9);
}
break;
case 9 : boxes_to_check.push(3,6,7,8);break;
}
var value="",xy_coods,cell_to_check;
next_box:
for(var i=0;i<boxes_to_check.length;i++) {
xy_coods = getXY(cell);
var check_box = boxes_to_check[i];
for(var j=1; j<=3; j++) {
//Horizondal Checks
if(isHorizondal(box,check_box)) {
//Non-full checks will check only the cells before them - will not check all the cells.
if(!full_check) {
if(box==1 || box==4 || box==7) continue next_box;
else if(box==5 && check_box==6) continue next_box;
else if(box==8 && check_box==9) continue next_box;
}
//Check the data for redundency here.
cell_to_check = getIndex(j,xy_coods[1]);
value = cells[(check_box-1)][cell_to_check-1].value;
if(value == number) {
repeated_at = "c" + check_box + cell_to_check;//Get the id of the cells that matched
return false; //There is number repeatation - return with error.
}
//Verical Checks
} else {
if(!full_check) {
if(box<4) continue;
else if(box==4 && check_box==7) continue next_box;
else if(box==5 && check_box==8) continue next_box;
else if(box==6 && check_box==9) continue next_box;
}
//Check the data for redundency here.
cell_to_check = getIndex(xy_coods[0],j);
value = cells[check_box-1][cell_to_check-1].value;
if(value == number) {
repeated_at = "c" + check_box + cell_to_check;//Get the id of the cells that matched
return false; //There is number repeatation - return with error.
}
}
}
}
}
//Check within the box
for(var k=0;k<9;k++) {
var val = cells[box-1][k].value;
if(number == val && (k+1 != cell)) { //If the nubmer is found at some other cell
repeated_at = "c"+box+(k+1);
return false;
}
}
return true;
}
//Insert the value given as the 'value' argument into the entry by the id of 'id'
function insert(id,value) {
var ele = document.getElementById(id);
ele.style.color="";
ele.value = value
if(value)
ele.disabled = true; //Make it uneditable
else
ele.disabled = false; //Make the fomerly uneditable cells editable
}
//Clear all the fields - and enable all the disabled cells
function clearer() {
var id = ""
document.f.reset(); //Clear the fields
for(var i=0; i<9; i++) {
for(var j=0; j<9; j++) {
cells[i][j].disabled = false;
}
}
}
//Change the background color of cells to white
function discolorCells(cell1,cell2) {
document.getElementById(cell1).style.background = "#fff";
if(cell2) document.getElementById(cell2).style.background = "#fff";
}
//Records the values of all box and cells by coping all values to the 'xy' array.
function recordPosition() {
var value=0;
for(var a=0;a<9;a++) {
for(var b=0;b<9;b++) {
value = cells[a][b].value;
if(!isNaN(value) && value.length==1) {
xy[a][b] = value;
} else {
xy[a][b] = 0;
}
}
}
}
//Convert the current position to a string that we can save and use latter on. This function will create a
// finger print for this game and will save that as a Cookie. The finger print will have two types of data...
// Number(1-9) - The number for that cell. If the number is 3, a 3 digit will be entered there.
// Aphabet(a-z)- The number of empty cells that must be left before the next number is inserted.
//Argument : Action - 1 = Record the game to a database.
// - 0 = Just get the fingerprint of the game and return it
function pos2str(action) {
var str = "";
var zero_count = 0;
var alpha = " abcdefghijklmnopqrstuvwxyz";
if(action) {
recordPosition(); //Get the position in the array
}
for(var a=0;a<9;a++) {
for(var b=0;b<9;b++) {
if(xy[a][b]) {
if(zero_count) {
str += alpha.charAt(zero_count); //Include the number of continous zeros - a means 1 zero, b means 2 etc.
zero_count = 0;
}
str += xy[a][b];
} else {
zero_count++; //Count the empty places
}
}
}
return str;
}
//Convert the given string to a position that can be displayed on the board
//Argument : str - FINGERPRINT = Use this fingerprint to create the game.
function str2pos(str) {
var zero_flag = 0;
var alpha = "abcdefghijklmnopqrstuvwxyz";
var pos = 0;
//The id of the current cell will be calculated form these varabales.
var a = 0;
var b = 0;
str = str.replace(/\./g,"");
while(a<9) {
ch = str.charAt(pos);
id = "c" + (a+1) + (b+1);
if(!isNaN(ch) && !zero_flag) {
insert(id,ch);
} else if(zero_flag) {
insert(id,"");
zero_flag--;
} else {
insert(id,"");
zero_flag = alpha.indexOf(ch);
}
//Get next number if the zero flag is not up
if(!zero_flag) {
pos++;
}
//Update the positions
b++;
if(b>=9) {
b=0;
a++;
}
}
}
//Create a string we will put into the cookie - a little different for the pos2str()
// - This format will have the values of all cells sperated by a ';' char. The provided
// numbers will be prefixed with a dot like - '.5'
function makeCookieString() {
var str = "";
var puzzle_cells = new Array(0);
for(var a=0;a<9;a++) {
for(var b=0;b<9;b++) {
value = cells[a][b].value;
if(cells[a][b].disabled) {
value = "."+value;
}
puzzle_cells.push(value);
}
}
str = puzzle_cells.join(';');
return str;
}
//This function is called when the user changes the value of a cell.
// :EVENT: called by the onchange Event
function checkCell(e) {
var cell = findTarget(e);
var val = cell.value;
if(val<1 || val>9 || isNaN(val)) { //Some error in this cell
tagProblemCell(cell,1);
if(val.length > 1) { //If mulitple numbers are given, make the font smaller.
cell.className += " possibilities-entry";
}
return 0;
} else {
if(cell.className.indexOf("possibilities-entry")) { //Make the font bigger if it was small.
cell.className = cell.className.replace(/ possibilities\-entry/g,"");
cell.className = cell.className.replace(/ problem\-cell/g,"");
cell.style.color = "#000";
}
if($("live-hints").checked) {
var id = cell.id;
var a = Number(id.charAt(1)) - 1;
var b = Number(id.charAt(2)) - 1;
if(!checkForUnique(a,b,true)) {
cell.style.background = "red"; //Repated number found here.
$(repeated_at).style.background = "red"; //and here.
setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);//Change the background back to white after 2 secs
//setTimeout("makeProblemCell('"+id+"')",2000);
return 0;
}
}
}
tagProblemCell(cell,0);
return 1;
}
function makeProblemCell(id) {
$(id).className += " problem-cell";
}
//Tags the given cell as having problem or not.
function tagProblemCell(cell,on) {
var current_classes = cell.className.toString();
var have_problem = 0;
if(current_classes.indexOf("problem-cell") >= 0) have_problem = 1;
if(on) {
if(!have_problem) cell.className += " problem-cell";
} else {
if(have_problem) cell.className = current_classes.replace(" problem-cell","");
}
}
////////////////////////////////////// Functions Called from GUI /////////////////////////////////
//Save the Cookie Format string created with the makeCookieString() function to a cookie
function save() {
var str = makeCookieString();
setCookie("sudoku_fingerprint",str);
alert("Game saved.");
}
//Load the game from the cookie string
function load() {
//Clear the previous data
clearer();
//Get the game fingerprint from the Cookie.
var str = getCookie("sudoku_fingerprint");
if(str == "" || str == null) {
alert("No saved games found!")
return false;
}
compleated = 0;
var index = 0;
var puzzle_cells = str.split(";");
for(var a=0;a<9;a++) {
for(var b=0;b<9;b++) {
number = puzzle_cells[index];
if(number.charAt(0) == ".") { //If there is a '.' char, it ia a provided number
number = number.charAt(1);
cells[a][b].disabled = true;
}
cells[a][b].value = number;
index++;
}
}
}
////////////////////////////////// Timer Functions ////////////////////////////
//Show the timer for the game.
function timer() {
if(!timer_seconds) timer_seconds = 0;
timer_seconds++;
var secs = timer_seconds % 60;
var mins = Math.floor(timer_seconds/60);
if(secs<10) secs = "0" + secs;
if(mins<10) mins = "0" + mins;
timer_element.innerHTML = mins + ":" + secs;
timer_clock = window.setTimeout("timer()",1000);
}
//Stop the timer
function stopTimer() {
if(timer_clock) clearTimeout(timer_clock);
}
//This will pause the timer if it is not paused, and will up-pause it if it was paused.
function toggleTimer() {
if(!timer_paused) { //Stop Time
clearTimeout(timer_clock);
timer_element.style.color = "#f00";
$("timer_control").value = "Continue";
timer_paused = 1;
//Make the users unable to edit the puzzle in the pause mode.
var edit_mask = $("pause-hider");
edit_mask.style.display="block";
//Find Time...
if(!timer_seconds) timer_seconds = 0;
var secs = timer_seconds % 60;
var mins = Math.floor(timer_seconds/60);
if(secs<10) secs = "0" + secs;
if(mins<10) mins = "0" + mins;
//Make the text in the Edit Mask.
edit_mask.innerHTML = "<br /><strong>Game Paused at "+mins+":"+secs+"</strong><br /><br />" +
"<a onclick='toggleTimer()' style='cursor:hand;'>Click to Continue...</a>";
} else { //UnPause the clock
$("timer_control").value = "Pause";
timer_element.style.color = "#000";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -