├── README.md ├── index.html ├── pic └── sudoku.png ├── script ├── app.js ├── sudoku-grid-generator.js └── sudoku-grid-template.js └── style ├── style.css ├── style.css.map └── style.scss /README.md: -------------------------------------------------------------------------------- 1 | # sudokumar 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Sudokumar 8 | 9 | 10 | 11 | 12 |

Sudokumar

13 | 14 |
15 | 16 |
17 |
18 |
19 |
Good Game/Nice Try
20 |
21 | 00: 22 | 00: 23 | 00 24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 127 |
128 |
129 | Mistake: 130 | 0/5 131 |
132 |
133 |
134 | 135 | 136 | 137 | 138 | 139 |
Erase
140 |
141 |
New Game
142 |
143 |
144 |
1
145 |
2
146 |
3
147 |
4
148 |
5
149 |
6
150 |
7
151 |
8
152 |
9
153 |
154 |
155 | 00: 156 | 00: 157 | 00 158 |
159 |
160 |
161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /pic/sudoku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jihadable/sudokumar/d5505d0c71aeb214d888b5bf670e6d8fcff85c23/pic/sudoku.png -------------------------------------------------------------------------------- /script/app.js: -------------------------------------------------------------------------------- 1 | var out = console.log.bind(document) 2 | 3 | const bigBox = document.querySelectorAll(".big-box"); 4 | const box = document.querySelectorAll(".box") 5 | 6 | const numbers = document.querySelectorAll(".number") 7 | const erase = document.querySelector(".erase") 8 | 9 | let arrNumbers = [1,2,3,4,5,6,7,8,9] 10 | 11 | // load window 12 | window.addEventListener("load",function(){ 13 | 14 | // set display 15 | document.querySelector(".new-game").style.height = `${document.querySelector(".erase").clientHeight}px` 16 | 17 | let height = `${document.querySelector(".new-game").clientHeight}px` 18 | document.querySelector(".new-game").style.lineHeight = height 19 | 20 | if (window.matchMedia("(min-width: 600px)").matches){ 21 | numbers.forEach(function(number){ 22 | number.style.height = `${number.clientWidth}px` 23 | }) 24 | } 25 | 26 | if (window.matchMedia("(max-width: 600px)").matches){ 27 | // document.querySelector(".mid").insertBefore(document.querySelector(".timer"), erase) 28 | 29 | const info = document.querySelector(".info") 30 | 31 | info.appendChild(mistake.parentElement) 32 | info.appendChild(document.querySelector(".timer")) 33 | info.style.display = "flex" 34 | out(info) 35 | } 36 | 37 | // put number into grid 38 | numberToGrid() 39 | 40 | // hide numbers 41 | hideNumbers() 42 | 43 | // highlight the first number 44 | let element = newBoxes[0] 45 | let row = 1 46 | let column = 1 47 | addClassRowColumn(element,row,column) 48 | }) 49 | 50 | // function put numbers into grid 51 | import { sudokuGrid } from "./sudoku-grid-generator.js" 52 | 53 | let newBoxes = [] 54 | function numberToGrid(){ 55 | 56 | // new array of boxes 57 | for (let j = 1 ; j <= 9 ; j++){ 58 | for (let k = 1 ; k <= 9 ; k++){ 59 | for (let i = 0 ; i < box.length ; i++){ 60 | if (box[i].classList.contains(`${j}-${k}`)){ 61 | newBoxes.push(box[i]) 62 | } 63 | } 64 | } 65 | } 66 | 67 | // input the numbers to grid 68 | for (let i = 0 ; i < newBoxes.length ; i++){ 69 | newBoxes[i].innerHTML = sudokuGrid[i] 70 | } 71 | } 72 | 73 | // function hide numbers 74 | let gridNumbers = [] 75 | let randomNumbers = [] 76 | function hideNumbers(){ 77 | for (let i = 0 ; i < newBoxes.length ; i++){ 78 | gridNumbers.push(i) 79 | } 80 | 81 | for (let i = 0 ; i < 45 ; i++){ 82 | gridNumbers = shuffle(gridNumbers) 83 | randomNumbers.push(gridNumbers[gridNumbers.length - 1]) 84 | gridNumbers.pop() 85 | } 86 | 87 | for (let i = 0 ; i < 45 ; i++){ 88 | newBoxes[randomNumbers[i]].innerHTML = "" 89 | } 90 | } 91 | 92 | // click grid 93 | box.forEach(function(box){ 94 | box.addEventListener("click",function(){ 95 | 96 | // get the row and column for class 97 | let row = box.classList.item(1)[0] 98 | let column = box.classList.item(1)[2] 99 | 100 | if (!done){ 101 | addClassRowColumn(box,row,column) 102 | } 103 | }) 104 | }) 105 | 106 | // function arrow 107 | document.addEventListener("keydown",function(el){ 108 | let key = el.key 109 | 110 | let element 111 | let row 112 | let column 113 | 114 | for (let i = 0 ; i < newBoxes.length ; i++){ 115 | if (newBoxes[i].classList.contains("click")){ 116 | element = newBoxes[i] 117 | row = parseInt(element.classList.item(1)[0]) 118 | column = parseInt(element.classList.item(1)[2]); 119 | } 120 | } 121 | 122 | if (key == "ArrowUp" && row > 1){ 123 | row--; 124 | } 125 | 126 | else if (key == "ArrowDown" && row < 9){ 127 | row++; 128 | } 129 | 130 | else if (key == "ArrowLeft" && column > 1){ 131 | column--; 132 | } 133 | 134 | else if (key == "ArrowRight" && column < 9){ 135 | column++; 136 | } 137 | 138 | for (let j = 0 ; j < newBoxes.length ; j++){ 139 | if (newBoxes[j].classList.item(1)[0] == row && newBoxes[j].classList.item(1)[2] == column){ 140 | element = newBoxes[j] 141 | } 142 | } 143 | 144 | if (element != undefined && row != undefined && column != undefined && !done){ 145 | addClassRowColumn(element,row,column) 146 | } 147 | }) 148 | 149 | // add side-click class to row and column 150 | function addClassRowColumn(element,row,column){ 151 | 152 | // remove all the class 153 | for (let i = 0 ; i < newBoxes.length ; i++){ 154 | newBoxes[i].classList.remove("click","side-click") 155 | } 156 | 157 | // add side class 158 | for (let i = 0 ; i < element.parentElement.children.length ; i++){ 159 | element.parentElement.children[i].classList.add("side-click") 160 | } 161 | 162 | for (let i = 1 ; i <= 9 ; i++){ 163 | for (let k = 0 ; k < newBoxes.length ; k++){ 164 | 165 | // check row, column, and same number 166 | let number = element.innerHTML 167 | 168 | if ((newBoxes[k].classList.item(1) == `${row}-${i}` || newBoxes[k].classList.item(1) == `${i}-${column}`) || (newBoxes[k].innerHTML == number && number != "")){ 169 | newBoxes[k].classList.add("side-click") 170 | element.classList.remove("side-click") 171 | } 172 | } 173 | } 174 | 175 | // add click class 176 | element.classList.remove("side-click") 177 | element.classList.add("click") 178 | } 179 | 180 | // function check row, column, and same number 181 | function checkRowColum(element,number,row,column,value=true){ 182 | 183 | // check siblings 184 | let siblings = element.parentElement.children 185 | for (let i = 0 ; i < siblings.length ; i++){ 186 | if (siblings[i].innerHTML == number && value){ 187 | siblings[i].classList.add("bg-red") 188 | } 189 | else if (siblings[i].innerHTML == number && !value){ 190 | siblings[i].classList.remove("bg-red") 191 | element.classList.remove("bg-red") 192 | } 193 | else if (siblings[i] == element && !value){ 194 | siblings[i].classList.remove("bg-red") 195 | } 196 | } 197 | 198 | // check row and column 199 | for (let i = 1 ; i <= 9 ; i++){ 200 | for (let k = 0 ; k < newBoxes.length ; k++){ 201 | if ((newBoxes[k].classList.item(1) == `${row}-${i}` || newBoxes[k].classList.item(1) == `${i}-${column}`) && newBoxes[k].innerHTML == number && value && newBoxes[k] != element){ 202 | newBoxes[k].classList.add("bg-red") 203 | } 204 | 205 | else if ((newBoxes[k].classList.item(1) == `${row}-${i}` || newBoxes[k].classList.item(1) == `${i}-${column}`) && !value && newBoxes[k].innerHTML == number){ 206 | newBoxes[k].classList.remove("bg-red") 207 | element.classList.remove("bg-red") 208 | element.classList.remove("color-red") 209 | } 210 | } 211 | } 212 | 213 | let nothingRed = 0 214 | for (let i = 0 ; i < newBoxes.length ; i++){ 215 | if (newBoxes[i].classList.contains("color-red")){ 216 | let element = newBoxes[i] 217 | let number 218 | let row = element.classList.item(1)[0] 219 | let column = element.classList.item(1)[2] 220 | if (element.innerHTML != "" && element.innerHTML != undefined){ 221 | number = element.innerHTML 222 | checkColorRed(element,number,row,column) 223 | } 224 | } 225 | else { 226 | nothingRed++ 227 | } 228 | } 229 | 230 | if (nothingRed == newBoxes.length){ 231 | checkColorRed(newBoxes[0],1,1,1,true) 232 | } 233 | } 234 | 235 | // function check color-red 236 | function checkColorRed(element,number,row,column,nothingRed=false){ 237 | 238 | if (nothingRed){ 239 | for (let i = 0 ; i < newBoxes.length ; i++){ 240 | newBoxes[i].classList.remove("bg-red") 241 | } 242 | 243 | return false 244 | } 245 | 246 | 247 | let redElement = [] 248 | 249 | for (let i = 0 ; i < newBoxes.length ; i++){ 250 | if (newBoxes[i].classList.contains("color-red")){ 251 | let text = newBoxes[i].innerHTML 252 | redElement.push(text) 253 | } 254 | } 255 | 256 | element.classList.add("bg-red") 257 | 258 | let siblings = element.parentElement.children 259 | 260 | // check siblings 261 | for (let i = 0 ; i < siblings.length ; i++){ 262 | if (siblings[i].innerHTML == number && siblings[i] != element){ 263 | siblings[i].classList.add("bg-red") 264 | } 265 | 266 | else if (siblings[i].innerHTML != number && !nothingRed && !redElement.includes(siblings[i].innerHTML)){ 267 | siblings[i].classList.remove("bg-red") 268 | } 269 | } 270 | 271 | // check row and column 272 | for (let i = 1 ; i <= 9 ; i++){ 273 | for (let k = 0 ; k < newBoxes.length ; k++){ 274 | if ((newBoxes[k].classList.item(1) == `${row}-${i}` || newBoxes[k].classList.item(1) == `${i}-${column}`) && newBoxes[k].innerHTML == number && newBoxes[k] != element && !nothingRed){ 275 | newBoxes[k].classList.add("bg-red") 276 | } 277 | 278 | else if ((newBoxes[k].classList.item(1) == `${row}-${i}` || newBoxes[k].classList.item(1) == `${i}-${column}`) && newBoxes[k].innerHTML != number && !nothingRed && !redElement.includes(newBoxes[k].innerHTML)){ 279 | newBoxes[k].classList.remove("bg-red") 280 | } 281 | } 282 | } 283 | } 284 | 285 | // enter number 286 | let firstClick = 0 287 | document.addEventListener("keydown",function(el){ 288 | let key = parseInt(el.key) 289 | if (arrNumbers.includes(key) && !done){ 290 | enterNumber(key) 291 | 292 | firstClick++ 293 | if (firstClick == 1){ 294 | timer() 295 | } 296 | } 297 | }) 298 | 299 | numbers.forEach(function(number){ 300 | number.addEventListener("click",function(){ 301 | 302 | if (!done){ 303 | let key = parseInt(number.innerHTML) 304 | enterNumber(key) 305 | 306 | firstClick++ 307 | if (firstClick == 1){ 308 | timer() 309 | } 310 | } 311 | }) 312 | }) 313 | 314 | // function enter number 315 | function enterNumber(number){ 316 | for (let i = 0 ; i < newBoxes.length ; i++){ 317 | if (newBoxes[i].classList.contains("click") && randomNumbers.includes(i)){ 318 | if (newBoxes[i].innerHTML == number){ 319 | let element = newBoxes[i] 320 | let number = element.innerHTML 321 | let row = element.classList.item(1)[0] 322 | let column = element.classList.item(1)[2] 323 | 324 | eraseNumbers(element) 325 | checkRowColum(element,number,row,column,false) 326 | addClassRowColumn(element,row,column) 327 | 328 | return 329 | } 330 | 331 | newBoxes[i].innerHTML = number 332 | 333 | if (newBoxes[i].innerHTML == number){ 334 | console.log("hai") 335 | } 336 | 337 | let index = i 338 | 339 | let element = newBoxes[i] 340 | let row = newBoxes[i].classList.item(1)[0] 341 | let column = newBoxes[i].classList.item(1)[2] 342 | 343 | 344 | // number is wrong 345 | if (number != sudokuGrid[index]){ 346 | newBoxes[index].classList.add("color-red") 347 | 348 | checkRowColum(element,number,row,column) 349 | 350 | countMistake() 351 | } 352 | 353 | // number is true 354 | else { 355 | newBoxes[index].classList.add("color-blue") 356 | newBoxes[index].classList.remove("color-red","bg-red") 357 | 358 | checkRowColum(element,number,row,column,false) 359 | 360 | checkFinish() 361 | } 362 | 363 | addClassRowColumn(element,row,column) 364 | } 365 | } 366 | } 367 | 368 | // erase number 369 | document.addEventListener("keyup",function(el){ 370 | let click = el.key; 371 | if (click == "Backspace" && !done){ 372 | // 373 | for (let i = 0 ; i < newBoxes.length ; i++){ 374 | if (newBoxes[i].classList.contains("click") && randomNumbers.includes(i)){ 375 | let element = newBoxes[i] 376 | let number = element.innerHTML 377 | let row = element.classList.item(1)[0] 378 | let column = element.classList.item(1)[2] 379 | 380 | eraseNumbers(element) 381 | checkRowColum(element,number,row,column,false) 382 | addClassRowColumn(element,row,column) 383 | } 384 | } 385 | } 386 | }) 387 | 388 | erase.addEventListener("click",function(){ 389 | for (let i = 0 ; i < newBoxes.length ; i++){ 390 | if (newBoxes[i].classList.contains("click") && randomNumbers.includes(i) && !done){ 391 | let element = newBoxes[i] 392 | let number = element.innerHTML 393 | let row = element.classList.item(1)[0] 394 | let column = element.classList.item(1)[2] 395 | 396 | eraseNumbers(element) 397 | checkRowColum(element,number,row,column,false) 398 | addClassRowColumn(element,row,column) 399 | } 400 | } 401 | }) 402 | 403 | // function erase 404 | function eraseNumbers(element){ 405 | element.innerHTML = "" 406 | } 407 | 408 | // shuffle array 409 | function shuffle(array) { 410 | array.sort(() => Math.random() - 0.5); 411 | 412 | return array 413 | } 414 | 415 | // check mistake 416 | const mistake = document.querySelector("span.mistake") 417 | const finishText = document.querySelector(".finish-text") 418 | 419 | let userMistakes = 0 420 | function countMistake(){ 421 | userMistakes++; 422 | 423 | mistake.innerHTML = `${userMistakes}/5` 424 | 425 | if (userMistakes == 5){ 426 | clearInterval(myTimer) 427 | 428 | bigBox.forEach(function(box){ 429 | box.style.filter = "blur(4px)" 430 | }) 431 | 432 | finish.style.display = "flex" 433 | setTimeout(() => { 434 | finish.style.opacity = "1" 435 | }, 500); 436 | 437 | finishText.innerHTML = "Nice Try :(" 438 | document.querySelector(".finish > .time").style.display = 'none' 439 | 440 | done = true 441 | } 442 | } 443 | 444 | // check finish 445 | const finish = document.querySelector(".finish") 446 | 447 | let done = false; 448 | function checkFinish(){ 449 | 450 | let win = 0 451 | for (let i = 0 ; i < newBoxes.length ; i++){ 452 | if (newBoxes[i].innerHTML == ""){ 453 | win++ 454 | } 455 | } 456 | 457 | if (win == 0){ 458 | clearInterval(myTimer) 459 | bigBox.forEach(function(box){ 460 | box.style.filter = "blur(4px)" 461 | }) 462 | 463 | finish.style.display = "flex" 464 | setTimeout(() => { 465 | finish.style.opacity = "1" 466 | }, 500); 467 | 468 | finishText.innerHTML = "Good Game" 469 | 470 | hourFinish.innerHTML = innerHour; 471 | minFinish.innerHTML = innerMin; 472 | secFinish.innerHTML = innerSec; 473 | 474 | done = true 475 | } 476 | } 477 | 478 | // timer 479 | const second = document.querySelector(".sec") 480 | const minute = document.querySelector(".min") 481 | const hours = document.querySelector(".hour") 482 | 483 | const secFinish = document.querySelector(".sec-finish") 484 | const minFinish = document.querySelector(".min-finish") 485 | const hourFinish = document.querySelector(".hour-finish") 486 | 487 | let myTimer; 488 | let innerSec,innerMin,innerHour; 489 | 490 | function timer(){ 491 | let sec = 2; 492 | let min = 0; 493 | let hour = 0; 494 | 495 | second.innerHTML = `01` 496 | 497 | myTimer = setInterval(() => { 498 | 499 | if (min == 60){ 500 | min = 0; 501 | hour++; 502 | } 503 | 504 | if (sec == 60){ 505 | sec = 0; 506 | min++; 507 | } 508 | 509 | // seconds 510 | if (sec < 10){ 511 | second.innerHTML = `0${sec}` 512 | } 513 | else { 514 | second.innerHTML = `${sec}` 515 | } 516 | 517 | // minutes 518 | if (min < 10){ 519 | minute.innerHTML = `0${min}:` 520 | } 521 | else { 522 | minute.innerHTML = `${min}:` 523 | } 524 | 525 | // hours 526 | if (hour < 10){ 527 | hours.innerHTML = `0${hour}:` 528 | } 529 | else { 530 | hours.innerHTML = `${hour}:` 531 | } 532 | 533 | innerSec = second.innerHTML; 534 | innerMin = minute.innerHTML; 535 | innerHour = hours.innerHTML; 536 | 537 | sec++ 538 | }, 1000); 539 | } 540 | -------------------------------------------------------------------------------- /script/sudoku-grid-generator.js: -------------------------------------------------------------------------------- 1 | let size = 9; 2 | 3 | export let sudokuGrid 4 | 5 | let grid = []; 6 | 7 | // fill the grid with zeros 8 | for (let i = 0; i < size; i++) { 9 | grid[i] = []; 10 | for (let j = 0; j < size; j++) { 11 | grid[i][j] = 0; 12 | } 13 | } 14 | 15 | // function to check if a value can be placed in a particular cell 16 | function isValid(grid, row, col, value) { 17 | 18 | // check row and column 19 | for (let i = 0; i < size; i++) { 20 | if (grid[row][i] === value || grid[i][col] === value) { 21 | return false; 22 | } 23 | } 24 | 25 | // check 3x3 block 26 | const blockRow = Math.floor(row / 3) * 3; 27 | const blockCol = Math.floor(col / 3) * 3; 28 | 29 | for (let i = 0; i < 3; i++) { 30 | for (let j = 0; j < 3; j++) { 31 | if (grid[blockRow + i][blockCol + j] === value) { 32 | return false; 33 | } 34 | } 35 | } 36 | 37 | // value can be placed in the cell 38 | return true; 39 | } 40 | 41 | // function solve the Sudoku grid 42 | function solve(grid) { 43 | for (let row = 0; row < size; row++) { 44 | for (let col = 0; col < size; col++) { 45 | if (grid[row][col] === 0) { 46 | let values = []; 47 | 48 | for (let value = 1; value <= size; value++) { 49 | if (isValid(grid, row, col, value)) { 50 | values.push(value); 51 | } 52 | } 53 | 54 | // shuffle array 55 | shuffle(values); 56 | 57 | for (let i = 0; i < values.length; i++) { 58 | grid[row][col] = values[i]; 59 | 60 | if (solve(grid)) { 61 | return true; 62 | } 63 | } 64 | 65 | grid[row][col] = 0; 66 | 67 | return false; 68 | } 69 | } 70 | } 71 | 72 | return true; 73 | } 74 | 75 | // shuffle array 76 | function shuffle(array) { 77 | for (let i = array.length - 1; i > 0; i--) { 78 | let j = Math.floor(Math.random() * (i + 1)); 79 | [array[i], array[j]] = [array[j], array[i]]; 80 | } 81 | } 82 | 83 | solve(grid); 84 | 85 | sudokuGrid = grid.flat() 86 | -------------------------------------------------------------------------------- /script/sudoku-grid-template.js: -------------------------------------------------------------------------------- 1 | export var numbersTemplate = [ 2 | [ 3 | 3,5,8,9,4,1,2,7,6, 4 | 7,9,6,2,5,8,4,3,1, 5 | 1,2,4,3,7,6,5,9,8, 6 | 4,7,1,8,2,9,3,6,5, 7 | 2,6,5,4,3,7,1,8,9, 8 | 9,8,3,6,1,5,7,4,2, 9 | 6,1,7,5,8,4,9,2,3, 10 | 5,3,9,7,6,2,8,1,4, 11 | 8,4,2,1,9,3,6,5,7 12 | ], 13 | [ 14 | 6,1,8,5,9,2,3,4,7, 15 | 7,3,9,6,8,4,2,1,5, 16 | 2,4,5,3,1,7,9,8,6, 17 | 1,8,6,9,7,5,4,2,3, 18 | 4,5,7,2,3,1,8,6,9, 19 | 9,2,3,8,4,6,5,7,1, 20 | 8,6,4,1,5,3,7,9,2, 21 | 5,9,2,7,6,8,1,3,4, 22 | 3,7,1,4,2,9,6,5,8 23 | ], 24 | [ 25 | 7,5,6,3,9,1,2,4,8, 26 | 4,1,8,2,6,7,9,3,5, 27 | 3,2,9,4,8,5,7,1,6, 28 | 2,4,7,5,1,6,3,8,9, 29 | 9,8,1,7,3,4,5,6,2, 30 | 5,6,3,9,2,8,1,7,4, 31 | 8,9,5,6,7,3,4,2,1, 32 | 1,3,4,8,5,2,6,9,7, 33 | 6,7,2,1,4,9,8,5,3 34 | ], 35 | [ 36 | 8,5,6,9,2,4,1,7,3, 37 | 4,3,1,8,6,7,2,9,5, 38 | 2,9,7,3,5,1,5,6,8, 39 | 1,7,5,6,4,8,3,2,9, 40 | 9,6,8,1,3,2,7,5,4, 41 | 3,2,4,5,7,9,6,8,1, 42 | 6,8,9,7,1,3,5,4,2, 43 | 5,1,2,4,8,6,9,3,7, 44 | 7,4,3,2,9,5,8,1,6 45 | ], 46 | // ------------------- 47 | [ 48 | 8,9,4,7,2,5,1,6,3, 49 | 7,3,6,4,9,1,2,5,8, 50 | 5,1,2,3,8,6,4,9,7, 51 | 3,5,7,9,1,8,6,2,4, 52 | 6,2,9,5,4,7,3,8,1, 53 | 4,8,1,6,3,2,9,7,5, 54 | 2,6,3,8,7,4,5,1,9, 55 | 9,7,5,1,6,3,8,4,2, 56 | 1,4,8,2,5,9,7,3,6 57 | ], 58 | [ 59 | 3,8,7,4,1,5,9,2,6, 60 | 6,5,9,2,8,7,1,4,3, 61 | 1,2,4,6,3,9,5,8,7, 62 | 5,1,6,8,7,2,4,3,9, 63 | 2,9,8,1,4,3,7,6,5, 64 | 7,4,3,9,5,6,8,1,2, 65 | 4,6,2,7,9,1,3,5,8, 66 | 9,3,1,5,2,8,6,7,4, 67 | 8,7,5,3,6,4,2,9,1 68 | ], 69 | [ 70 | 6,3,7,9,5,2,8,4,1, 71 | 2,4,8,3,6,1,5,7,9, 72 | 9,1,5,4,7,8,3,6,2, 73 | 5,7,9,2,3,6,1,8,4, 74 | 1,8,3,7,4,5,9,2,6, 75 | 4,2,6,8,1,9,7,5,3, 76 | 7,9,4,6,8,3,2,1,5, 77 | 8,5,2,1,9,4,6,3,7, 78 | 3,6,1,5,2,7,4,9,8 79 | ], 80 | [ 81 | 1,9,2,4,6,3,5,7,8, 82 | 4,7,6,8,2,5,1,3,9, 83 | 8,5,3,1,9,7,2,6,4, 84 | 2,1,8,6,5,9,3,4,7, 85 | 5,6,7,3,4,1,8,9,2, 86 | 9,3,2,4,7,8,6,1,5, 87 | 7,8,5,9,3,6,4,2,1, 88 | 3,4,1,7,8,2,9,5,6, 89 | 6,2,9,5,1,4,7,8,3 90 | ], 91 | // ------------------- 92 | [ 93 | 9,1,2,3,8,4,5,7,6, 94 | 7,3,6,2,1,5,4,8,9, 95 | 5,4,8,7,6,9,1,2,3, 96 | 1,8,5,6,9,7,2,3,4, 97 | 3,6,7,5,4,2,9,1,8, 98 | 4,2,9,8,3,1,6,5,7, 99 | 8,7,1,9,5,6,3,4,2, 100 | 6,5,3,4,2,8,7,9,1, 101 | 2,9,4,1,7,3,8,6,5 102 | ], 103 | [ 104 | 6,9,3,4,8,7,2,1,5, 105 | 7,8,2,3,1,5,4,9,6, 106 | 5,4,1,2,9,6,3,7,8, 107 | 4,5,9,7,2,1,6,8,3, 108 | 8,1,6,9,4,3,5,2,7, 109 | 3,2,7,6,5,8,9,4,1, 110 | 2,6,8,5,7,9,1,3,4, 111 | 1,3,4,8,6,2,7,5,9, 112 | 9,7,5,1,3,4,8,6,2 113 | ], 114 | [ 115 | 5,6,8,3,7,1,4,9,2, 116 | 1,9,7,8,2,4,3,5,6, 117 | 2,4,3,6,5,9,1,7,8, 118 | 7,5,6,1,3,8,9,2,4, 119 | 8,1,9,2,4,5,7,6,3, 120 | 4,3,2,7,9,6,5,8,1, 121 | 3,2,1,9,6,7,8,4,5, 122 | 9,8,4,5,1,2,6,3,7, 123 | 6,7,5,4,8,3,2,1,9 124 | ], 125 | [ 126 | 2,6,8,4,3,1,5,7,9, 127 | 9,5,7,2,6,8,4,3,1, 128 | 4,3,1,9,7,5,8,6,2, 129 | 1,4,9,8,5,6,7,2,3, 130 | 7,2,5,3,4,9,6,1,8, 131 | 3,8,6,1,2,7,9,5,4, 132 | 8,7,3,6,9,2,1,4,5, 133 | 6,9,4,5,1,3,2,8,7, 134 | 5,1,2,7,8,4,3,9,6 135 | ] 136 | // ------------------- 137 | ] -------------------------------------------------------------------------------- /style/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Courier+Prime&family=Inter&family=Nunito&family=Pacifico&family=Poppins&display=swap"); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: "Poppins", sans-serif; 7 | } 8 | 9 | body { 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | padding: 50px 0; 14 | gap: 50px; 15 | background-color: #62bf9e; 16 | } 17 | 18 | .info { 19 | width: 95vw; 20 | display: flex; 21 | align-items: center; 22 | justify-content: space-between; 23 | margin-bottom: -20px; 24 | display: none; 25 | } 26 | .info .timer { 27 | display: flex; 28 | align-items: center; 29 | align-self: center; 30 | font-size: 1.2rem; 31 | } 32 | .info .timer .sec, .info .timer .min, .info .timer .hour { 33 | font-size: 1.25rem; 34 | font-family: "Courier Prime", monospace; 35 | } 36 | 37 | .container { 38 | display: flex; 39 | align-items: center; 40 | justify-content: center; 41 | gap: 20px; 42 | } 43 | .container .content { 44 | display: grid; 45 | grid-template-columns: repeat(3, 1fr); 46 | grid-template-rows: repeat(3, 1fr); 47 | border-radius: 3px; 48 | border: 1px solid #000; 49 | position: relative; 50 | } 51 | .container .content .finish { 52 | width: 100%; 53 | position: absolute; 54 | display: flex; 55 | flex-direction: column; 56 | align-items: center; 57 | z-index: 99; 58 | left: 50%; 59 | top: 50%; 60 | transform: translate(-50%, -50%); 61 | opacity: 0; 62 | transition: all 1.5s; 63 | display: none; 64 | } 65 | .container .content .finish .finish-text { 66 | font-family: "Pacifico", cursive; 67 | font-size: 50px; 68 | } 69 | .container .content .finish .time { 70 | font-size: 1.8rem; 71 | display: flex; 72 | align-items: center; 73 | } 74 | .container .content .big-box { 75 | display: grid; 76 | grid-template-columns: repeat(3, 1fr); 77 | grid-template-rows: repeat(3, 1fr); 78 | border: 1px solid #000; 79 | } 80 | .container .content .big-box .box { 81 | width: 45px; 82 | height: 45px; 83 | font-size: 1.7rem; 84 | border: 1px solid #888; 85 | background-color: #eee; 86 | cursor: default; 87 | display: flex; 88 | justify-content: center; 89 | align-items: center; 90 | -webkit-user-select: none; 91 | -moz-user-select: none; 92 | user-select: none; 93 | } 94 | .container .content .big-box .side-click { 95 | background-color: #bbb; 96 | } 97 | .container .content .big-box .color-blue { 98 | color: blue; 99 | } 100 | .container .content .big-box .color-red { 101 | color: red; 102 | } 103 | .container .content .big-box .bg-red { 104 | background-color: rgba(255, 0, 0, 0.5); 105 | } 106 | .container .content .big-box .click { 107 | background-color: #549abb; 108 | } 109 | .container .tools { 110 | display: flex; 111 | flex-direction: column; 112 | gap: 15px; 113 | } 114 | .container .tools .mistake { 115 | align-self: center; 116 | } 117 | .container .tools .mid { 118 | display: flex; 119 | align-items: center; 120 | gap: 10px; 121 | } 122 | .container .tools .mid .erase { 123 | display: flex; 124 | flex-direction: column; 125 | align-items: center; 126 | padding: 5px 10px; 127 | border-radius: 7px; 128 | background-color: rgba(255, 255, 255, 0.4); 129 | cursor: pointer; 130 | transition: all 0.2s; 131 | -webkit-user-select: none; 132 | -moz-user-select: none; 133 | user-select: none; 134 | } 135 | .container .tools .mid .erase:hover { 136 | background-color: rgba(255, 255, 255, 0.6); 137 | } 138 | .container .tools .mid .erase div { 139 | font-size: 0.8rem; 140 | } 141 | .container .tools .mid .new-game { 142 | padding: 0 15px; 143 | background-color: rgba(255, 255, 255, 0.4); 144 | border-radius: 7px; 145 | text-align: center; 146 | cursor: pointer; 147 | transition: all 0.2s; 148 | -webkit-user-select: none; 149 | -moz-user-select: none; 150 | user-select: none; 151 | } 152 | .container .tools .mid .new-game:hover { 153 | background-color: rgba(255, 255, 255, 0.6); 154 | } 155 | .container .tools .numbers { 156 | display: grid; 157 | grid-template-columns: repeat(3, auto); 158 | grid-template-rows: repeat(3, auto); 159 | gap: 10px; 160 | } 161 | .container .tools .numbers .number { 162 | background-color: rgba(255, 255, 255, 0.4); 163 | border-radius: 7px; 164 | transition: all 0.2s; 165 | cursor: pointer; 166 | font-size: 2.1rem; 167 | display: flex; 168 | justify-content: center; 169 | align-items: center; 170 | -webkit-user-select: none; 171 | -moz-user-select: none; 172 | user-select: none; 173 | } 174 | .container .tools .numbers .number:hover { 175 | background-color: rgba(255, 255, 255, 0.6); 176 | } 177 | .container .tools .timer { 178 | display: flex; 179 | align-items: center; 180 | align-self: center; 181 | font-size: 1.2rem; 182 | } 183 | .container .tools .timer .sec, .container .tools .timer .min, .container .tools .timer .hour { 184 | font-size: 1.25rem; 185 | font-family: "Courier Prime", monospace; 186 | } 187 | 188 | @media screen and (max-width: 600px) { 189 | body { 190 | padding: 25px; 191 | gap: 25px; 192 | } 193 | .container { 194 | flex-direction: column; 195 | } 196 | .container .content { 197 | width: 95vw; 198 | height: 95vw; 199 | } 200 | .container .content .big-box .box { 201 | font-size: 1.5rem; 202 | width: calc((95vw - 8px) / 9); 203 | height: calc((95vw - 8px) / 9); 204 | } 205 | .container .tools { 206 | align-items: center; 207 | } 208 | .container .tools .numbers { 209 | width: 95vw; 210 | display: flex; 211 | align-items: center; 212 | justify-content: space-evenly; 213 | } 214 | .container .tools .numbers .number { 215 | background: none; 216 | padding: 0 5px; 217 | } 218 | .container .tools .numbers .number:hover { 219 | background-color: rgba(255, 255, 255, 0.4); 220 | } 221 | }/*# sourceMappingURL=style.css.map */ -------------------------------------------------------------------------------- /style/style.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["style.scss","style.css"],"names":[],"mappings":"AAAQ,4IAAA;AAER;EACI,SAAA;EACA,UAAA;EACA,sBAAA;EACA,kCAAA;ACAJ;;ADGA;EACI,aAAA;EACA,sBAAA;EACA,mBAAA;EACA,eAAA;EACA,SAAA;EACA,yBAAA;ACAJ;;ADGA;EACI,WAAA;EACA,aAAA;EACA,mBAAA;EACA,8BAAA;EACA,oBAAA;EACA,aAAA;ACAJ;ADEI;EACI,aAAA;EACA,mBAAA;EACA,kBAAA;EACA,iBAAA;ACAR;ADEQ;EACI,kBAAA;EACA,uCAAA;ACAZ;;ADKA;EACI,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,SAAA;ACFJ;ADII;EACI,aAAA;EACA,qCAAA;EACA,kCAAA;EACA,kBAAA;EACA,sBAAA;EACA,kBAAA;ACFR;ADIQ;EACI,WAAA;EACA,kBAAA;EACA,aAAA;EACA,sBAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;EACA,gCAAA;EACA,UAAA;EACA,oBAAA;EACA,aAAA;ACFZ;ADIY;EACI,gCAAA;EACA,eAAA;ACFhB;ADKY;EACI,iBAAA;EACA,aAAA;EACA,mBAAA;ACHhB;ADOQ;EACI,aAAA;EACA,qCAAA;EACA,kCAAA;EACA,sBAAA;ACLZ;ADOY;EACI,WAAA;EACA,YAAA;EACA,iBAAA;EACA,sBAAA;EACA,sBAAA;EACA,eAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,yBAAA;KAAA,sBAAA;UAAA,iBAAA;ACLhB;ADQY;EACI,sBAAA;ACNhB;ADSY;EACI,WAAA;ACPhB;ADUY;EACI,UAAA;ACRhB;ADWY;EACI,sCAAA;ACThB;ADYY;EACI,yBAAA;ACVhB;ADeI;EACI,aAAA;EACA,sBAAA;EACA,SAAA;ACbR;ADeQ;EACI,kBAAA;ACbZ;ADgBQ;EACI,aAAA;EACA,mBAAA;EACA,SAAA;ACdZ;ADgBY;EACI,aAAA;EACA,sBAAA;EACA,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,0CAAA;EACA,eAAA;EACA,oBAAA;EACA,yBAAA;KAAA,sBAAA;UAAA,iBAAA;ACdhB;ADgBgB;EACI,0CAAA;ACdpB;ADiBgB;EACI,iBAAA;ACfpB;ADmBY;EACI,eAAA;EACA,0CAAA;EACA,kBAAA;EACA,kBAAA;EACA,eAAA;EACA,oBAAA;EACA,yBAAA;KAAA,sBAAA;UAAA,iBAAA;ACjBhB;ADmBgB;EACI,0CAAA;ACjBpB;ADsBQ;EACI,aAAA;EACA,sCAAA;EACA,mCAAA;EACA,SAAA;ACpBZ;ADsBY;EACI,0CAAA;EACA,kBAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;EACA,yBAAA;KAAA,sBAAA;UAAA,iBAAA;ACpBhB;ADsBgB;EACI,0CAAA;ACpBpB;ADyBQ;EACI,aAAA;EACA,mBAAA;EACA,kBAAA;EACA,iBAAA;ACvBZ;ADyBY;EACI,kBAAA;EACA,uCAAA;ACvBhB;;AD8BA;EACI;IACI,aAAA;IACA,SAAA;EC3BN;ED6BE;IACI,sBAAA;EC3BN;ED6BM;IACI,WAAA;IACA,YAAA;EC3BV;ED+Bc;IACI,iBAAA;IACA,6BAAA;IACA,8BAAA;EC7BlB;EDkCM;IACI,mBAAA;EChCV;EDkCU;IACI,WAAA;IACA,aAAA;IACA,mBAAA;IACA,6BAAA;EChCd;EDkCc;IACI,gBAAA;IACA,cAAA;EChClB;EDkCkB;IACI,0CAAA;EChCtB;AACF","file":"style.css"} -------------------------------------------------------------------------------- /style/style.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Courier+Prime&family=Inter&family=Nunito&family=Pacifico&family=Poppins&display=swap'); 2 | 3 | *{ 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | font-family: 'Poppins', sans-serif; 8 | } 9 | 10 | body{ 11 | display: flex; 12 | flex-direction: column; 13 | align-items: center; 14 | padding: 50px 0; 15 | gap: 50px; 16 | background-color: #62bf9e; 17 | } 18 | 19 | .info{ 20 | width: 95vw; 21 | display: flex; 22 | align-items: center; 23 | justify-content: space-between; 24 | margin-bottom: -20px; 25 | display: none; 26 | 27 | .timer{ 28 | display: flex; 29 | align-items: center; 30 | align-self: center; 31 | font-size: 1.2rem; 32 | 33 | .sec,.min,.hour{ 34 | font-size: 1.25rem; 35 | font-family: 'Courier Prime', monospace; 36 | } 37 | } 38 | } 39 | 40 | .container{ 41 | display: flex; 42 | align-items: center; 43 | justify-content: center; 44 | gap: 20px; 45 | 46 | .content{ 47 | display: grid; 48 | grid-template-columns: repeat(3,1fr); 49 | grid-template-rows: repeat(3,1fr); 50 | border-radius: 3px; 51 | border: 1px solid #000; 52 | position: relative; 53 | 54 | .finish{ 55 | width: 100%; 56 | position: absolute; 57 | display: flex; 58 | flex-direction: column; 59 | align-items: center; 60 | z-index: 99; 61 | left: 50%; 62 | top: 50%; 63 | transform: translate(-50%,-50%); 64 | opacity: 0; 65 | transition: all 1.5s; 66 | display: none; 67 | 68 | .finish-text{ 69 | font-family: 'Pacifico', cursive; 70 | font-size: 50px; 71 | } 72 | 73 | .time{ 74 | font-size: 1.8rem; 75 | display: flex; 76 | align-items: center; 77 | } 78 | } 79 | 80 | .big-box{ 81 | display: grid; 82 | grid-template-columns: repeat(3,1fr); 83 | grid-template-rows: repeat(3,1fr); 84 | border: 1px solid #000; 85 | 86 | .box{ 87 | width: 45px; 88 | height: 45px; 89 | font-size: 1.7rem; 90 | border: 1px solid #888; 91 | background-color: #eee; 92 | cursor: default; 93 | display: flex; 94 | justify-content: center; 95 | align-items: center; 96 | user-select: none; 97 | } 98 | 99 | .side-click{ 100 | background-color: #bbb; 101 | } 102 | 103 | .color-blue{ 104 | color: blue; 105 | } 106 | 107 | .color-red{ 108 | color: red; 109 | } 110 | 111 | .bg-red{ 112 | background-color: rgb(255,0,0,.5); 113 | } 114 | 115 | .click{ 116 | background-color: #549abb; 117 | } 118 | } 119 | } 120 | 121 | .tools{ 122 | display: flex; 123 | flex-direction: column; 124 | gap: 15px; 125 | 126 | .mistake{ 127 | align-self: center; 128 | } 129 | 130 | .mid{ 131 | display: flex; 132 | align-items: center; 133 | gap: 10px; 134 | 135 | .erase{ 136 | display: flex; 137 | flex-direction: column; 138 | align-items: center; 139 | padding: 5px 10px; 140 | border-radius: 7px; 141 | background-color: rgb(255,255,255,.4); 142 | cursor: pointer; 143 | transition: all .2s; 144 | user-select: none; 145 | 146 | &:hover{ 147 | background-color: rgb(255,255,255,.6); 148 | } 149 | 150 | div{ 151 | font-size: .8rem; 152 | } 153 | } 154 | 155 | .new-game{ 156 | padding: 0 15px; 157 | background-color: rgb(255,255,255,.4); 158 | border-radius: 7px; 159 | text-align: center; 160 | cursor: pointer; 161 | transition: all .2s; 162 | user-select: none; 163 | 164 | &:hover{ 165 | background-color: rgb(255,255,255,.6); 166 | } 167 | } 168 | } 169 | 170 | .numbers{ 171 | display: grid; 172 | grid-template-columns: repeat(3,auto); 173 | grid-template-rows: repeat(3,auto); 174 | gap: 10px; 175 | 176 | .number{ 177 | background-color: rgb(255,255,255,.4); 178 | border-radius: 7px; 179 | transition: all .2s; 180 | cursor: pointer; 181 | font-size: 2.1rem; 182 | display: flex; 183 | justify-content: center; 184 | align-items: center; 185 | user-select: none; 186 | 187 | &:hover{ 188 | background-color: rgb(255,255,255,.6); 189 | } 190 | } 191 | } 192 | 193 | .timer{ 194 | display: flex; 195 | align-items: center; 196 | align-self: center; 197 | font-size: 1.2rem; 198 | 199 | .sec,.min,.hour{ 200 | font-size: 1.25rem; 201 | font-family: 'Courier Prime', monospace; 202 | } 203 | } 204 | } 205 | } 206 | 207 | // responsive code 208 | @media screen and (max-width: 600px) { 209 | body{ 210 | padding: 25px; 211 | gap: 25px; 212 | } 213 | .container{ 214 | flex-direction: column; 215 | 216 | .content{ 217 | width: 95vw ; 218 | height: 95vw; 219 | 220 | .big-box{ 221 | 222 | .box{ 223 | font-size: 1.5rem; 224 | width: calc((95vw - 8px)/9); 225 | height: calc((95vw - 8px)/9); 226 | } 227 | } 228 | } 229 | 230 | .tools{ 231 | align-items: center; 232 | 233 | .numbers{ 234 | width: 95vw; 235 | display: flex; 236 | align-items: center; 237 | justify-content: space-evenly; 238 | 239 | .number{ 240 | background: none; 241 | padding: 0 5px; 242 | 243 | &:hover{ 244 | background-color: rgb(255,255,255,.4); 245 | } 246 | } 247 | } 248 | } 249 | } 250 | } --------------------------------------------------------------------------------