剖析五子棋游戏代码:从HTML到JavaScript的逻辑构建

《剖析五子棋游戏代码:从HTML到JavaScript的逻辑构建》

一、整体结构

这个HTML文档构建了一个简单的双人手动PK五子棋游戏。整体结构上,HTML部分定义了页面的基本布局和样式,而JavaScript部分则负责处理游戏的逻辑,如棋盘的创建、棋子的放置、胜负的判断以及游戏的重新开始等功能。

二、HTML部分分析

  1. <head>标签内的设置

    • <title>标签将页面标题设置为“五子棋游戏”,这是在浏览器标签上显示的标题。
    • <style>标签中,定义了页面的样式。
      • body的背景颜色被设置为#be9416d9
      • 对于表格(<table>),设置了border - collapse: collapse,使表格边框合并。
      • 表格中的单元格(<td>)被定义了宽度为30px,高度为30px,带有2px的黑色边框,并且文本居中。
  2. <body>标签内的元素

    • 有一个<h1>标签,显示“双人手动PK五子棋”,清晰地表明游戏的类型和模式。
    • 定义了玩家1(白棋)和玩家2(黑棋),虽然只是简单的文字标识,但能让玩家清楚各自的角色。
    • 有一个<button>按钮,其onclick属性绑定了restartGame()函数,用于重新开始游戏。
    • 最重要的是创建了一个空的<table>表格,其id为“board”,这是后续通过JavaScript创建棋盘的基础。

三、JavaScript部分分析

  1. 棋盘创建

    • 通过getElementById获取到<table>元素,然后使用循环嵌套创建棋盘。
    • 外层循环控制行数,内层循环控制列数。对于每一个单元格<td>,设置了data - xdata - y属性,这可能是为了方便后续获取棋子的坐标位置。并且将创建好的单元格添加到行<tr>中,行再添加到棋盘表格中。
    • 同时,创建了一个二维数组boardState来存储棋盘上每个位置的棋子状态,初始值都为0,表示空位置。
  2. 下棋逻辑

    • 定义了一个变量currentPlayer来标记当前轮到哪个玩家下棋,1代表白棋,2代表黑棋。
    • placePiece函数用于处理下棋操作。首先获取点击单元格的坐标,然后判断该位置是否为空(即boardState[y][x]!== 0),如果不为空则直接返回,不进行下棋操作。
    • 如果位置为空,则根据当前玩家创建一个圆形的棋子<div>元素,设置其颜色(白棋或黑棋)、大小和边距等样式,然后添加到点击的单元格中,并更新boardState数组中对应位置的值为当前玩家的值。
    • 在下完棋后,调用checkWin函数来检查当前玩家是否获胜,如果获胜则弹出提示框显示获胜玩家。
    • 最后通过currentPlayer = currentPlayer === 1? 2 : 1切换玩家。
  3. 胜负判断逻辑(checkWin函数)

    • 这个函数从四个方向检查是否有五子连珠。
    • 横向检查:通过两层嵌套循环,外层循环遍历每一行,内层循环遍历每一列。当遇到当前玩家的棋子时,计数器count加1,如果count达到5则返回true表示获胜,否则遇到其他玩家的棋子或者空位置时将count重置为0。
    • 纵向检查:与横向检查类似,只是外层循环控制列数,内层循环控制行数。
    • 对角线检查(左上 - 右下):通过一个循环遍历所有可能的对角线,根据对角线的索引k计算起始行iStart和结束行iEnd,然后在内层循环中获取对应的列j = k - i,再按照与横向检查类似的逻辑判断是否有五子连珠。
    • 对角线检查(右上 - 左下):同样通过循环遍历对角线,计算起始行和结束行,然后获取对应的列j = size - 1-(k - i),进行胜负判断。
  4. 重新开始游戏(restartGame函数)

    • 这个函数非常简单,直接调用location.reload(),这会重新加载整个页面,从而达到重新开始游戏的目的。
  5. 添加点击事件

    • 通过querySelectorAll获取所有的<td>单元格,然后使用forEach方法为每个单元格添加点击事件,点击事件绑定到placePiece函数上,这样玩家点击单元格时就能下棋了。

这个五子棋游戏代码虽然简单,但涵盖了HTML和JavaScript在构建交互式游戏方面的基本用法,从页面布局到游戏逻辑的完整实现都有涉及。

完整代码:

<!DOCTYPE html>
<html>

<head>
    <title>五子棋游戏</title>
    <style>
        body {
            background-color: #be9416d9;
        }

        table {
            border-collapse: collapse;
        }

        td {
            width: 30px;
            height: 30px;
            border: 2px solid black;
            text-align: center;
        }
    </style>
</head>

<body>
    <h1>双人手动PK五子棋</h1>
    玩家1: 白棋
    玩家2: 黑棋
    <br>
    <button onclick="restartGame()">重新开始</button>
    <br>
    <br>
    <table id="board">
    </table>
    <script>
        // 创建棋盘
        const board = document.getElementById('board');
        const size = 15;
        for (let i = 0; i < size; i++) {
            const row = document.createElement('tr');
            for (let j = 0; j < size; j++) {
                const cell = document.createElement('td');
                cell.dataset.x = j;
                cell.dataset.y = i;
                row.appendChild(cell);
            }
            board.appendChild(row);
        }

        // 存储棋子状态的数组
        const boardState = [];
        for (let i = 0; i < size; i++) {
            boardState[i] = [];
            for (let j = 0; j < size; j++) {
                boardState[i][j] = 0;
            }
        }

        // 标记当前轮到哪个玩家下棋,1为白棋,2为黑棋
        let currentPlayer = 1;

        // 下棋函数
        function placePiece(cell) {
            const x = parseInt(cell.dataset.x);
            const y = parseInt(cell.dataset.y);
            if (boardState[y][x] !== 0) {
                return;
            }
            const piece = document.createElement('div');
            piece.style.width = '20px';
            piece.style.height = '20px';
            piece.style.borderRadius = '50%';
            piece.style.margin = '5px';
            if (currentPlayer === 1) {
                piece.style.backgroundColor = 'white';
            } else {
                piece.style.backgroundColor = 'black';
            }
            cell.appendChild(piece);
            boardState[y][x] = currentPlayer;
            if (checkWin(currentPlayer)) {
                alert('玩家' + currentPlayer + '获胜!');
            }
            // 切换玩家
            currentPlayer = currentPlayer === 1 ? 2 : 1;
        }


        // 检查是否获胜
        function checkWin(player) {
            // 检查横向
            for (let i = 0; i < size; i++) {
                let count = 0;
                for (let j = 0; j < size; j++) {
                    if (boardState[i][j] === player) {
                        count++;
                        if (count === 5) {
                            return true;
                        }
                    } else {
                        count = 0;
                    }
                }
            }
            // 检查纵向
            for (let j = 0; j < size; j++) {
                let count = 0;
                for (let i = 0; i < size; i++) {
                    if (boardState[i][j] === player) {
                        count++;
                        if (count === 5) {
                            return true;
                        }
                    } else {
                        count = 0;
                    }
                }
            }
            // 检查左上 - 右下对角线
            for (let k = 0; k < size * 2 - 1; k++) {
                let count = 0;
                let iStart = Math.max(0, k - size + 1);
                let iEnd = Math.min(size - 1, k);
                for (let i = iStart; i <= iEnd; i++) {
                    let j = k - i;
                    if (boardState[i][j] === player) {
                        count++;
                        if (count === 5) {
                            return true;
                        }
                    } else {
                        count = 0;
                    }
                }
            }
            // 检查右上 - 左下对角线
            for (let k = 0; k < size * 2 - 1; k++) {
                let count = 0;
                let iStart = Math.max(0, k - size + 1);
                let iEnd = Math.min(size - 1, k);
                for (let i = iStart; i <= iEnd; i++) {
                    let j = size - 1 - (k - i);
                    if (boardState[i][j] === player) {
                        count++;
                        if (count === 5) {
                            return true;
                        }
                    } else {
                        count = 0;
                    }
                }
            }
            return false;
        }

        // 给每个格子添加点击事件
        const cells = document.querySelectorAll('td');
        cells.forEach(cell => {
            cell.addEventListener('click', () => {
                placePiece(cell);
            });
        });
        function restartGame() {
            location.reload();
        }
    </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风尚云网

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值