// 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