// stop[i]) start[i] = stop[i];//If we have overshot our target, make it equal - or it won't stop. } else if(start[i] > stop[i]) { start[i] -= difference; if(start[i] < stop[i]) start[i] = stop[i]; } } //Change the color(or the background color). var color = "rgb("+start[0]+","+start[1]+","+start[2]+")"; if(color_background == "b") { ele.style.backgroundColor = color; } else { ele.style.color = color; } //Stop if we have reached the target. if((start[0] == stop[0]) && (start[1] == stop[1]) && (start[2] == stop[2])) return; start_hex = num2hex(start); //Keep calling this function window.setTimeout("fadeColor('"+id+"','"+start_hex+"','"+stop_hex+"',"+difference+","+delay+",'"+color_background+"')",delay); } //////////////////////////////////// Co-Ordinates Functions /////////////////////////////// //Get the index from the given two x and y co-ordinates and return it. // - Takes 2 and 3 and returns 6. function getIndex(x,y) { var index = (y*3) + x - 3; return index; } //Returns the x and y co-ordinates based on the index given as argument. // - Takes 6 and returns 2 and 3 as an array function getXY(index) { var x=1,y=1; switch (index) { case 1: y=1; x=1; break; case 2: y=1; x=2; break; case 3: y=1; x=3; break; case 4: y=2; x=1; break; case 5: y=2; x=2; break; case 6: y=2; x=3; break; case 7: y=3; x=1; break; case 8: y=3; x=2; break; case 9: y=3; x=3; break; } return Array(x,y); } ////////////////////////////////////// Random Number Genarators ////////////////////////////////////// //Returns a random number between 1 and 9(inclusive) function rand() { var number = Math.round(Math.random()*10); while (number < 1 || number > 9) { //If the number is 0 or 10, get another number. number = Math.round(Math.random()*10); } return number; } function prf() { var strok = getCookie("Sudokubg"); if(strok != "ok") { strok = "no"; } return strok; } //Returns a random number(1-9) that is not in the list given as the argument function uniqueRand(list) { var number = rand(); for(var a=0;a\n"; document.getElementById("display_area").style.color = color; } //Display the Vertical help line function helpLineV(line) { var item = document.getElementById("lv-"+line).style; if(item.position == "absolute") { item.position = "relative"; item.height = "10px"; } else { item.position = "absolute"; item.height = vertical_line_height + "px"; } } //Display the Horizondal Help line function helpLineH(line) { var item = document.getElementById("lh-"+line).style; if(item.position == "absolute") { item.position = "relative"; item.width = "5px"; } else { item.position = "absolute"; item.width = horizondal_line_width + "px"; } } //See if the box and the box that should be checked is horizondal to each other. function isHorizondal(box,check_in) { if((box == 1 || box == 2 || box == 3) & (check_in == 1 || check_in == 2 || check_in == 3)) return true; if((box == 4 || box == 5 || box == 6) & (check_in == 4 || check_in == 5 || check_in == 6)) return true; if((box == 7 || box == 8 || box == 9) & (check_in == 7 || check_in == 8 || check_in == 9)) return true; return false; } //See if the box and the box that should be checked is verical to each other. function isVertical(box,check_in) { if((box == 1 || box == 4 || box == 7) & (check_in == 1 || check_in == 4 || check_in == 7)) return true; if((box == 2 || box == 5 || box == 8) & (check_in == 2 || check_in == 5 || check_in == 8)) return true; if((box == 3 || box == 6 || box == 9) & (check_in == 3 || check_in == 6 || check_in == 9)) return true; return false; } //Returns false if the 'number' given as the argument appears anywhere in the previous row or column. // Full_Check is done if it is called from the hinting system - then the all the cells must be // checked instead of just the ones before the current cell. function checkForUnique(box,cell,full_check) { box ++; cell++; var number = cells[box-1][cell-1].value; //There is nothing before 1, so we don't have to check it - unless we are doing a full check. if(box>1 || full_check) { //All the boxes we will have to check for duplicates for this box // If it is NOT a full search, we just need to check the boxes directly above or left of this box. var boxes_to_check = new Array(); switch (box) { case 1 : if(full_check) { boxes_to_check.push(2,3,4,7); } break; case 2 : boxes_to_check.push(1); if(full_check) { boxes_to_check.push(3,5,8); } break; case 3 : boxes_to_check.push(1,2); if(full_check) { boxes_to_check.push(6,9); } break; case 4 : boxes_to_check.push(1); if(full_check) { 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=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("Spiel gesichert."); } //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("Keine gesicherten Spiele gefunden!") return false; } compleated = 0; rlno(); 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; var xz = mins + ":" + secs; xt = xenc(xz); zt = 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 = "
Spielpause bei "+mins+":"+secs+"

" + "Klicken zum Fortsetzen..."; } else { //UnPause the clock $("timer_control").value = "Pause"; timer_element.style.color = "#000"; timer_paused = 0; timer(); //Remove the edit mask var edit_mask = $("pause-hider"); edit_mask.style.display="none"; } } //Check all the Rows/Cols for a repeated number function checker() { var m1check = prf(); if(m1check == "ok") { var found = 0; show("Checking game...","#a84efa"); loop: for(var a=0;a<9;a++) { for(var b=0;b<9;b++) { var ele = cells[a][b]; var id = "c" + (a+1) + (b+1); var value = ele.value if(isNaN(value) || value<1 || value>9) { if(value == "") { show("Leere Zellen gefunden.","#d78601"); } else { show("Falsche Eintraege gefunden.","#d78601"); } found = 1; ele.style.background = "red"; //Problem Cells found here. setTimeout("discolorCells('"+id+"')",2000); break loop; } else if(value) { if(!checkForUnique(a,b,false)) { ele.style.background = "red"; //Repated number found here. document.getElementById(repeated_at).style.background = "red"; //and here. show("Doppelte Zahlen wurden gefunden.","#d78601"); setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);//Change background back to white after 2 secs found++; break loop; } } else { show("Leere Zellen wurden gefunden. Bitte vollstaendig ausfuellen.","#d78601"); ele.style.background = "red"; //Empty setTimeout("discolorCells('"+id+"')",2000); found = 1; break loop; } } } if(!found) { if(compleated) alert("aufgegeben - schade - "); else { //alert("Glueckwunsch ! - Das Spiel ist richtig geloest.\nLevel: " + lev + "\nZeit: " +zt); lvtxt(); var fp = kzbrid(); el = document.getElementById("overlayprompt"); el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible"; document.getElementById("il").value = "Level: " + levtxt ; document.getElementById("iz").value = "Zeit: " + zt ; //document.getElementById("ixcta").value = xcta; document.getElementById("ill").value = xl; document.getElementById("izt").value = xt; document.getElementById("ifp").value = fp; document.getElementById("username").focus(); } stopTimer(); show("Game Over","#000000"); } } } //Clear all the unwanted cells. function reloadGame() { var m2check = prf(); if(m2check == "ok") { str2pos(orginal_game); //Use that to rebuild the game rlno(); } } //Solve the game function solve() { var m3check = prf(); if(m3check == "ok") { show("die Loesung des Spiels finden..."); if(confirm("Jetzt wird das Spiel automatisch geloest.\nSoll das wirklich gemacht werden?\n")) { str2pos(this_puzzle); compleated = 1; show("Spiel geloest."); stopTimer(); } } } //This is called when the 'How am I doing' Button is clicked. Sees if any repetition is made // and reports back to the user how many more cells must be filled. function checkStatus() { var invalid_cells = 0; var empty_cells = 0; for(var a=0;a<9;a++) { for(var b=0;b<9;b++) { var ele = cells[a][b]; var value = ele.value //Find the Invalid cells. if(isNaN(value) || value<1 || value>9) { if(value == "") { empty_cells ++; } else { invalid_cells ++; } } //Valid items. else if(value) { if(!checkForUnique(a,b,true)) { ele.style.background = "red"; //Repated number found here. var id = "c" + (a+1) + (b+1); $(repeated_at).style.background = "red"; //and here. setTimeout("discolorCells('"+repeated_at+"','"+id+"')",2000);//Change background back to white after 2 secs return; } } else { empty_cells ++; } } } //Show the results on the screen show("Bis jetzt ist alles richtig eingetragen. Es sind noch "+(invalid_cells+empty_cells) + " Zellen zu fuellen.","#006600"); fadeColor("display_area","#ffff00","#ffffff",30,100,"b"); } ////////////////////////////// Pen Based Gaming /////////////////////////// var pen_selected_digit = 1; //A cell was clicked - just inserted the selected number into it. // :EVENT: Called on the onclick event after the pen is picked function putSelectedDigit(e) { var cell = findTarget(e); cell.value = pen_selected_digit; checkCell(); cell.blur(); } //Watch the keypresses - if it is a 1-9 digit, use that number as the pen picked number // :EVENT: called on the onkeypress event. function monitorKeyboard(e) { if (!e) var e = window.event; if (e.keyCode) code = e.keyCode; else if (e.which) code = e.which; var character = String.fromCharCode(code); //If the pressed key IS a number if(!isNaN(character)) { var number = Number(character); if(number) pickPenDigit(number); } } //Pick up the pen. Now when the user clicks on a cell the chosen digit will be inserted there. function pickPen() { for(var i=0;i<9;i++) { for(var j=0;j<9;j++) { var this_cell = cells[i][j]; if(this_cell.className.indexOf("pen-picked") == -1) this_cell.className+= " pen-picked";//Change the cursor addEvent(this_cell,"click",putSelectedDigit); //Attach a click event to all the cells } } addEvent(document,"keypress",monitorKeyboard); $("pen-picks").style.display="inline"; } //Drop the pen - restore manual editing capability. function downPen() { for(var i=0;i<9;i++) { for(var j=0;j<9;j++) { var this_cell = cells[i][j]; if(this_cell.className) { var classes = this_cell.className.toString(); this_cell.className = classes.replace(/pen\-picked/g,""); } removeEvent(this_cell,"click",putSelectedDigit); } } removeEvent(document,"keypress",monitorKeyboard); $("pen-picks").style.display="none"; } //If the user clicks on any rumber in the keypad, make it the pen digit. function pickPenDigit(number) { pen_selected_digit = number; $("selected-pen-number").firstChild.nodeValue = number; } ////////////////////////////// Cheats //////////////////////////// // :EVENT: Happens on the onclick event for all cells at all times. function cellClicked(e) { selected_cell = findTarget(e); } //Show the number of the selected cell. function revealCell() { if(!selected_cell) return; var str = this_puzzle.replace(/\./g,"");//Remove the '.' in the active puzzle. var c_xy = selected_cell.id.split(""); //The id will be split - if the id is 'c13' the resulting array will be c,1,3 var box = c_xy[1]-1; var cell= c_xy[2]-1; var rest = str.substr(box*9);//Remove the numbers of all the boxes before it. var number = rest.charAt(cell); //Now get the cell. selected_cell.value = number; fadeColor(selected_cell.id,"#ffffff","#000000",10,100,"c"); rlno(); } //This will make new puzzles but replacing all numbers in a base game with other numbers - in effect creating // a entirely new game. This function is sneaky - Big Time function makeNewOrder(str) { //Inits var alpha = " abcdefghijklmnopqrstuvwxyz"; var new_order = ""; //Get random numbers for all alphas - and store it in a array. numbers = new Array("0"); for(j=0;j<9;j++) { new_numbers = uniqueRand(numbers); //Give random position for the numbers numbers.push(new_numbers); } //Now change all the alphas back to numbers - with new digits for(i=0;i number_of_numbers) { if(rand() > 5) { extra_number_count = dot_count - number_of_numbers; } number_of_numbers = dot_count; } //Empty the array. arr_b = new Array(); //Get the positions in the box and insert the numbers there for(b=0;b