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
Easy
Medium
Hard
1
2
3
4
5
6
7
8
9
New
Clear
Hint
// 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();
});
About The Author
Livia F. Oates
I'm writing on stuff I really like. I have a dog and small rabbit.