【问题标题】:Converting a PGN to a list of FEN strings in nodejs (chess notations)将 PGN 转换为 nodejs 中的 FEN 字符串列表(国际象棋符号)
【发布时间】:2015-09-20 23:21:20
【问题描述】:

我正在使用 nodejs 构建一个与国际象棋相关的应用程序。我一直在尝试尽可能多地使用chess.js,但我认为我在功能方面遇到了障碍。在扩展该功能之前,我想确保没有其他工具可以满足我的需要。

我正在寻找一种将 PGN 字符串转换为 FEN 移动列表的方法。我希望在 chess.js 中使用 load_pgn() 将移动加载到对象中,然后遍历每个移动并调用 fen() 函数来输出当前的 FEN。然而,chess.js 似乎没有办法在游戏中走步。除非我错过了什么。

我宁愿不必解析字符串,但如果必须的话。有什么建议吗?

解决方案:

另请参阅下面 efirvida 的答案以获取解决方案

这样的东西(未经测试)似乎有效。该函数接受一个使用chess.js 创建的Chess 对象,该对象已经加载了一个PGN。

function getMovesAsFENs(chessObj) {
    var moves = chessObj.history();
    var newGame = new Chess();
    var fens = [];
    for (var i = 0; i < moves.length; i++) {
      newGame.move(moves[i]);
      fens.push(newGame.fen());
    }
    return fens;
}

【问题讨论】:

    标签: node.js chess chessboard.js fen


    【解决方案1】:

    去github页面看看.load_pgnlink

    var chess = new Chess();
    pgn = ['[Event "Casual Game"]',
           '[Site "Berlin GER"]',
           '[Date "1852.??.??"]',
           '[EventDate "?"]',
           '[Round "?"]',
           '[Result "1-0"]',
           '[White "Adolf Anderssen"]',
           '[Black "Jean Dufresne"]',
           '[ECO "C52"]',
           '[WhiteElo "?"]',
           '[BlackElo "?"]',
           '[PlyCount "47"]',
           '',
           '1.e4 e5 2.Nf3 Nc6 3.Bc4 Bc5 4.b4 Bxb4 5.c3 Ba5 6.d4 exd4 7.O-O',
           'd3 8.Qb3 Qf6 9.e5 Qg6 10.Re1 Nge7 11.Ba3 b5 12.Qxb5 Rb8 13.Qa4',
           'Bb6 14.Nbd2 Bb7 15.Ne4 Qf5 16.Bxd3 Qh5 17.Nf6+ gxf6 18.exf6',
           'Rg8 19.Rad1 Qxf3 20.Rxe7+ Nxe7 21.Qxd7+ Kxd7 22.Bf5+ Ke8',
           '23.Bd7+ Kf8 24.Bxe7# 1-0'];
    
    chess.load_pgn(pgn.join('\n'));
    // -> true
    
    chess.fen()
    // -> 1r3kr1/pbpBBp1p/1b3P2/8/8/2P2q2/P4PPP/3R2K1 b - - 0 24
    

    类似

    moves = chess.history();
    var chess1 = new Chess();
    for (move in moves){
        chess1.move(move);
        fen = chess1.fen()
    }
    

    【讨论】:

    • 是的,我阅读了 API。问题是,一旦加载 PGN,就没有获取所有移动的所有 FEN 位置的功能。您只能获得当前的举动。
    • 使用.history(),您可以获得所有动作,然后从每个动作的分档位置迭代它们
    • 但是如果你在加载 PGN 后在同一个国际象棋实例中移动我认为因为无效移动而不起作用,我认为我更好地使用新的国际象棋实例,也许我错了并且有效很好,但我不这么认为
    • 你完全正确。我刚刚对其进行了测试,您需要创建一个新的棋盘来继续下棋。我将恢复我的编辑
    【解决方案2】:

    (不是真正的答案;只是需要额外格式化的评论。)

    你的getMovesAsFENs 函数也可以写成:

    function getMovesAsFENs(chessObj) {
        return chessObj.history().map(function(move) {
            chessObj.move(move);
            return chessObj.fen();
        });
    }
    

    也许对你来说并不重要,但这符合我的整洁感。

    【讨论】:

    • 酷!我完全忘记了一个简单的映射。
    【解决方案3】:

    这是一个端到端的答案,添加了一些 ES6 糖:

    const Chess = require('chess.js').Chess;
    const chess1 = new Chess();
    const chess2 = new Chess();
    const startPos = chess2.fen();
    const pgn = `1.e4 c5 0-1`;
    
    chess1.load_pgn(pgn);
    let fens = chess1.history().map(move => {
      chess2.move(move);
      return chess2.fen();
    });
    
    //the above technique will not capture the fen of the starting position.  therefore:
    fens = [startPos, ...fens];
    
    //double checking everything
    fens.forEach(fen => console.log(fen));
    

    【讨论】:

      【解决方案4】:

      “但是,chess.js 似乎没有办法通过 在游戏中移动。除非我错过了什么。”。

      你是对的(因为我现在已经多次阅读整个图书馆)。并且需要回顾历史的所有内容基本上都是撤消然后重做动作,而没有集成某种真正的导航(以这种方式解决它是一个有趣的选择,它的优点是在某些任务中快速点亮,但缺点是对于其他看似简单的任务(如您需要的任务)来说真的很痛苦)。

      免责声明(我编写了以下工具),在过去 5 年多的时间里,我一直在创建一个工具 (isepic-chess.js),类似于 chess.js,我认为它正在慢慢实现... 该库将移动历史存储在一个对象中,其中包含(fen、from_square、to_square、san 等)等信息,并且还有某种带有移动索引和一些移动导航助手的“光标”。

      所以使用 isepic-chess.js 你可以在解析 PGN 游戏后调用棋盘方法board.fenHistoryExport() 来获取 FEN 列表:

      var example_pgn = `[Event "m1 London"]
      [Site "?"]
      [Date "1861.07.??"]
      [Round "9"]
      [White "Kolisch, Ignatz"]
      [Black "Anderssen, Adolf"]
      [Result "0-1"]
      [Annotator "JvR"]
      [SetUp "1"]
      [FEN "5r1k/pp4pp/3r3q/8/3PpP1P/1P2NbP1/PB1Q3K/R7 b - - 0 30"]
      [PlyCount "13"]
      [EventDate "1861.??.??"]
      
      30... Rxf4 $1 {Anderssen starts fireworks.} 31. Qe1 (31.gxf4 $2 Qxh4+ 32.Kg1
      Rg6+) 31... Rg6 (31...Rxh4+ $1 32.gxh4 Rg6 $1) 32. Bc1 (32.Ng2 $1) 32... Rxh4+
      $1 33. gxh4 Qf4+ 34. Kh3 Bg2+ $1 35. Nxg2 Qf3+ 36. Kh2 Qxg2# { Anderssen won
      the match by this mate (+4, =2, -3).} 0-1`;
      
      var board = Ic.initBoard({
        pgn : example_pgn
      });
      
      console.log(board.fenHistoryExport());
      

      README.md 中有一个更完整的 node.js exampleconst {Ic} = require("isepic-chess"); 导入的东西,让它在 node.js 中运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-02
        • 2012-03-25
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        • 1970-01-01
        • 2021-06-01
        • 2011-07-10
        相关资源
        最近更新 更多