和大家分享一个经典的游戏项目——井字棋游戏。这个项目不仅能带你回味童年的乐趣,还能帮助你练习 HTML、CSS 和 JavaScript 编程。
项目介绍
井字棋游戏是一个两人对战游戏,玩家轮流在一个3x3的网格上标记 X 或 O。先将三个标记连成一条直线(水平、垂直或对角线)的玩家获胜。如果所有的格子都被填满且没有玩家获胜,则游戏结束,结果为平局。
代码实现
<!DOCTYPE html>
<html lang="en">
<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;
background-color: #f9f9f9;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
/* 设置标题样式 */
h1 {
font-size: 2.5em;
color: #333;
margin-bottom: 20px;
}
/* 设置游戏板的样式 */
#game-board {
display: grid;
grid-template-columns: repeat(3, 120px);
grid-template-rows: repeat(3, 120px);
gap: 10px;
background-color: #333;
padding: 10px;
border-radius: 10px;
}
/* 设置每个单元格的样式 */
.cell {
width: 120px;
height: 120px;
background-color: #fff;
border: 2px solid #ddd;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3em;
color: #333;
cursor: pointer;
transition: background-color 0.3s, transform 0.3s;
}
/* 设置单元格的悬停效果 */
.cell:hover {
background-color: #f0f0f0;
transform: scale(1.05);
}
/* 设置 X 的样式 */
.cell.x {
color: #ff6347; /* 番茄色 */
}
/* 设置 O 的样式 */
.cell.o {
color: #4682b4; /* 钢蓝色 */
}
/* 设置按钮的样式 */
button {
margin-top: 20px;
padding: 10px 20px;
font-size: 1.2em;
color: #fff;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
/* 设置按钮的悬停效果 */
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<h1>井字棋游戏</h1>
<!-- 游戏板 -->
<div id="game-board">
<div class="cell" data-index="0"></div>
<div class="cell" data-index="1"></div>
<div class="cell" data-index="2"></div>
<div class="cell" data-index="3"></div>
<div class="cell" data-index="4"></div>
<div class="cell" data-index="5"></div>
<div class="cell" data-index="6"></div>
<div class="cell" data-index="7"></div>
<div class="cell" data-index="8"></div>
</div>
<!-- 重新开始按钮 -->
<button id="reset-button">重新开始</button>
<script>
// 获取所有单元格元素
const cells = document.querySelectorAll('.cell');
// 获取重新开始按钮
const resetButton = document.getElementById('reset-button');
// 设置当前玩家,默认为 'X'
let currentPlayer = 'X';
// 创建一个长度为 9 的数组,用于存储游戏状态,初始值为 null
let board = Array(9).fill(null);
// 标记游戏是否在进行中
let gameActive = true;
// 定义胜利组合
const winningCombinations = [
[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 checkWinner = () => {
for (const [a, b, c] of winningCombinations) {
if (board[a] && board[a] === board[b] && board[a] === board[c]) {
return board[a];
}
}
return board.includes(null) ? null : 'Tie';
};
// 处理单元格点击事件
const handleClick = (e) => {
const index = e.target.dataset.index;
// 如果单元格已被点击或游戏已结束,则返回
if (board[index] || !gameActive) return;
// 更新单元格内容和样式
board[index] = currentPlayer;
e.target.textContent = currentPlayer;
e.target.classList.add(currentPlayer.toLowerCase());
// 检查是否有获胜者
const winner = checkWinner();
if (winner) {
gameActive = false;
if (winner === 'Tie') {
alert("平局!");
} else {
alert(`${winner} 胜!`);
}
return;
}
// 切换当前玩家
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
};
// 重置游戏
const resetGame = () => {
board.fill(null);
cells.forEach(cell => {
cell.textContent = '';
cell.classList.remove('x', 'o');
});
currentPlayer = 'X';
gameActive = true;
};
// 为每个单元格添加点击事件监听器
cells.forEach(cell => cell.addEventListener('click', handleClick));
// 为重新开始按钮添加点击事件监听器
resetButton.addEventListener('click', resetGame);
</script>
</body>
</html>