我正在使用nodejs构建一个与棋相关的应用程序。我一直试图尽可能多地使用chess.js
,但我认为我在功能方面遇到了障碍。在扩展该功能之前,我想确保没有其他工具能够满足我的需求。
我正在寻找一种方法将PGN字符串转换为FEN移动列表。我希望在chess.js中使用load_pgn()
将移动加载到对象中然后遍历每个移动并调用fen()
函数来输出当前FEN。然而,chess.js似乎没有办法在游戏中走动。除非我错过了什么。
我宁愿不必进入解析字符串,但如果必须的话。有什么建议?
解:
另请参阅下面的efirvida答案以获得解决方案
这样的事情(未经测试)似乎有效。该函数接受用Chess
创建的chess.js
对象,该对象已经加载了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;
}
看看github页面.load_pgn
link
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()
}
(不是真正的答案;只是需要额外格式化的评论。)
你的getMovesAsFENs
函数也可能写成:
function getMovesAsFENs(chessObj) {
return chessObj.history().map(function(move) {
chessObj.move(move);
return chessObj.fen();
});
}
也许这对你没关系,但这吸引了我的整洁感。
这是一个端到端的答案,加入了一些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));