如何高亮显示 PHP 实现的井字棋(Tic Tac Toe)获胜方格

作者:袖梨 2026-08-08

本文讲解如何在 PHP 井字棋游戏中精准高亮获胜的三个连续方格,通过重构胜利检测逻辑、提取获胜位置索引,并在 HTML 渲染时动态添加 CSS 类实现视觉突出。

本文讲解如何在 PHP 井字棋游戏中精准高亮获胜的三个连续方格,通过重构胜利检测逻辑、提取获胜位置索引,并在 HTML 渲染时动态添加 CSS 类实现视觉突出。

要让井字棋中获胜的三个方格以不同颜色高亮(如橙色),关键在于:分离“判定谁赢”与“标记哪几个格子赢”。原代码中 win() 函数仅设置 $winner 和 $msg,未记录具体获胜坐标,导致无法针对性样式化。解决方案是新增一个独立函数 winningTiles(),遍历棋盘,返回获胜方格对应的按钮编号(b1–b9)数组,再在输出表单时为对应 <input> 动态添加 CSS 类。

✅ 步骤一:定义获胜位置检测函数

将冗长的 switch 中重复的胜利判断逻辑提取为可复用函数,支持行、列、对角线三种模式:

function winningTiles(array $board): array{// 检查三行for ($i = 0; $i < 3; $i++) {if ($board[$i][0] !== ' ' && $board[$i][0] === $board[$i][1] && $board[$i][1] === $board[$i][2]) {return [$i * 3 + 1, $i * 3 + 2, $i * 3 + 3]; // b1-b3, b4-b6, b7-b9}}// 检查三列for ($i = 0; $i < 3; $i++) {if ($board[0][$i] !== ' ' && $board[0][$i] === $board[1][$i] && $board[1][$i] === $board[2][$i]) {return [$i + 1, $i + 4, $i + 7]; // b1,b4,b7 → 列0;b2,b5,b8 → 列1 等}}// 检查主对角线(左上→右下)if ($board[0][0] !== ' ' && $board[0][0] === $board[1][1] && $board[1][1] === $board[2][2]) {return [1, 5, 9];}// 检查副对角线(右上→左下)if ($board[0][2] !== ' ' && $board[0][2] === $board[1][1] && $board[1][1] === $board[2][0]) {return [3, 5, 7];}return []; // 无获胜者}

注意:该函数应放在 session_start() 之后、HTML 输出之前调用,且需传入当前棋盘状态 $_SESSION['board']。

✅ 步骤二:在视图中动态应用高亮类

替换原有硬编码的 9 个 <input> 标签,改用嵌套循环生成,并根据 $winningTiles 数组决定是否添加 class="winningTile":

<?php$winningTiles = winningTiles($_SESSION['board']);?><style>input {height: 250px;font-size: 5em;border: 3px solid black;padding: 20px;margin-top: 5px;margin-left: 5px;}.winningTile {background-color: #ff9800; /* 橙色,醒目且兼容性好 */box-shadow: 0 0 12px rgba(255, 152, 0, 0.6);}</style><form id="board" name="play" action="hw-ttt.php" method="get"><?phpforeach ($_SESSION['board'] as $rowIndex => $row) {foreach ($row as $colIndex => $cellValue) {$buttonNumber = $rowIndex * 3 + $colIndex + 1; // 转换为 b1~b9 编号$disabled = ($cellValue !== ' ') ? ' disabled' : '';$highlightClass = in_array($buttonNumber, $winningTiles) ? ' class="winningTile"' : '';printf('<input type="submit" name="b%d" value="%s"%s%s>',$buttonNumber,htmlspecialchars($cellValue), // 防 XSS,安全必备$disabled,$highlightClass);}}?></form>

✅ 步骤三:整合到主流程(关键修改点)

  1. 将原 win() 函数中仅设 $winner 的逻辑移除,不再手动调用 win()
  2. 在控制器逻辑末尾(即所有 isset($_GET['bX']) 处理完成后),直接调用 $winningTiles = winningTiles($_SESSION['board']);;
  3. 若 $winningTiles 非空,则视为游戏结束,此时 $winner = $_SESSION['player'],并禁用剩余空格(保持原逻辑);
  4. $msg 更新仍由后续逻辑控制(如 $msg = $winner . " WINs";),无需改动。

? 补充说明与最佳实践

  1. 安全性增强:使用 htmlspecialchars() 输出 value,防止恶意字符注入;
  2. 可维护性提升:避免重复的 isset() 分支,全部交由统一函数判定;
  3. 样式扩展友好:.winningTile 可自由定制背景色、边框、阴影等,不影响游戏逻辑;
  4. 平局处理兼容:当 $winningTiles 为空且 moves === 9 时,自动进入平局分支,不触发高亮。

通过以上重构,获胜方格将精准、稳定、语义清晰地高亮显示,既满足作业要求,也为后续功能扩展(如动画、音效、统计)打下坚实基础。

相关文章

精彩推荐