Files
HTML-Game/tic-tac-toe.html
T

192 lines
4.9 KiB
HTML

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Крестики-нолики</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #0f0f23;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
font-family: 'Segoe UI', sans-serif;
color: #eee;
}
h1 { color: #7b68ee; margin-bottom: 10px; }
#status {
font-size: 1.3em;
margin-bottom: 15px;
min-height: 35px;
color: #ffd700;
}
.board {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 5px;
}
.cell {
width: 100px;
height: 100px;
background: #1a1a3e;
border: 2px solid #7b68ee;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3em;
font-weight: bold;
cursor: pointer;
transition: all 0.2s;
}
.cell:hover { background: #2a2a5e; transform: scale(1.05); }
.cell.x { color: #ff6b6b; }
.cell.o { color: #4ecdc4; }
.cell.win { background: #2a4a2a; border-color: #0f0; box-shadow: 0 0 15px #0f0; }
#scoreBoard {
margin-top: 20px;
font-size: 1.1em;
display: flex;
gap: 30px;
}
#restart {
margin-top: 20px;
padding: 10px 30px;
font-size: 1em;
background: #7b68ee;
color: #fff;
border: none;
border-radius: 8px;
cursor: pointer;
transition: 0.3s;
}
#restart:hover { background: #6a5acd; transform: scale(1.05); }
</style>
</head>
<body>
<h1>❌ Крестики-нолики</h1>
<div id="status">Ваш ход (X)</div>
<div class="board" id="board"></div>
<div id="scoreBoard">
<span>Вы (X): <b id="xs">0</b></span>
<span>НИЧЬЯ: <b id="ds">0</b></span>
<span>Компьютер (O): <b id="os">0</b></span>
</div>
<button id="restart">Новая игра</button>
<script>
const board = document.getElementById('board');
const status = document.getElementById('status');
let cells = Array(9).fill('');
let currentTurn = 'X';
let gameActive = true;
let scores = { X: 0, O: 0, D: 0 };
const wins = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
function render() {
board.innerHTML = '';
cells.forEach((val, i) => {
const div = document.createElement('div');
div.className = 'cell' + (val === 'X' ? ' x' : val === 'O' ? ' o' : '');
div.textContent = val;
div.onclick = () => move(i);
board.appendChild(div);
});
}
function checkWin(player) {
return wins.find(w => w.every(i => cells[i] === player));
}
function isDraw() { return cells.every(c => c !== ''); }
function move(i) {
if (!gameActive || cells[i] || currentTurn !== 'X') return;
cells[i] = 'X';
render();
const w = checkWin('X');
if (w) { endGame('X', w); return; }
if (isDraw()) { endGame('D'); return; }
currentTurn = 'O';
status.textContent = 'Компьютер думает...';
setTimeout(aiMove, 400);
}
function aiMove() {
let best = -Infinity, bestMove = -1;
for (let i = 0; i < 9; i++) {
if (cells[i]) continue;
cells[i] = 'O';
let sc = minimax(false, 0);
cells[i] = '';
if (sc > best) { best = sc; bestMove = i; }
}
cells[bestMove] = 'O';
render();
const w = checkWin('O');
if (w) { endGame('O', w); return; }
if (isDraw()) { endGame('D'); return; }
currentTurn = 'X';
status.textContent = 'Ваш ход (X)';
}
function minimax(isMax, depth) {
if (checkWin('O')) return 10 - depth;
if (checkWin('X')) return depth - 10;
if (isDraw()) return 0;
if (isMax) {
let best = -Infinity;
for (let i = 0; i < 9; i++) {
if (cells[i]) continue;
cells[i] = 'O';
best = Math.max(best, minimax(false, depth + 1));
cells[i] = '';
}
return best;
} else {
let best = Infinity;
for (let i = 0; i < 9; i++) {
if (cells[i]) continue;
cells[i] = 'X';
best = Math.min(best, minimax(true, depth + 1));
cells[i] = '';
}
return best;
}
}
function endGame(result, wLine) {
gameActive = false;
if (result === 'D') {
status.textContent = '🤝 Ничья!';
scores.D++;
} else {
const name = result === 'X' ? 'Вы победили!' : 'Компьютер победил!';
status.textContent = (result === 'X' ? '🎉 ' : '😞 ') + name;
scores[result]++;
if (wLine) {
const allCells = board.children;
wLine.forEach(i => allCells[i].classList.add('win'));
}
}
document.getElementById('xs').textContent = scores.X;
document.getElementById('os').textContent = scores.O;
document.getElementById('ds').textContent = scores.D;
}
document.getElementById('restart').onclick = () => {
cells = Array(9).fill('');
currentTurn = 'X';
gameActive = true;
status.textContent = 'Ваш ход (X)';
render();
};
render();
</script>
</body>
</html>