咨询:6×6表格放置6个符合国际象棋规则无冲突元素的PHP实现方案
6×6无冲突棋子放置实现方案
核心简化规则(无需复杂数学基础)
你的需求等价于6阶无攻击放置(即简化版六皇后问题),所有判断可以拆成三个极简单的规则,不需要记推导公式:
- 水平方向天然无冲突:我们给每一行固定仅放置1个标记,同一行不可能出现两个标记,直接跳过这一项的冲突检查
- 垂直方向检查:如果某一列之前已经放过标记,该列的后续位置就禁止放置
- 对角线方向检查:两个格子如果满足「行号差的绝对值 = 列号差的绝对值」,就说明两个位置在同一条斜线上,这类位置禁止放置
修正补全后的可运行代码
先补上原代码的语法遗漏(比如$totalElements = 6缺少结尾分号的问题),再把冲突判断逻辑完整落地:
$size = 6; $totalElements = 6; // 记录已被占用的列,key为列号 $colOccupied = []; // 记录已确定的标记位置,格式为 [行号 => 对应列号] $placedPositions = []; $foundResult = false; // 逐行寻找合法放置位置的简单回溯逻辑 function findValidPosition($currentRow, $size, &$colOccupied, &$placedPositions, &$foundResult) { // 已经遍历完所有行,说明找到合法方案,终止搜索 if ($currentRow > $size) { $foundResult = true; return; } // 逐列尝试当前行的可放置位置 for ($tryCol = 1; $tryCol <= $size; $tryCol++) { // 跳过已被占用的列 if (!empty($colOccupied[$tryCol])) continue; // 检查对角线冲突 $diagConflict = false; foreach ($placedPositions as $existRow => $existCol) { if (abs($currentRow - $existRow) == abs($tryCol - $existCol)) { $diagConflict = true; break; } } // 有对角线冲突就尝试下一列 if ($diagConflict) continue; // 标记当前位置为已占用,继续搜索下一行 $colOccupied[$tryCol] = true; $placedPositions[$currentRow] = $tryCol; findValidPosition($currentRow + 1, $size, $colOccupied, $placedPositions, $foundResult); // 找到合法方案就直接返回,无需继续搜索 if ($foundResult) return; // 未找到合法方案就回退选择,试下一个列 unset($colOccupied[$tryCol]); unset($placedPositions[$currentRow]); } } findValidPosition(1, $size, $colOccupied, $placedPositions, $foundResult); // 输出表格 echo '<table>'; for ($i = 1; $i <= $size; $i++) { echo '<tr>'; for ($ii = 1; $ii <= $size; $ii++) { echo '<td>'; // 判断当前单元格是否为合法放置位置 $match = (isset($placedPositions[$i]) && $placedPositions[$i] == $ii); if ($match && $totalElements) { echo '<div>X</div>'; } echo '</td>'; } echo '</tr>'; } echo '</table>';
方案特点
- 所有冲突判断都是直白的条件比较,不需要掌握复杂数学知识
- 6×6规模的计算量极小,代码执行瞬时完成,无性能压力
- 最终输出完全匹配需求:恰好放置6个X标记,每行、每列各1个标记,无水平、垂直、对角线方向的位置冲突
内容的提问来源于stack exchange,提问作者user759235
相关产品推荐
相关产品推荐

