<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Игра "Стратегия"</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background: #f4f4f4;
padding: 20px;
}
h1 {
color: #222;
}
#scoreboard,
#status {
font-size: 20px;
margin: 10px 0;
}
#board {
display: grid;
grid-template-columns: repeat(10, 40px);
grid-gap: 2px;
margin: auto;
width: fit-content;
border: 2px solid #333;
background: #ccc;
}
.cell {
width: 40px;
height: 40px;
background: #fff;
border: 1px solid #999;
cursor: pointer;
transition: background 0.3s, border 0.3s;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
font-weight: bold;
}
.cell:hover {
background: #f0f0f0;
}
.player1 {
background-color: lightblue;
}
.player2 {
background-color: lightgreen;
}
.winning {
animation: pulse 1s infinite;
border: 3px solid red !important;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
#controls {
margin-top: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
background-color: #333;
color: #fff;
border-radius: 5px;
transition: background 0.3s;
margin: 0 5px;
}
button:hover {
background-color: #555;
}
@media (max-width: 500px) {
#board {
grid-template-columns: repeat(10, 30px);
grid-gap: 2px;
}
.cell {
width: 30px;
height: 30px;
font-size: 14px;
}
}
</style>
</head>
<body>
<h1>Игра "Стратегия"</h1>
<div id="scoreboard">Игрок 1: 0 | Игрок 2: 0 | Ничья: 0</div>
<div id="status">Ход игрока 1</div>
<div id="board"></div>
<div id="controls">
<button id="undoBtn">Отмена хода</button>
<button id="resetBtn">Новая игра</button>
</div>
<audio id="moveSound" src="move.mp3" preload="auto"></audio>
<audio id="winSound" src="win.mp3" preload="auto"></audio>
<script>
const boardSize = 10;
const winningCount = 5;
let currentPlayer = 1;
let gameActive = true;
let score = { player1: 0, player2: 0, draws: 0 };
let boardState = new Array(boardSize * boardSize).fill(0);
let moveHistory = [];
const boardElement = document.getElementById("board");
const statusElement = document.getElementById("status");
const scoreboardElement = document.getElementById("scoreboard");
const resetBtn = document.getElementById("resetBtn");
const undoBtn = document.getElementById("undoBtn");
const moveSound = document.getElementById("moveSound");
const winSound = document.getElementById("winSound");
function updateScoreboard() {
scoreboardElement.textContent = `Игрок 1: ${score.player1} | Игрок 2: ${score.player2} | Ничья: ${score.draws}`;
}
function createBoard() {
boardElement.innerHTML = "";
for (let i = 0; i < boardSize * boardSize; i++) {
const cell = document.createElement("div");
cell.classList.add("cell");
cell.dataset.index = i;
cell.addEventListener("click", () => handleCellClick(cell, i));
boardElement.appendChild(cell);
}
}
function handleCellClick(cell, index) {
if (!gameActive || boardState[index] !== 0) return;
if (moveSound) {
moveSound.currentTime = 0;
moveSound.play();
}
boardState[index] = currentPlayer;
cell.classList.add(currentPlayer === 1 ? "player1" : "player2");
moveHistory.push({ index, player: currentPlayer });
const row = Math.floor(index / boardSize);
const col = index % boardSize;
if (checkWin(row, col, currentPlayer)) {
statusElement.textContent = `Победа игрока ${currentPlayer}!`;
gameActive = false;
if (currentPlayer === 1) score.player1++;
else score.player2++;
updateScoreboard();
highlightWinningSequence(row, col, currentPlayer);
if (winSound) {
winSound.currentTime = 0;
winSound.play();
}
return;
}
if (boardState.every(cell => cell !== 0)) {
statusElement.textContent = "Ничья!";
gameActive = false;
score.draws++;
updateScoreboard();
return;
}
currentPlayer = currentPlayer === 1 ? 2 : 1;
statusElement.textContent = `Ход игрока ${currentPlayer}`;
}
function checkWin(row, col, player) {
function countDir(dr, dc) {
let count = 0;
let r = row + dr;
let c = col + dc;
while (
r >= 0 &&
r < boardSize &&
c >= 0 &&
c < boardSize &&
boardState[r * boardSize + c] === player
) {
count++;
r += dr;
c += dc;
}
return count;
}
const directions = [
{ dr: 0, dc: 1 },
{ dr: 1, dc: 0 },
{ dr: 1, dc: 1 },
{ dr: 1, dc: -1 }
];
for (const { dr, dc } of directions) {
let count = 1;
count += countDir(dr, dc);
count += countDir(-dr, -dc);
if (count >= winningCount) return true;
}
return false;
}
function highlightWinningSequence(row, col, player) {
const directions = [
{ dr: 0, dc: 1 },
{ dr: 1, dc: 0 },
{ dr: 1, dc: 1 },
{ dr: 1, dc: -1 }
];
let winningSequence = [];
for (const { dr, dc } of directions) {
let sequence = [{ row, col }];
let r = row + dr;
let c = col + dc;
while (
r >= 0 &&
r < boardSize &&
c >= 0 &&
c < boardSize &&
boardState[r * boardSize + c] === player
) {
sequence.push({ row: r, col: c });
r += dr;
c += dc;
}
r = row - dr;
c = col - dc;
while (
r >= 0 &&
r < boardSize &&
c >= 0 &&
c < boardSize &&
boardState[r * boardSize + c] === player
) {
sequence.push({ row: r, col: c });
r -= dr;
c -= dc;
}
if (sequence.length >= winningCount) {
winningSequence = sequence;
break;
}
}
winningSequence.forEach(pos => {
const index = pos.row * boardSize + pos.col;
const cell = boardElement.querySelector(`[data-index='${index}']`);
if (cell) {
cell.classList.add("winning");
}
});
}
function undoMove() {
if (!gameActive || moveHistory.length === 0) return;
const lastMove = moveHistory.pop();
boardState[lastMove.index] = 0;
const cell = boardElement.querySelector(`[data-index='${lastMove.index}']`);
if (cell) cell.classList.remove("player1", "player2", "winning");
currentPlayer = lastMove.player;
statusElement.textContent = `Ход игрока ${currentPlayer}`;
}
function resetGame() {
boardState = new Array(boardSize * boardSize).fill(0);
currentPlayer = 1;
gameActive = true;
moveHistory = [];
statusElement.textContent = `Ход игрока ${currentPlayer}`;
createBoard();
}
resetBtn.addEventListener("click", resetGame);
undoBtn.addEventListener("click", undoMove);
createBoard();
updateScoreboard();
</script>
</body>
</html>