使用HTML实现井字棋游戏缩略图

效果展示:

<!DOCTYPE html>
<html lang="zh-CN">
<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: #f4f4f9;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        .game-container {
            text-align: center;
            width: 400px;
        }
        .board {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            grid-template-rows: repeat(3, 1fr);
            gap: 5px;
            margin-bottom: 20px;
        }
        .cell {
            width: 100px;
            height: 100px;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #fff;
            border: 2px solid #ddd;
            font-size: 36px;
            cursor: pointer;
            transition: background-color 0.3s ease;
        }
        .cell:hover {
            background-color: #f0f0f0;
        }
        .status {
            font-size: 18px;
            margin-bottom: 20px;
        }
        button {
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            border: none;
            background-color: #007bff;
            color: #fff;
            border-radius: 5px;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>井字棋游戏</h1>
        <div class="status">
            <span id="gameStatus">玩家 X 的回合</span>
        </div>
        <div class="board" id="board">
            <!-- 9个格子 -->
            <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 onclick="restartGame()">重新开始</button>
    </div>

    <script>
        const board = document.getElementById("board");
        const gameStatus = document.getElementById("gameStatus");
        let currentPlayer = "X";
        let gameActive = true;
        let boardState = ["", "", "", "", "", "", "", "", ""];

        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]
        ];

        function handleCellClick(event) {
            const index = event.target.getAttribute("data-index");
            if (boardState[index] !== "" || !gameActive) return;

            boardState[index] = currentPlayer;
            event.target.textContent = currentPlayer;

            if (checkWinner()) {
                gameStatus.textContent = `玩家 ${currentPlayer} 胜利!`;
                gameActive = false;
            } else if (boardState.every(cell => cell !== "")) {
                gameStatus.textContent = "平局!";
                gameActive = false;
            } else {
                currentPlayer = currentPlayer === "X" ? "O" : "X";
                gameStatus.textContent = `玩家 ${currentPlayer} 的回合`;
            }
        }

        function checkWinner() {
            for (let combination of winningCombinations) {
                const [a, b, c] = combination;
                if (boardState[a] && boardState[a] === boardState[b] && boardState[a] === boardState[c]) {
                    return true;
                }
            }
            return false;
        }

        function restartGame() {
            boardState = ["", "", "", "", "", "", "", "", ""];
            gameActive = true;
            currentPlayer = "X";
            gameStatus.textContent = `玩家 ${currentPlayer} 的回合`;

            const cells = document.querySelectorAll(".cell");
            cells.forEach(cell => {
                cell.textContent = "";
            });
        }

        board.addEventListener("click", handleCellClick);
    </script>
</body>
</html>

井字棋游戏原理与实现

井字棋(Tic-Tac-Toe)是一款经典的两人棋盘游戏,玩家通过轮流在3×3的棋盘上标记自己的符号(通常是“X”和“O”),首先在任意一行、列或对角线上连续放置三个相同符号的玩家获胜。如果所有格子都被填满而没有玩家获胜,则游戏以平局结束。在本文中,我们将介绍如何使用纯HTML和JavaScript来实现一个井字棋小游戏,分析其背后的原理与实现方法。

1. HTML结构

HTML作为网页的基础结构,主要负责界面的布局。在这个井字棋游戏中,我们使用了一个div容器来包含所有的游戏元素,包括棋盘、游戏状态和控制按钮。棋盘本身由一个包含九个子元素的div容器组成,每个子元素代表棋盘上的一个格子。每个格子通过data-index属性来标识其位置,方便后续的事件处理。

除了棋盘,页面上还有一个status区域,用于显示当前的游戏状态,如“玩家 X 的回合”或“玩家 X 胜利”。此外,还有一个“重新开始”按钮,点击后可以重置游戏。

2. CSS样式

为了增强游戏的可视化效果,CSS被用来设置游戏界面的样式。棋盘由一个3×3的网格组成,使用CSS的grid布局实现,每个格子固定大小,并且设置了合适的边框和背景颜色,使得整个棋盘看起来简洁美观。同时,给格子添加了悬停效果,鼠标移到上面时会改变背景颜色,以增加用户的交互体验。

游戏的按钮也有样式,点击时会改变背景颜色,提升了游戏的互动性。

3. JavaScript逻辑

JavaScript作为游戏的核心逻辑部分,负责处理游戏的状态变化和玩家的互动。游戏通过一个名为boardState的数组来跟踪每个格子的状态。数组中的每个元素表示棋盘上的一个格子,XO表示该格子已经被标记。如果格子为空,数组中的值为空字符串。

  • 玩家的轮流: 游戏从玩家“X”开始,每次点击空的格子时,当前玩家的标记会被添加到该格子中,之后轮到另一个玩家。玩家通过切换currentPlayer来实现轮流。
  • 获胜判定: 每次玩家进行一次标记后,系统都会检查当前棋盘状态是否满足某个玩家获胜的条件。通过winningCombinations数组,保存了所有可能的获胜线(水平、垂直和对角线),在每次玩家标记后,检查这些线是否已被占据。如果某条线的三个格子都被同一玩家标记,则游戏结束,宣布该玩家获胜。
  • 平局判定: 如果所有格子都已填满并且没有任何玩家获胜,则游戏判定为平局。
  • 重新开始: 游戏提供了一个“重新开始”按钮,点击该按钮时,棋盘状态和显示内容会被重置,游戏重新开始。

4. 代码的实现过程

在代码实现过程中,我们通过添加点击事件监听器来处理玩家的每一次操作。当玩家点击某个格子时,首先判断该格子是否已经被标记,如果没有,则更新格子的状态,并检查游戏的胜负情况。如果没有人获胜且棋盘未满,则交换玩家。

此外,通过检查boardState数组是否完全填满并且没有获胜者,来判断是否发生了平局。一旦游戏结束,用户无法继续进行操作,避免了无意义的点击。

5. 总结

这个井字棋小游戏通过简洁的HTML、CSS和JavaScript实现了游戏的完整功能。HTML负责布局和结构,CSS负责美化界面,而JavaScript处理游戏逻辑和交互。通过简单的数组和事件处理,我们实现了玩家交替操作、获胜判断、平局判断以及游戏重置功能。这个游戏不仅可以作为一个娱乐项目,还能帮助初学者更好地理解前端开发中的DOM操作、事件监听、数组处理和基本的UI设计。

作者 LiveTops

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code