Создание судоку на веб-странице может показаться сложной задачей, но с использованием CSS, HTML и немного JavaScript, это становится увлекательным процессом. В этой статье мы рассмотрим, как создать судоку с нуля, используя технологии веб-разработки. Мы обсудим алгоритмы генерации головоломок, методы решения и особенности оформления с помощью CSS.

Что за игра

Судоку — это популярная логическая головоломка, где задача заключается в заполнении сетки 9×9 цифрами так, чтобы в каждом ряду, каждом столбце и каждом 3×3 подблоке не повторялись числа от 1 до 9. В веб-разработке создание судоку включает несколько этапов: создание структуры HTML, оформление с использованием CSS и логика игры на JavaScript.

Создание структуры HTML

Первый шаг — создание базовой структуры HTML для судоку. Для этого нам потребуется создать таблицу 9×9.

<!DOCTYPE html>

<html lang="ru">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Судоку</title>

<link rel="stylesheet" href="styles.css">

</head>

<body>

<div class="sudoku-container">

<table class="sudoku-grid">

<!-- Таблица 9x9 -->

<!-- Вставляем HTML-код для создания таблицы -->

<tbody>

<!-- Создаем строки и ячейки таблицы -->

<script>

document.addEventListener('DOMContentLoaded', () => {

const sudokuGrid = document.querySelector('.sudoku-grid');

for (let i = 0; i < 9; i++) {

const row = document.createElement('tr');

for (let j = 0; j < 9; j++) {

const cell = document.createElement('td');

if (i % 3 === 0) cell.classList.add('bold-border-top');

if (j % 3 === 0) cell.classList.add('bold-border-left');

row.appendChild(cell);

}

sudokuGrid.appendChild(row);

}

});

</script>

</tbody>

</table>

<button id="generate">Сгенерировать Судоку</button>

<button id="solve">Решить Судоку</button>

</div>

<script src="script.js"></script>

</body>

</html>

Оформление с использованием CSS

CSS позволяет нам создать красивую и удобную таблицу для судоку. Мы используем grid layout для равномерного распределения ячеек.

/* styles.css */

body {

margin: 0;

font-family: Arial, sans-serif;

background-color: #f9f9f9;

}

.sudoku-container {

display: flex;

flex-direction: column;

align-items: center;

padding-top: 50px;

}

.sudoku-grid {

border-collapse: collapse;

}

.sudoku-grid td {

width: 40px;

height: 40px;

border: 1px solid #000;

text-align: center;

font-size: 20px;

vertical-align: middle;

}

.sudoku-grid .bold-border-top {

border-top-width: 2px;

}

.sudoku-grid .bold-border-left {

border-left-width: 2px;

}

button {

margin: 10px;

padding: 10px 20px;

font-size: 16px;

cursor: pointer;

}

Логика игры на JavaScript

Теперь добавим JavaScript для генерации и решения судоку. Сначала создадим генератор головоломок.

// script.js

document.addEventListener('DOMContentLoaded', () => {

const generateButton = document.getElementById('generate');

const solveButton = document.getElementById('solve');

const sudokuGrid = document.querySelector('.sudoku-grid');

generateButton.addEventListener('click', () => generateSudoku(sudokuGrid));

solveButton.addEventListener('click', () => {

const grid = getGridFromDOM(sudokuGrid);

if (solveSudoku(grid)) {

renderGrid(sudokuGrid, grid);

} else {

alert('Невозможно решить данное судоку.');

}

});

});

function generateSudoku(sudokuGrid) {

let grid = [...Array(9)].map(e => Array(9).fill(0));

fillGrid(grid);

removeNumbers(grid);

renderGrid(sudokuGrid, grid);

}

function fillGrid(grid) {

// Функция для заполнения сетки допустимыми числами

for (let i = 0; i < 9; i++) {

for (let j = 0; j < 9; j++) {

let num = Math.floor(Math.random() * 9) + 1;

while (!isValid(grid, i, j, num)) {

num = Math.floor(Math.random() * 9) + 1;

}

grid[i][j] = num;

}

}

}

function removeNumbers(grid) {

let attempts = 5;

while (attempts > 0) {

const row = Math.floor(Math.random() * 9);

const col = Math.floor(Math.random() * 9);

if (grid[row][col] !== 0) {

const backup = grid[row][col];

grid[row][col] = 0;

let gridCopy = grid.map(row => row.slice());

if (!solveSudoku(gridCopy)) {

grid[row][col] = backup;

attempts--;

}

}

}

}

function renderGrid(sudokuGrid, grid) {

const cells = sudokuGrid.querySelectorAll('td');

cells.forEach((cell, index) => {

const row = Math.floor(index / 9);

const col = index % 9;

cell.textContent = grid[row][col] !== 0 ? grid[row][col] : '';

});

}

function solveSudoku(grid) {

const emptyCell = findEmptyCell(grid);

if (!emptyCell) return true;

const [row, col] = emptyCell;

for (let num = 1; num <= 9; num++) {

if (isValid(grid, row, col, num)) {

grid[row][col] = num;

if (solveSudoku(grid)) {

return true;

}

grid[row][col] = 0;

}

}

return false;

}

function findEmptyCell(grid) {

for (let i = 0; i < 9; i++) {

for (let j = 0; j < 9; j++) {

if (grid[i][j] === 0) {

return [i, j];

}

}

}

return null;

}

function isValid(grid, row, col, num) {

for (let i = 0; i < 9; i++) {

if (grid[row][i] === num || grid[i][col] === num) {

return false;

}

const boxRow = 3 * Math.floor(row / 3) + Math.floor(i / 3);

const boxCol = 3 * Math.floor(col / 3) + (i % 3);

if (grid[boxRow][boxCol] === num) {

return false;

}

}

return true;

}

function getGridFromDOM(sudokuGrid) {

const grid = [...Array(9)].map(e => Array(9).fill(0));

const cells = sudokuGrid.querySelectorAll('td');

cells.forEach((cell, index) => {

const row = Math.floor(index / 9);

const col = index % 9;

grid[row][col] = cell.textContent ? parseInt(cell.textContent) : 0;

});

return grid;

}

Заключение

Создание судоку с использованием HTML, CSS и JavaScript — это отличный способ улучшить свои навыки веб-разработки. Вы научитесь создавать сложные макеты с помощью CSS grid, а также поймете основы алгоритмов генерации и решения головоломок. Судоку может стать отличным проектом для портфолио, демонстрирующим ваши способности в области веб-разработки.