2015-09-20 1 views
5

Je construis une application liée aux échecs en utilisant nodejs. J'ai essayé d'utiliser chess.js autant que je peux mais je pense que j'ai atteint un barrage routier en termes de fonctionnalité. Avant d'étendre cette fonctionnalité, je voulais m'assurer qu'il n'y avait pas un autre outil capable de faire ce dont j'avais besoin.Conversion d'un PGN en une liste de chaînes FEN dans nodejs (notations d'échecs)

Je suis à la recherche d'un moyen de convertir une chaîne PGN en une liste de mouvements FEN. J'espérais utiliser load_pgn() dans chess.js pour charger les mouvements dans l'objet, puis faire une boucle sur chaque mouvement et appeler la fonction fen() pour sortir le FEN actuel. Cependant, chess.js ne semble pas avoir un moyen de parcourir les mouvements dans une partie. À moins que je ne manque quelque chose. Je préférerais ne pas avoir à entrer dans les chaînes d'analyse, mais le fera si je le dois. Aucune suggestion?

Solution:

également voir la réponse de efirvida ci-dessous pour une solution

Quelque chose comme ça (non testé) semble fonctionner. La fonction accepte un objet Chess créé avec chess.js pour lequel un PGN est déjà chargé.

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; 
} 

Répondre

4

Jetez un oeil à la page 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 

quelque chose comme

something like 

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

Ouais, je lis l'API. Le problème est qu'une fois que vous chargez le PGN, il n'y a pas de fonction pour obtenir toutes les positions FEN pour tous les mouvements. Vous ne pouvez obtenir pour le mouvement actuel. – n0pe

+0

avec le '.history()' vous pouvez obtenir tous les mouvements puis itère sur eux à partir du binning ayant la position fen pour chaque mouvement – efirvida

+0

Je mets à jour ma réponse – efirvida

3

(Pas vraiment une réponse, juste un commentaire qui a besoin de la mise en forme supplémentaire.)

Votre fonction getMovesAsFENs pourrait aussi être écrite s:

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

Peut-être qu'il n'a pas d'importance pour vous, mais cela fait appel à mon sens de neatness.

+0

Cool! J'ai complètement oublié une simple cartographie. – n0pe

1

est ici une réponse de bout en bout avec un peu de sucre ajouté dans 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));