Daily Sudoku

We can probably say that the game Sudoku is kind of a phenomenon that got extremely popular out of nowhere practically all over the world. Almost everybody I knew was solving this puzzle from time to time. It really felt like it was everybody except me, cause I simply wasn’t interested in that for some reason. Now I’m bringing you this game in a digital form which is a lot more convenient as it’s so easy to correct any random mistakes, etc.

The origin of this game is pretty hard to tell and as it’s been here more than a thousand years in China known as Magic Squares. Also worth noting is the fact that the game was first introduced to the public under a Japanese name which can be translated to: “the numbers must occur only once”. It was in the May 1979 edition of Dell Pencil Puzzles and Word Games.

Instructions:

  • Each row, column and 3×3 square must contain the numbers 1-9 only once.
Playable Sudoku - Mobile Responsive * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: Arial, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background-color: #f0f0f0; padding: 10px; } .sudoku-container { background-color: white; padding: 15px; border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.1); text-align: center; width: 100%; max-width: 500px; margin: 0 auto; } h1 { color: #333; margin-bottom: 15px; font-size: clamp(1.5rem, 5vw, 2rem); } #sudoku-board { display: grid; grid-template-columns: repeat(9, 1fr); gap: 1px; background-color: #999; border: 2px solid #333; margin: 10px auto; width: 100%; max-width: 450px; aspect-ratio: 1 / 1; } .sudoku-cell { background-color: white; display: flex; justify-content: center; align-items: center; font-size: clamp(14px, 4vw, 20px); font-weight: bold; cursor: pointer; transition: background-color 0.2s; aspect-ratio: 1 / 1; width: 100%; height: 100%; padding: 0; user-select: none; } /* Remove any extra spacing */ .sudoku-cell:empty::before { content: ""; display: inline-block; } .sudoku-cell:hover { background-color: #e0e0e0; } .sudoku-cell.selected { background-color: #b8d9ff; } .sudoku-cell.fixed-cell { color: #000; font-weight: bold; background-color: #f9f9f9; } .sudoku-cell.top-border { border-top: 2px solid #333; } .sudoku-cell.left-border { border-left: 2px solid #333; } .controls { margin-top: 20px; } .number-pad { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin: 20px 0; padding: 0 5px; } .num-btn { aspect-ratio: 1 / 1; font-size: clamp(18px, 5vw, 24px); font-weight: bold; background-color: #4CAF50; color: white; border: none; border-radius: 8px; cursor: pointer; transition: background-color 0.2s; display: flex; align-items: center; justify-content: center; width: 100%; padding: 0; -webkit-tap-highlight-color: transparent; } .num-btn:hover { background-color: #45a049; } .num-btn:active { transform: scale(0.95); } .action-buttons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 15px 0; } .action-btn { padding: 12px 5px; font-size: clamp(14px, 4vw, 16px); color: white; border: none; border-radius: 8px; cursor: pointer; transition: background-color 0.2s; font-weight: bold; -webkit-tap-highlight-color: transparent; } .action-btn:active { transform: scale(0.95); } #new-game-btn { background-color: #008CBA; } #new-game-btn:hover { background-color: #007399; } #clear-btn { background-color: #f44336; } #clear-btn:hover { background-color: #da190b; } #hint-btn { background-color: #ff9800; } #hint-btn:hover { background-color: #e68a00; } .difficulty-selector { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 15px 0; } .difficulty-btn { padding: 10px 15px; font-size: clamp(12px, 3.5vw, 14px); background-color: #f1f1f1; color: #333; border: 1px solid #ddd; border-radius: 20px; cursor: pointer; transition: all 0.2s; flex: 0 1 auto; min-width: 70px; font-weight: bold; -webkit-tap-highlight-color: transparent; } .difficulty-btn:hover { background-color: #e0e0e0; } .difficulty-btn.active { background-color: #4CAF50; color: white; border-color: #4CAF50; } .footer-text { color: #666; margin-top: 15px; font-size: clamp(12px, 3.5vw, 14px); line-height: 1.4; } /* iPhone and small phone optimizations */ @media (max-width: 380px) { .sudoku-container { padding: 10px; } .number-pad { gap: 5px; } .difficulty-btn { min-width: 60px; padding: 8px 10px; } .action-buttons { gap: 5px; } } /* Landscape mode optimization */ @media (max-height: 600px) and (orientation: landscape) { body { padding: 5px; } .sudoku-container { max-width: 400px; } #sudoku-board { max-width: 300px; } .number-pad { margin: 10px 0; } } /* Touch device optimizations */ @media (hover: none) and (pointer: coarse) { .sudoku-cell:hover { background-color: white; } .sudoku-cell.selected { background-color: #b8d9ff; } .num-btn:hover, .action-btn:hover, .difficulty-btn:hover { transform: none; } .num-btn:active, .action-btn:active { transform: scale(0.95); } }

Sudoku

// sudoku-new.js - Playable Sudoku Game (mobile responsive) class SudokuGame { constructor() { this.board = []; this.solution = []; this.difficulty = 'medium'; this.selectedCell = null; this.initBoard(); this.generateNewGame(); } initBoard() { // Initialize empty 9x9 board this.board = Array(9).fill().map(() => Array(9).fill(0)); this.solution = Array(9).fill().map(() => Array(9).fill(0)); } generateNewGame() { // Generate a solved Sudoku board this.generateSolvedBoard(); // Copy solution to current board for (let i = 0; i < 9; i++) { for (let j = 0; j Array(9).fill(0)); // Fill diagonal 3x3 boxes first (they're independent) for (let box = 0; box < 3; box++) { this.fillBox(box * 3, box * 3); } // Fill the remaining cells this.solveSudoku(this.solution); } fillBox(row, col) { let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]; this.shuffleArray(nums); let index = 0; for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { this.solution[row + i][col + j] = nums[index++]; } } } solveSudoku(board) { for (let row = 0; row < 9; row++) { for (let col = 0; col < 9; col++) { if (board[row][col] === 0) { for (let num = 1; num <= 9; num++) { if (this.isValidMove(board, row, col, num)) { board[row][col] = num; if (this.solveSudoku(board)) { return true; } board[row][col] = 0; } } return false; } } } return true; } isValidMove(board, row, col, num) { // Check row for (let x = 0; x < 9; x++) { if (board[row][x] === num) return false; } // Check column for (let x = 0; x < 9; x++) { if (board[x][col] === num) return false; } // Check 3x3 box let boxRow = Math.floor(row / 3) * 3; let boxCol = Math.floor(col / 3) * 3; for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { if (board[boxRow + i][boxCol + j] === num) return false; } } return true; } removeCellsForDifficulty() { let cellsToRemove; switch(this.difficulty) { case 'easy': cellsToRemove = 40; break; case 'medium': cellsToRemove = 50; break; case 'hard': cellsToRemove = 55; break; default: cellsToRemove = 50; } let cellsRemoved = 0; while (cellsRemoved = 0 && value <= 9) { this.board[row][col] = value; return true; } return false; } checkWin() { for (let row = 0; row < 9; row++) { for (let col = 0; col < 9; col++) { if (this.board[row][col] === 0) return false; if (this.board[row][col] !== this.solution[row][col]) return false; } } return true; } getHint() { for (let row = 0; row < 9; row++) { for (let col = 0; col 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } } // UI Handler class SudokuUI { constructor() { this.game = new SudokuGame(); this.selectedRow = null; this.selectedCol = null; this.initializeUI(); } initializeUI() { this.renderBoard(); this.attachEventListeners(); } renderBoard() { const boardElement = document.getElementById('sudoku-board'); boardElement.innerHTML = ''; for (let i = 0; i < 9; i++) { for (let j = 0; j this.handleCellClick(e)); cell.addEventListener('touchstart', (e) => { e.preventDefault(); // Prevent double-tap zoom }, { passive: false }); boardElement.appendChild(cell); } } // Check win condition if (this.game.checkWin()) { setTimeout(() => alert('Congratulations! You solved the puzzle!'), 100); } } handleCellClick(event) { const row = parseInt(event.target.dataset.row); const col = parseInt(event.target.dataset.col); // Only allow selection of editable cells if (this.game.isCellEditable(row, col)) { this.selectedRow = row; this.selectedCol = col; this.renderBoard(); } } handleNumberInput(number) { if (this.selectedRow !== null && this.selectedCol !== null) { const success = this.game.setCellValue(this.selectedRow, this.selectedCol, number); if (success) { this.renderBoard(); } } } attachEventListeners() { // Number buttons for (let i = 1; i { this.handleNumberInput(i); }); // Touch events for mobile document.getElementById(`num-${i}`).addEventListener('touchstart', (e) => { e.preventDefault(); this.handleNumberInput(i); }, { passive: false }); } // Clear button document.getElementById('clear-btn').addEventListener('click', () => { if (this.selectedRow !== null && this.selectedCol !== null) { this.game.setCellValue(this.selectedRow, this.selectedCol, 0); this.renderBoard(); } }); document.getElementById('clear-btn').addEventListener('touchstart', (e) => { e.preventDefault(); if (this.selectedRow !== null && this.selectedCol !== null) { this.game.setCellValue(this.selectedRow, this.selectedCol, 0); this.renderBoard(); } }, { passive: false }); // New Game button document.getElementById('new-game-btn').addEventListener('click', () => { this.game.generateNewGame(); this.selectedRow = null; this.selectedCol = null; this.renderBoard(); }); document.getElementById('new-game-btn').addEventListener('touchstart', (e) => { e.preventDefault(); this.game.generateNewGame(); this.selectedRow = null; this.selectedCol = null; this.renderBoard(); }, { passive: false }); // Hint button document.getElementById('hint-btn').addEventListener('click', () => { const hint = this.game.getHint(); if (hint) { this.selectedRow = hint.row; this.selectedCol = hint.col; this.game.setCellValue(hint.row, hint.col, hint.value); this.renderBoard(); } else { alert('No hints available - puzzle might be complete!'); } }); document.getElementById('hint-btn').addEventListener('touchstart', (e) => { e.preventDefault(); const hint = this.game.getHint(); if (hint) { this.selectedRow = hint.row; this.selectedCol = hint.col; this.game.setCellValue(hint.row, hint.col, hint.value); this.renderBoard(); } else { alert('No hints available - puzzle might be complete!'); } }, { passive: false }); // Difficulty buttons document.getElementById('difficulty-easy').addEventListener('click', () => { this.game.setDifficulty('easy'); this.selectedRow = null; this.selectedCol = null; document.querySelectorAll('.difficulty-btn').forEach(btn => { btn.classList.remove('active'); }); document.getElementById('difficulty-easy').classList.add('active'); this.renderBoard(); }); document.getElementById('difficulty-medium').addEventListener('click', () => { this.game.setDifficulty('medium'); this.selectedRow = null; this.selectedCol = null; document.querySelectorAll('.difficulty-btn').forEach(btn => { btn.classList.remove('active'); }); document.getElementById('difficulty-medium').classList.add('active'); this.renderBoard(); }); document.getElementById('difficulty-hard').addEventListener('click', () => { this.game.setDifficulty('hard'); this.selectedRow = null; this.selectedCol = null; document.querySelectorAll('.difficulty-btn').forEach(btn => { btn.classList.remove('active'); }); document.getElementById('difficulty-hard').classList.add('active'); this.renderBoard(); }); } } // Initialize the game when the page loads document.addEventListener('DOMContentLoaded', () => { new SudokuUI(); });