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

如何用Chess.js或工具验证所有国际象棋代数记法有效性?

验证任意国际象棋代数记法的有效性

需求说明

我需要验证一个字符串是否属于合法的国际象棋代数记法,不需要考虑这个走法在当前棋局中是否真的能走(比如chess.js的moves()方法只能返回当前局面下的合法走法,满足不了我的需求)。希望能找到现成的字典/工具包,或者自己实现验证逻辑。

举个例子,chess.js初始局面的合法走法是:

const chess = new Chess()
chess.moves()
// -> ['a3', 'a4', 'b3', 'b4', 'c3', 'c4', 'd3', 'd4', 'e3', 'e4',
//     'f3', 'f4', 'g3', 'g4', 'h3', 'h4', 'Na3', 'Nc3', 'Nf3', 'Nh3']

而我需要覆盖的所有合法代数记法包括但不限于:['a1','a2','a3',...,'Ba1','Ba2',...,'a8=Q',...,'a8=N+']这类形式。


解决方案

方法一:正则表达式匹配

国际象棋代数记法(SAN)有明确的语法规则,可以用正则表达式直接匹配验证。以下是一个覆盖大部分常见情况的正则:

const sanRegex = /^([KQRBN]?[a-h]?[1-8]?x?[a-h][1-8](?:=[KQRBN])?[+#]?|O-O(?:-O)?)$/;

正则规则拆解:

  • [KQRBN]?:可选的棋子标识(K王、Q后、R车、B象、N马,兵无需标识)
  • [a-h]?[1-8]?:可选的消除歧义的位置(比如两个马能走到同一格子时,会加原位置的列/行,如Nbd2)
  • x?:可选的吃子符号(x表示吃子)
  • [a-h][1-8]:必填的目标格子(比如a3、d8)
  • (?:=[KQRBN])?:可选的升变标识(兵走到底线升变,如a8=Q)
  • [+#]?:可选的将军/将死标识(+将军,#将死)
  • |O-O(?:-O)?:王车易位的特殊记法(短易位O-O,长易位O-O-O)

使用示例:

function isValidSAN(san) {
  const sanRegex = /^([KQRBN]?[a-h]?[1-8]?x?[a-h][1-8](?:=[KQRBN])?[+#]?|O-O(?:-O)?)$/;
  return sanRegex.test(san);
}

// 测试用例
console.log(isValidSAN('a3')); // true
console.log(isValidSAN('Na3')); // true
console.log(isValidSAN('a8=Q+')); // true
console.log(isValidSAN('Rxe4#')); // true
console.log(isValidSAN('O-O')); // true
console.log(isValidSAN('abc')); // false

方法二:使用专门的棋类工具库

如果不想自己维护正则,可以用支持独立解析代数记法的工具库:

  • chessops:该库提供parseSan函数,可直接解析代数记法字符串,无需依赖当前棋局状态。解析失败会抛出错误,以此判断有效性。
    使用示例:
    import { parseSan } from 'chessops';
    
    function isValidSAN(san) {
      try {
        parseSan(san);
        return true;
      } catch (e) {
        return false;
      }
    }
    
  • chess.js:虽然它的moves()只返回当前局面合法走法,但可以通过创建任意棋盘,尝试用move()方法执行目标记法并捕获错误——不过这个方法有局限性,部分合法记法在特定棋盘下无法执行,不如chessops直接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:37:35