PageSourceSearch

https://schulte-page.de/js/sudoku.js

js schulte-page.de collected 2026-10-02 01:52:14 UTC 19,127 bytes, 501 lines download raw bytes

1function getRandomInt( max ){
2    var ticks = new Date().getTime();
3    var rnd = (Math.random() * ticks % max) << 0;
4    return rnd;
5}
6
7function getColors(opacity){
8    if (!opacity) opacity = 0.3;
9    var colors = [
10        "rgba(255, 192, 203, " + opacity + ")", // pink
11        "rgba(152, 251, 152, " + opacity + ")", // palegreen
12        "rgba(221, 160, 221, " + opacity + ")", // plum
13        "rgba(176, 224, 230, " + opacity + ")", // powderblue
14        "rgba(238, 232, 170, " + opacity + ")", // palegoldenrod
15        "rgba(255, 160, 122, " + opacity + ")", // lightsalmon
16        "rgba(175, 238, 238, " + opacity + ")", // paleturquoise
17        "rgba(245, 245, 220, " + opacity + ")", // beige
18        "rgba(173, 216, 230, " + opacity + ")", // lightblue
19        "rgba(143, 188, 143, " + opacity + ")", // darkseagreen
20        "rgba(240, 230, 140, " + opacity + ")", // khaki
21        "rgba(144, 238, 144, " + opacity + ")", // lightgreen
22        "rgba(230, 230, 250, " + opacity + ")" // lavender
23    ];
24    return colors;
25}
26
27function getPossibleSudokus(){
28    return [
29        { size: 4, a: 2, b: 2 },
30        { size: 6, a: 3, b: 2 },
31        { size: 8, a: 4, b: 2 },
32        { size: 9, a: 3, b: 3 },
33        { size: 12, a: 4, b: 3 },
34        { size: 15, a: 5, b: 3 },
35        { size: 16, a: 4, b: 4 }
36    ];
37}
38
39function createRowAndColCounter(sudoku){
40    var cellTops = []; var cellLefts = [];
41    $('.sudokucells').each(function(index, cell){
42        var myOffset = $(cell).offset();
43        if (cellTops.indexOf(myOffset.top) === -1) cellTops.push(myOffset.top);
44        if (cellLefts.indexOf(myOffset.left) === -1) cellLefts.push(myOffset.left);
45    });
46
47    var rowIds = {}; var colIds = {};
48    for (var i = 0; i < sudoku.size; i++){
49        rowIds["row" + i] = [];
50        colIds["col" + i] = [];
51    }
52
53    $('.sudokucells').each(function(index, cell){
54        var myId = $(cell).attr("cellid")
55        var myOffset = $(cell).offset();
56
57        var myTopIndex = cellTops.indexOf(myOffset.top);
58        rowIds["row" + myTopIndex].push( myId );
59
60        var myLeftIndex = cellLefts.indexOf(myOffset.left);
61        colIds["col" + myLeftIndex].push( myId );
62
63        $(cell).attr("row", myTopIndex+1);
64        $(cell).attr("col", myLeftIndex+1);
65    });
66}
67
68function onHoverInCell(event, myobj){
69    var newColor = getColors(0.8)[parseInt( $(myobj).attr("value") ) - 1];
70    var oldColor = $(myobj).css("background");
71    $(myobj).attr("oldcolor", oldColor);
72    $(myobj).css("background", newColor);
73}
74
75function onHoverOutCell(event, myobj){
76    var newColor = $(myobj).attr("oldcolor");
77    $(myobj).css("background", newColor);
78}
79
80function onHoverInEmptyCell(event, myobj){
81    var newColor = "black";
82    var oldColor = $(myobj).css("border-color");
83    $(myobj).attr("oldcolor", oldColor);
84    $(myobj).css("border-color", newColor);
85}
86
87function onHoverOutEmptyCell(event, myobj){
88    var newColor = $(myobj).attr("oldcolor");
89    $(myobj).css("border-color", newColor);
90}
91
92function onClickInEmptyCell(event, myobj){
93    if ($('#iconcontainer:visible').length === 0) $('#iconcontainer').animate({width: "toggle"});
94    $('.hideable').attr('clicked', 'false').each(function(index, element){
95        var text = $(element).text();
96        if ( text === "?"){
97            $(element).css({'background': 'white', 'color': 'black'});
98        } else {
99            var color = $(element).attr('lastcolor'); // $('.icons[value="' + text + '"]').css('background-color');
100            $(element).css({'background': color, 'color': 'black'});
101        }
102    });
103    $(myobj).attr('clicked', 'true').css({'background': 'darkblue', 'color': 'white'});
104}
105
106function onClickIconCell(event, myobj){
107    if ( $('#iconcontainer').attr('editable') === "true") return;
108    var text = $(myobj).text();
109    var opacity = $('.sudokucells').first().css("opacity");
110    var colors = getColors(opacity);
111    var i = $.inArray(myobj, $('.icons'));
112    $('[clicked="true"]').text(text).attr({'solved': 'true', 'lastcolor': colors[i]}).css({'background': colors[i], 'border-color': 'black', 'color': 'black'});
113    $('#iconcontainer').animate({width: "toggle"});
114
115    if ($('[solved="false"]').length === 0) checkSudokuSolved();
116}
117
118function onHoverInOverlay(){ $("#overlaytext").css({ "color": "darkblue", "text-decoration": "underline" }); }
119function onHoverOutOverlay(){ $("#overlaytext").css({ "color": "black", "text-decoration": "none" }); }
120
121function onHoverInChangeSize(event, myobj){ $(myobj).css({"color": "darkblue", "text-decoration": "underline"}); }
122function onHoverOutChangeSize(event, myobj){ $(myobj).css({"color": "black", "text-decoration": "none"}); }
123
124function onHoverInEditIcons(event, myobj){ $(myobj).css({"opacity": "1"}); }
125function onHoverOutEditIcons(event, myobj){ $(myobj).css({"opacity": "0.6"}); }
126
127function onClickChangeSize(event, myobj){
128    var usersize = prompt("Size?", getSudokuSize());
129    usersize = parseInt(usersize);
130    if (isNaN(usersize)) return;
131    createSudokuTable(usersize);
132}
133
134function setTextOnly( elements, newText){
135    $(elements).each(function(index, element){
136        var child = $(element).children();
137        $(element).text(newText).append(child);
138    });
139}
140
141function setNewIconTextsToSudokuTable(event){
142    // fire script if enter is pressed or the button was clicked, not else
143    if (event && event.keyCode !== 13){
144        return;
145    } else if (event){
146        event.stopPropagation();
147        event.preventDefault();
148    }
149
150    $('#iconcontainer').attr('editable', 'false');
151    $('.icons').attr('contenteditable', 'false');
152    $('.icons').css({'border': 'none'});
153
154    var values = [];
155    $('.icons').each(function(index, icon){
156        values.push( $(icon).attr('value') );
157    });
158
159    for (var i = 0; i < values.length; i++){
160        var newText = $('.icons[value="' + values[i] + '"]').text();
161        setTextOnly($('[value="' + values[i] + '"]'), newText);
162    }
163}
164
165function onClickEditIcons(event, myobj){
166    var setToEditable = $('#iconcontainer').attr('editable') === "false" || $('#iconcontainer').attr('editable') === undefined;
167    $('#iconcontainer').attr('editable', setToEditable );
168    if (setToEditable) {
169        $('.icons').attr('contenteditable', 'true');
170        $('.icons').css({'border': '1px solid black'});
171    } else {
172        setNewIconTextsToSudokuTable();
173    }
174}
175
176function hideOverlay(){
177   $('#iconcontainer').animate({width: "toggle"});
178   $('#overlaytextaddition').text("");
179   $('#overlay').hide();
180}
181
182function createSmallTable(id, rows, cols, tableCounter, tableRowCounter, tableColCounter){
183    var cellCounter = 0;
184    var toBeAppended = '<table table="' + tableCounter + '" style="background: snow;"><tbody>';
185    for (var i = 0; i < rows; i++){
186        toBeAppended += '<tr>';
187        for (var j = 0; j < cols; j++){
188            toBeAppended += '<td class="sudokucells" cellid="' + ++id + '" table="' + tableCounter + '" row="" col="" value="" cell="' + ++cellCounter + '" ' +
189                'onmouseover="onHoverInCell(event, this)" ' +
190                'onmouseout="onHoverOutCell(event, this)" ' +
191                'style="padding: 25px; border: 5px solid white; width: 30px; text-align: center;">' +
192            '?</td>';
193        }
194        toBeAppended += '</tr>';
195    }
196    toBeAppended += '</tbody></table>';
197    return toBeAppended;
198}
199
200function createBigTable(sudoku, id){
201    var tableCounter = 0; var tableRowCounter = 0; var tableColCounter = 0;
202    var toBeAppended = '<table id="sudokucontainer" size="' + sudoku.size + '" ' +
203        'style="background: gainsboro; font-size: 1.5em; margin: 25px; float: left;"><tbody>';
204    for (var i = 0; i < sudoku.b; i++){
205        toBeAppended += '<tr>';
206        tableRowCounter++;
207        for (var j = 0; j < sudoku.a; j++){
208            tableColCounter = tableColCounter % sudoku.a + 1;
209            toBeAppended += '<td>' + createSmallTable(id, sudoku.a, sudoku.b, ++tableCounter, tableRowCounter, tableColCounter) + '</td>';
210        }
211        toBeAppended += '</tr>';
212    }
213    toBeAppended += '</tbody></table>';
214    return toBeAppended;
215}
216
217function createPossibleIconsArea(sudoku){
218    var size = sudoku.size;
219
220    var toBeAppended = '<table id="iconcontainer" ' +
221            'style="border: 1px solid gainsboro; background: white; font-size: 1.5em; margin: 25px 25px 25px -25px; float: left; display: block; border-radius: 0 5px 5px 0;' +
222        '"><tbody>';
223
224    // preferences
225    toBeAppended += '<tr>' +
226            '<td id="mysize" ' +
227                'style="cursor: pointer; padding: 6px; font-size: 0.7em; text-align: center;" ' +
228                'onmouseover="onHoverInChangeSize(event, this)" ' +
229                'onmouseout="onHoverOutChangeSize(event, this)" ' +
230                'onclick="onClickChangeSize(event, this)" ' +
231            '>' + size + ' x ' + size + '</td>' +
232        '</tr><tr>' +
233            '<td id="preferences" style="cursor: pointer; padding: 6px;"><img ' +
234                'style="margin: auto; display: block; opacity: 0.6;" ' +
235                'onmouseover="onHoverInEditIcons(event, this)" ' +
236                'onmouseout="onHoverOutEditIcons(event, this)" ' +
237                'onclick="onClickEditIcons(event, this)" ' +
238                'src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA30lEQVQ4T5WTAQ3CMBBF3xSABBwACgAHOIA5wAGgAAkMBVgABcwCDnAA+eSaHKVdtybL0vXf67/fteJ3rIErcLPnGK3/TauEYAuc7XsLzLsgKYD0O+BkhXJxyEEE0GJK8LaiO7DsAkjYALUTab5x85xTtKA+pw4SFz+BSamFfUdQF0DBJkewFlzkdMooeaS+N4kU1gKQbf0LPoc4p+9m2XDMiqC+PTldAa9gtQSQLg5VEJ2Y3kUHYaM4IzmQk7aPA0HGlomO24+6L0BFM4OMPGEIIEAeDjDIQagLt1VBNh/joyfQKnMuZwAAAABJRU5ErkJggg==" ' +
239            '/></td>' +
240        '</tr>';
241
242    // icons
243    for (var i = 0; i < size; i++){
244        toBeAppended += '<tr style="padding: 3px;"><td class="icons" ' +
245                'onmouseover="onHoverInCell(event, this)" ' +
246                'onmouseout="onHoverOutCell(event, this)" ' +
247                'onclick="onClickIconCell(event, this)" ' +
248                'onkeydown=setNewIconTextsToSudokuTable(event) ' +
249                'style="cursor: pointer; padding: 18px;"' +
250            '>?</td></tr>';
251    }
252    toBeAppended += '</tbody></table>';
253
254    return toBeAppended;
255}
256
257function createSudokuTable(selectedSize, container){
258    "use strict"
259    if (!container) container = 'body';
260    if (!selectedSize) selectedSize = 6;
261    window.userSelectedSize = selectedSize;
262    var possibleSudokus = getPossibleSudokus();
263
264    possibleSudokus.sort( function(a,b){ return a.size-b.size });
265    if (selectedSize < possibleSudokus[0].size) selectedSize = possibleSudokus[0].size;
266    for( var i = 0; i < possibleSudokus.length - 1; i++){
267        if (possibleSudokus[i].size < selectedSize && possibleSudokus[i+1].size > selectedSize) selectedSize = possibleSudokus[i].size;
268    }
269    if (selectedSize > possibleSudokus[possibleSudokus.length - 1].size) selectedSize = possibleSudokus[possibleSudokus.length - 1].size;
270
271    var sudoku = possibleSudokus.filter(function(a){ return a.size === selectedSize })[0];
272    var id = 0;
273
274    $( container ).children().remove();
275    $( container ).append('<div id="sudoku" style="cursor: default;">' +
276            '<table><tbody><tr><td id="sudokutd"></td><td id="icontd"></td></tr></tbody></table>' +
277        '</div>');
278    var toBeAppended = createBigTable(sudoku, id);
279    $( '#sudokutd' ).append( toBeAppended );
280    toBeAppended = createPossibleIconsArea(sudoku);
281    $( '#icontd' ).append( toBeAppended );
282
283    $( '#sudoku' ).prepend('<div id="overlay" ' +
284            'onclick="" ' +
285            'onmouseover="onHoverInOverlay()" ' +
286            'onmouseout="onHoverOutOverlay()" ' +
287            'style="z-index: 99; margin: 25px; position:absolute; background: rgba(245,245,245,0.6);"' +
288        '>' +
289        '<div id="overlaytextaddition" ' +
290            'style="margin-top: -1em; text-align: right; font-size: 1em;" ' +
291        '></div>' +
292        '<div id="overlaytext" ' +
293            'style="cursor: pointer; margin: auto; text-align: center; font-size: 3em; padding-top: 3em;" ' +
294        '></div>' +
295    '</div>');
296    $('#overlay').height($('#sudokucontainer').outerHeight());
297    $('#overlay').width($('#sudokucontainer').outerWidth());
298
299    createRowAndColCounter(sudoku);
300
301    fillSudokuTable(sudoku);
302}
303
304function fillSudokuTable(sudoku){
305    var signs = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" ];
306    var opacity = 0.3;
307    var colors = getColors(opacity);
308
309    var allowedSigns = signs.splice(0, sudoku.size);
310    $('.sudokucells').removeClass().addClass('sudokucells').css('background', 'white').text('?');
311    $('.icons').text('?').css('background', 'white');
312
313    var valid = true;
314    for (var j = 0; j < allowedSigns.length; j++){
315        var mySign = allowedSigns[j];
316        var myColor = colors[j];
317        for (var i = 0; i < sudoku.size; i++){
318            var validCells = $('.sudokucells:not(.hasBeenEdited)').not('.has' + mySign);
319            var max = validCells.length;
320            if ( max === 0 ) {
321                valid = false;
322                break;
323            }
324
325            var rnd = getRandomInt( max );
326            validCells.eq(rnd).text(mySign).addClass('hasBeenEdited').css('background', myColor);
327            validCells.eq(rnd).attr('value', mySign);
328            $('.icons').eq(j).text(mySign).css('background', myColor).attr("value", mySign);
329
330            var myTable = validCells.eq(rnd).attr('table');
331            var myRow = validCells.eq(rnd).attr('row');
332            var myCol = validCells.eq(rnd).attr('col');
333            $('.sudokucells[table="' + myTable + '"]').addClass('has' + mySign);
334            $('.sudokucells[row="' + myRow + '"]').addClass('has' + mySign);
335            $('.sudokucells[col="' + myCol + '"]').addClass('has' + mySign);
336        }
337        if (!valid) break;
338    }
339    console.log("valid sukodu: " + valid);
340
341    if (!valid){
342        var counter = $('#overlaytextaddition').text();
343        counter = (counter === "") ? 0 : parseInt(counter) + 1;
344        $('#overlaytextaddition').text(counter);
345
346        if (sudoku.size < 7) {
347            window.setTimeout(function(){ fillSudokuTable(sudoku); }, 100);
348        } else {
349            window.setTimeout(function(){ fillSudokuTable(sudoku); }, 0);
350        }
351    } else {
352        hideSomeCells();
353        saveThisSudoku();
354    }
355}
356
357function getSudokuSize(){
358    return $('#sudokucontainer').attr('size');
359}
360
361function getMySudoku(){
362    var mySudoku = [];
363    var sudokuSize = getSudokuSize();
364
365    $('.sudokucells').each(function(index, cell){
366        mySudoku.push({
367            cellid: $(cell).attr("cellid"),
368            row: $(cell).attr("row"),
369            col: $(cell).attr("col"),
370            table: $(cell).attr("table"),
371            value: $(cell).attr("value"),
372            size: sudokuSize
373        });
374    });
375
376    mySudoku.sort(function(a,b){ return (a.row === b.row) ? a.col - b.col : a.row - b.row; });
377
378    return mySudoku;
379}
380
381function hideSomeCells(){
382    var span = '<span class="hideable" clicked="false" solved="false" ' +
383            'onclick="onClickInEmptyCell(event, this)" ' +
384            'onmouseover="onHoverInEmptyCell(event, this)" ' +
385            'onmouseout="onHoverOutEmptyCell(event, this)"' +
386            'style="cursor: pointer; width: 30px; border: 2px dashed gainsboro; padding: 27px; margin: -29px 0 0 -52px; text-align: center; position: absolute; background: white;"' +
387        '>?</span>';
388
389    var size = getSudokuSize();
390
391    for (var j = 0; j < 2; j++){
392        for (var i = 0; i < size; i++){
393            var rnd = getRandomInt( size );
394            var target = $('.sudokucells[table="' + (i+1) + '"]').eq(rnd);
395            if (target.children().length === 0) target.append(span);
396        }
397    }
398
399    $('#overlaytext').text('start');
400    $('#sizechooser').text(size + ' x ' + size);
401    $('#overlay').click(hideOverlay);
402}
403
404function checkSudokuSolved(){
405    var check = true;
406    $('.hideable').css({
407        "border": "2px dashed black",
408        "margin": "-29px 0 0 -52px",
409        "z-index": "2"
410    });
411    $('.hideable').each(function(index,span){
412        var myText = $(span).text();
413        var myValue = $(span).parent().attr('value')
414        var correctText = $('.icons[value="' + myValue + '"]').text();
415        if ( myText !== correctText ){
416            check = false;
417            $(span).css({
418                "border-color": "hotpink",
419                "z-index": "5"
420            }).animate({
421                    "border-width": "20px",
422                    "margin": "-40px 0px 0px -60px"
423                }, {
424                    queue: true,
425                    duration: 333
426            }).animate({
427                    "border-width": "3px",
428                    "margin": "-30px 0px 0px -52px"
429                }, {
430                    queue: true,
431                    duration: 999
432            });
433            $('icons').click(checkSudokuSolved);
434        }
435    });
436    if (check) {
437        $('.hideable').remove();
438        yeah();
439    }
440}
441
442var saveToServer = function(str) {
443    $.ajax({
444        type : "POST",
445        url : "../php/savesudoku.php",
446        dataType : 'json',
447        cache: false,
448        data : {
449            json : JSON.stringify(str)
450        }
451    });
452};
453
454var getStoredSudokus = function() {
455    $.get( "../php/sudoku.txt", function( str ) {
456        debugger;
457    });
458}
459
460
461function saveThisSudoku(){
462    var mySudoku = getMySudoku();
463    var sudokuSize = Math.sqrt( $('.sudokucells').length );
464    var sudokuString = "" + sudokuSize + ":";
465    $(mySudoku).each(function(index, element){
466        sudokuString += element.value;
467        if (index % sudokuSize === sudokuSize-1 && index !== mySudoku.length - 1) sudokuString += "|";
468    });
469    console.log(sudokuString);
470
471    // aus jedem validen Sudoku lassen sich durch vertauschen von Zeilen/Spalten innerhalb der Tables neue valide Sudokus erstellen...
472    saveToServer(sudokuString);
473}
474
475function randomColor(){
476    var max = 25;
477    $('.sudokucells').each( function(index, element){
478        var colors = getColors(0.3);
479        var rnd = getRandomInt( colors.length );
480        $(element).css("background", colors[rnd]);
481    });
482    if (window.counterForColor++ < max){
483        window.setTimeout(randomColor, 100);
484    }
485}
486
487function yeah(){
488    $('#overlaytext').text(':) super!');
489    $('#overlay').fadeIn(1500)
490        .attr("onmouseout", "")
491        .attr("onmouseover", "")
492        .click(function(){
493        createSudokuTable(window.userSelectedSize);
494    });
495
496    window.counterForColor = 0;
497    window.setTimeout(randomColor, 10);
498}
499
500
501createSudokuTable(6);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.