PHP井字棋游戏问题:点击格子无法放置X的解决方案
修复PHP井字棋点击不显示X的问题
你的代码存在两个核心问题:
- 请求方式不匹配:前端点击格子用GET传递参数,但后端只处理POST请求,导致用户的操作没被处理。
- 状态未持久化:HTTP是无状态协议,每次页面刷新都会重新初始化空棋盘,之前的操作记录会丢失。
以下是修改后的完整代码,附关键修改说明:
<!DOCTYPE html> <html> <head> <title>Tic Tac Toe</title> <style> /* Styling for the game board */ table { border-collapse: collapse; margin: auto; font-size: 25px; font-weight: bold; } td { width: 50px; height: 50px; border: 1px solid black; text-align: center; vertical-align: middle; cursor: pointer; } td:hover { background-color: #ccc; } form { margin: 0; padding: 0; } button { font-size: inherit; font-weight: inherit; } </style> </head> <body> <?php // 开启Session,用于保存棋盘状态 session_start(); // 初始化棋盘:优先从Session读取,不存在则创建空棋盘 if (!isset($_SESSION['board'])) { $_SESSION['board'] = array( array("", "", ""), array("", "", ""), array("", "", "") ); } $board = $_SESSION['board']; // 检查玩家是否获胜 function checkWin($board, $player) { // 横向检查 for ($i = 0; $i < 3; $i++) { if ($board[$i][0] == $player && $board[$i][1] == $player && $board[$i][2] == $player) { return true; } } // 纵向检查 for ($i = 0; $i < 3; $i++) { if ($board[0][$i] == $player && $board[1][$i] == $player && $board[2][$i] == $player) { return true; } } // 对角线检查 if ($board[0][0] == $player && $board[1][1] == $player && $board[2][2] == $player) { return true; } if ($board[0][2] == $player && $board[1][1] == $player && $board[2][0] == $player) { return true; } return false; } // 检查是否平局 function checkTie($board) { for ($i = 0; $i < 3; $i++) { for ($j = 0; $j < 3; $j++) { if ($board[$i][$j] == "") { return false; } } } return true; } // 处理玩家操作:兼容GET和POST请求 if (($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['row'], $_POST['col'])) || (isset($_GET['row'], $_GET['col']))) { // 获取落子位置 $row = isset($_POST['row']) ? $_POST['row'] : $_GET['row']; $col = isset($_POST['col']) ? $_POST['col'] : $_GET['col']; // 仅允许空格子落子 if ($board[$row][$col] == "") { // 玩家落子 $board[$row][$col] = "X"; // 检查玩家获胜 if (checkWin($board, "X")) { echo "<h1>你赢了!</h1>"; unset($_SESSION['board']); exit(); } // 检查平局 if (checkTie($board)) { echo "<h1>平局!</h1>"; unset($_SESSION['board']); exit(); } // 电脑随机落子 do { $comp_row = rand(0, 2); $comp_col = rand(0, 2); } while ($board[$comp_row][$comp_col] != ""); $board[$comp_row][$comp_col] = "O"; // 检查电脑获胜 if (checkWin($board, "O")) { echo "<h1>你输了!</h1>"; unset($_SESSION['board']); exit(); } // 检查平局 if (checkTie($board)) { echo "<h1>平局!</h1>"; unset($_SESSION['board']); exit(); } // 更新Session中的棋盘状态 $_SESSION['board'] = $board; } } ?> <h1>井字棋游戏</h1> <table> <?php // 渲染棋盘 for ($i = 0; $i < 3; $i++) { echo "<tr>"; for ($j = 0; $j < 3; $j++) { // 使用POST表单提交落子请求 echo "<td>"; echo "<form method='post' style='width:100%;height:100%;'>"; echo "<input type='hidden' name='row' value='$i'>"; echo "<input type='hidden' name='col' value='$j'>"; echo "<button type='submit' style='width:100%;height:100%;border:none;background:none;cursor:pointer;'>"; echo $board[$i][$j]; echo "</button>"; echo "</form>"; echo "</td>"; } echo "</tr>"; } ?> </table> </body> </html>
关键修改点说明:
- Session状态持久化:通过
session_start()开启会话,将棋盘状态存储在$_SESSION['board']中,确保页面刷新后不会丢失落子记录。 - 请求方式兼容:修改后端逻辑,同时处理GET和POST请求,保证玩家的点击操作能被正确接收。
- 前端提交优化:将每个格子的点击改为POST表单提交,既符合HTTP语义,又避免URL暴露参数,同时保证点击区域覆盖整个格子。
- 落子合法性检查:增加空格子判断,防止重复落子。
- 游戏结束重置:胜负或平局后清除Session中的棋盘状态,方便启动新游戏。
内容的提问来源于stack exchange,提问作者Christian Placido
相关产品推荐
相关产品推荐

