<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>井字棋游戏</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.cell {
transition: all 0.3s ease;
}
.cell:hover {
transform: scale(1.05);
background-color: #f3f4f6;
}
.winning-cell {
animation: pulse 1s infinite;
}
@keyframes pulse {
0% { background-color: #fef08a; }
50% { background-color: #fbbf24; }
100% { background-color: #fef08a; }
}
</style>
</head>
<body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-xl p-6 md:p-8 max-w-md w-full">
<h1 class="text-3xl md:text-4xl font-bold text-center text-gray-800 mb-2">井字棋游戏</h1>
<p class="text-gray-600 text-center mb-6">经典三子棋游戏</p>
<div class="mb-6">
<div class="flex justify-between items-center mb-4">
<div class="text-lg font-semibold text-gray-700">
当前玩家:
<span id="current-player" class="text-indigo-600">X</span>
</div>
<button id="reset-btn" class="px-4 py-2 bg-indigo-500 text-white rounded-lg hover:bg-indigo-600 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-indigo-300">
重新开始
</button>
</div>
<div id="status" class="text-center text-lg font-medium text-gray-700 mb-4 h-8">
游戏进行中...
</div>
</div>
<div class="grid grid-cols-3 gap-3 mb-6">
<!-- 9个格子 -->
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="0"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="1"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="2"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="3"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="4"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="5"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="6"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="7"></div>
<div class="cell bg-gray-50 border-2 border-gray-200 rounded-lg h-24 md:h-32 flex items-center justify-center text-4xl font-bold cursor-pointer" data-index="8"></div>
</div>
<div class="bg-gray-50 rounded-lg p-4">
<h3 class="font-semibold text-gray-700 mb-2">游戏规则:</h3>
<ul class="text-sm text-gray-600 list-disc pl-5 space-y-1">
<li>玩家轮流在格子中放置 X 或 O</li>
<li>先连成一条线(横、竖或斜)的玩家获胜</li>
<li>若所有格子填满仍未分出胜负,则为平局</li>
</ul>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// 游戏状态
const board = Array(9).fill('');
let currentPlayer = 'X';
let gameActive = true;
// 获取DOM元素
const cells = document.querySelectorAll('.cell');
const currentPlayerDisplay = document.getElementById('current-player');
const statusDisplay = document.getElementById('status');
const resetButton = document.getElementById('reset-btn');
// 胜利组合
const winPatterns = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], // 横行
[0, 3, 6], [1, 4, 7], [2, 5, 8], // 竖行
[0, 4, 8], [2, 4, 6] // 对角线
];
// 游戏消息
const winningMessage = () => `玩家 ${currentPlayer} 获胜!`;
const drawMessage = () => `平局!`;
const currentPlayerTurn = () => `当前玩家: ${currentPlayer}`;
// 初始化游戏
statusDisplay.innerHTML = currentPlayerTurn();
// 处理单元格点击
function handleCellClick(e) {
const cell = e.target;
const index = parseInt(cell.getAttribute('data-index'));
// 检查是否可以放置棋子
if (board[index] !== '' || !gameActive) return;
// 更新棋盘和显示
board[index] = currentPlayer;
cell.textContent = currentPlayer;
cell.classList.add(currentPlayer === 'X' ? 'text-blue-600' : 'text-red-600');
// 检查是否获胜
if (checkWin()) {
endGame(false);
return;
}
// 检查是否平局
if (isDraw()) {
endGame(true);
return;
}
// 切换玩家
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
currentPlayerDisplay.textContent = currentPlayer;
statusDisplay.innerHTML = currentPlayerTurn();
}
// 检查胜利条件
function checkWin() {
return winPatterns.some(pattern => {
const [a, b, c] = pattern;
return board[a] !== '' && board[a] === board[b] && board[a] === board[c];
});
}
// 检查平局
function isDraw() {
return board.every(cell => cell !== '');
}
// 结束游戏
function endGame(isDraw) {
gameActive = false;
if (isDraw) {
statusDisplay.innerHTML = drawMessage();
} else {
statusDisplay.innerHTML = winningMessage();
highlightWinningCells();
}
}
// 高亮胜利的格子
function highlightWinningCells() {
winPatterns.forEach(pattern => {
const [a, b, c] = pattern;
if (board[a] !== '' && board[a] === board[b] && board[a] === board[c]) {
cells[a].classList.add('winning-cell');
cells[b].classList.add('winning-cell');
cells[c].classList.add('winning-cell');
}
});
}
// 重置游戏
function resetGame() {
board.fill('');
currentPlayer = 'X';
gameActive = true;
currentPlayerDisplay.textContent = currentPlayer;
statusDisplay.innerHTML = currentPlayerTurn();
cells.forEach(cell => {
cell.textContent = '';
cell.classList.remove('winning-cell', 'text-blue-600', 'text-red-600');
});
}
// 添加事件监听器
cells.forEach(cell => cell.addEventListener('click', handleCellClick));
resetButton.addEventListener('click', resetGame);
});
</script>
</body>
</html>
index.html
index.html