简体   繁体   中英

How to save variations branching off of each other and initial state

I want to keep track of lines and variations of chess moves. lines can branch off of each other and inherits all the previous moves up to the branched of point called ply.

I make these definitions in code:

fen('initial', 'fen');
moves('initial', 'a b c d e f g'.split(' '));
branch('line2', 'initial', 3);
moves('line2', 'c2 d2 e2'.split(' '));

And I want to query this state like this:

// desired output is commented
ply('initial', 0) // fen
ply('initial', 3) // c
ply('initial', 5) // e
ply('line2', 0) // fen
ply('line2', 2) // b
ply('line2', 3) // c2
ply('line2', 5) // e2

I've coded this but it's unnecessarily complicated and not usable. I want a simple working code. Keep in mind that branched lines can also further be branched.

The complications come from various error cases I return. The example is the happy path, but I don't know what to do if I try to branch off of an undefined line or try to setup moves twice for an already defined line.

You could store each line as a linked list, in reversed order, so with the last ply represented in the first node of the linked list, which then links to the "parent" node, ie the preceding ply of the line, ... all the way to the root node. In other words, each line points to a leaf in the tree, and each node has a link to its parent in the tree.

With this organisation, lines can have shared nodes, as they are common parents in a tree.

I am not completely clear on what the 'fen' argument represents... I guess it could represent a fully defined game state, which can be dealt with just like a ply.

This could be a starting point:

 class Node { constructor(ply, parent) { this.ply = ply; this.parent = parent; // Optional for this demo, but could be useful to walk the tree // starting at the root instead of a leaf: this.children = []; if (parent) parent.children.push(this); } } class Tree { constructor(initialLine, startPos) { this.lines = { [initialLine]: new Node(startPos, null) }; } line(line) { // Collect all nodes that belong to a line, bottom up. let arr = []; for (let node = this.lines[line]; node; node = node.parent) { arr.push(node); } return arr.reverse(); // Return them in forward (top-down) order } branch(line, fromLine, numPly) { this.lines[line] = this.line(fromLine)[numPly-1]; } moves(line, plies) { for (let ply of plies) { this.lines[line] = new Node(ply, this.lines[line]); } } ply(line, numPly) { return this.line(line)[numPly].ply } } let tree = new Tree('initial', 'fen'); tree.moves('initial', 'ab c def g'.split(' ')); tree.branch('line2', 'initial', 3); tree.moves('line2', 'c2 d2 e2'.split(' ')); console.log([ tree.ply('initial', 0), // fen tree.ply('initial', 3), // c tree.ply('initial', 5), // e tree.ply('line2', 0), // fen tree.ply('line2', 2), // b tree.ply('line2', 3), // c2 tree.ply('line2', 5) // e2 ]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM