
本文详解如何用 react 构建一个严格遵循「同奇偶行列配对」规则的 19×19 棋盘网格,修正常见着色逻辑错误,并优化渲染结构以支持后续棋子(如黑白皇后)按颜色区域限制移动。
本文详解如何用 react 构建一个严格遵循「同奇偶行列配对」规则的 19×19 棋盘网格,修正常见着色逻辑错误,并优化渲染结构以支持后续棋子(如黑白皇后)按颜色区域限制移动。
在开发国际象棋变体或策略类棋盘应用时,一个语义正确、视觉清晰的网格是基础。你提供的代码意图创建一个 19×19 的双色棋盘,其中「黑后」仅能在偶数行+偶数列(即 (row % 2 === 0 && col % 2 === 0))的格子上移动——对应白色背景;「白后」则限于奇数行+奇数列((row % 2 === 1 && col % 2 === 1))——对应深灰背景。但原始着色逻辑 row % 2 === 1 || col % 2 === 1 ? "red" : "green" 实际生成的是反斜线干扰型着色(类似条纹),导致整片区域失真,无法形成标准棋盘纹理。
✅ 正确的着色判定应基于 行列奇偶性是否一致:
当 row % 2 === col % 2 时,该格为“主色”(例如白色/浅灰);否则为“辅色”(深灰)。这一逻辑确保了每个格子的颜色与其二维坐标构成的“棋盘 parity”严格对应。
以下是重构后的完整实现,兼顾可读性、性能与扩展性:
import React, { useState, useEffect } from 'react';
function Board() {
const [gridCells, setGridCells] = useState<JSX.Element[]>([]);
const handleClick = (row: number, col: number) => {
console.log('Cell clicked:', { row, col });
// ✅ 后续可在此处校验:黑后仅允许点击 (row % 2 === 0 && col % 2 === 0),白后反之
};
useEffect(() => {
const size = 19;
const cells: JSX.Element[] = [];
// ✅ 推荐:使用嵌套循环,语义清晰、避免除法取模误差、便于调试行列索引
for (let row = 0; row < size; row++) {
for (let col = 0; col < size; col++) {
const isLightCell = row % 2 === col % 2; // true → 白色/浅灰;false → 深灰
const colorClass = isLightCell ? 'cell-light' : 'cell-dark';
cells.push(
<div
key={`${row}-${col}`} // ⚠️ 强烈建议用唯一复合 key,避免仅用 row 或 i
data-row={row}
data-col={col}
className={`grid-cell ${colorClass}`}
onClick={() => handleClick(row, col)}
/>
);
}
}
setGridCells(cells);
}, []);
return (
<div id="GridContainer" className="chessboard-grid">
{gridCells}
</div>
);
}
export default Board;? 关键改进说明:
- 着色逻辑修复:row % 2 === col % 2 是棋盘着色的数学本质,等价于 (row + col) % 2 === 0,二者任选其一均可,但前者更直观体现“行列同步性”。
- 结构优化:嵌套循环替代单层 i 遍历,消除 Math.floor(i / 19) 和 i % 19 的隐式计算,提升可维护性与调试效率。
- Key 规范:使用 ${row}-${col} 而非 i 或 ${row}_${col}(下划线易与数据属性混淆),确保 React diff 准确识别位置变更。
- 语义增强:添加 data-row/data-col 属性,方便事件处理器直接获取坐标,无需字符串解析。
? CSS 示例(供参考):
.chessboard-grid {
display: grid;
grid-template-columns: repeat(19, 1fr);
gap: 0;
width: fit-content;
border: 1px solid #333;
}
.grid-cell {
width: 24px;
height: 24px;
box-sizing: border-box;
}
.cell-light { background-color: #f8f8f8; }
.cell-dark { background-color: #3a3a3a; }
/* 可选:悬停反馈 */
.grid-cell:hover {
opacity: 0.8;
transform: scale(1.05);
}? 延伸提示(为黑白皇后逻辑铺垫):
- 黑后合法位置 ⇨ row % 2 === 0 && col % 2 === 0
- 白后合法位置 ⇨ row % 2 === 1 && col % 2 === 1
可在 handleClick 中加入运行时校验,或通过 className 动态绑定 .valid-move 样式预标记可落子格。
至此,你已拥有一套结构健壮、逻辑严谨、易于扩展的 React 棋盘组件——它不仅是视觉载体,更是游戏规则落地的第一块基石。










