You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用eval()实现棋盘棋子与方格对象的互相访问?

国际象棋棋盘性能优化方案

核心问题分析

当前实现中依赖eval()通过字符串名称获取对象,以及遍历方格查找关联对象的方式,导致深度预判走法时性能极差——计算深度2的400种走法耗时20秒。核心原因是eval()的动态解析开销极大,遍历查找也会带来不必要的时间消耗。

解决方案

1. 建立对象映射表(兼容现有逻辑的快速修改)

如果暂时无法调整现有对象的初始化流程,创建两个全局/模块级的映射对象,将字符串名称与实际对象直接关联:

// 存储所有方格对象,键为方格名称字符串
const squaresMap = {
  a1, a2, a3, ..., h8 // 填入所有已创建的方格对象
};

// 存储所有棋子对象,键为棋子名称字符串
const piecesMap = {
  whiteRook1, whiteRook2, whiteKing, ..., blackQueen // 填入所有已创建的棋子对象
};

替换所有eval()调用为映射表查找:

  • 查询a1方格中棋子是否存活:
console.log(piecesMap[a1.occupiedBy].alive); // true
  • 查询a1前方方格是否空闲:
console.log(squaresMap[a1.north1].occupiedBy !== 'none'); // false

这种方式将eval()的动态解析替换为O(1)的对象属性访问,性能会得到质的提升。

2. 初始化时直接存储对象引用(最优性能方案)

如果可以调整对象的初始化顺序,直接在对象属性中存储对方的引用而非字符串名称,完全消除字符串查找开销:

实现步骤:

  1. 先创建空的映射表(解决初始化顺序冲突问题):
const squares = {};
const pieces = {};
  1. 创建所有方格对象并存入映射表,后续统一设置相邻方格引用:
// 先创建所有方格框架
squares.a1 = { occupiedBy: null, north1: null, east1: null /* 其他属性 */ };
squares.a2 = { occupiedBy: null, south1: null, north1: null /* 其他属性 */ };
// ... 依次创建a3到h8的所有方格

// 统一设置相邻方格的引用
squares.a1.north1 = squares.a2;
squares.a2.south1 = squares.a1;
squares.a1.east1 = squares.b1;
squares.b1.west1 = squares.a1;
// ... 完成所有相邻方格的关联
  1. 创建棋子对象并与方格双向关联:
pieces.whiteRook1 = {
  square: squares.a1,
  value: 5,
  alive: true,
  // 其他属性
};
// 将棋子关联到对应方格
squares.a1.occupiedBy = pieces.whiteRook1;

访问方式:

  • 查询a1方格中棋子是否存活:
console.log(squares.a1.occupiedBy.alive); // true
  • 查询a1前方方格是否空闲:
console.log(squares.a1.north1.occupiedBy === null); // false

JS允许对象循环引用,只要不需要序列化这些对象(如存储到本地或网络传输),就不会有任何问题,这种方式的性能是最优的。

3. 避免遍历查找的补充技巧

如果需要通过棋子快速定位方格(或反之),可以给每个对象添加唯一标识属性(比如方格加squareId,棋子加pieceId),结合映射表实现O(1)的查找,彻底避免遍历64个方格的低效操作。

内容的提问来源于stack exchange,提问作者panup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 13:01:15