makePgn method
Make a PGN String from PgnGame.
Implementation
String makePgn() {
final builder = StringBuffer();
final token = StringBuffer();
if (headers.isNotEmpty) {
headers.forEach((key, value) {
builder.writeln('[$key "${_escapeHeader(value)}"]');
});
builder.write('\n');
}
for (final comment in comments) {
builder.writeln('{ ${_safeComment(comment)} }');
}
final fen = headers['FEN'];
final initialPly = fen != null ? _getPlyFromSetup(fen) : 0;
final List<_PgnFrame> stack = [];
if (moves.children.isNotEmpty) {
final variations = moves.children.iterator;
variations.moveNext();
stack.add(_PgnFrame(
state: _PgnState.pre,
ply: initialPly,
node: variations.current,
sidelines: variations,
startsVariation: false,
inVariation: false));
}
bool forceMoveNumber = true;
while (stack.isNotEmpty) {
final frame = stack[stack.length - 1];
if (frame.inVariation) {
token.write(') ');
frame.inVariation = false;
forceMoveNumber = true;
}
switch (frame.state) {
case _PgnState.pre:
{
if (frame.node.data.startingComments != null) {
for (final comment in frame.node.data.startingComments!) {
token.write('{ ${_safeComment(comment)} } ');
}
forceMoveNumber = true;
}
if (forceMoveNumber || frame.ply.isEven) {
token.write(
'${(frame.ply / 2).floor() + 1}${frame.ply.isOdd ? "..." : "."} ');
forceMoveNumber = false;
}
token.write('${frame.node.data.san} ');
if (frame.node.data.nags != null) {
for (final nag in frame.node.data.nags!) {
token.write('\$$nag ');
}
forceMoveNumber = true;
}
if (frame.node.data.comments != null) {
for (final comment in frame.node.data.comments!) {
token.write('{ ${_safeComment(comment)} } ');
}
}
frame.state = _PgnState.sidelines;
continue;
}
case _PgnState.sidelines:
{
final child = frame.sidelines.moveNext();
if (child) {
token.write('( ');
forceMoveNumber = true;
stack.add(_PgnFrame(
state: _PgnState.pre,
ply: frame.ply,
node: frame.sidelines.current,
sidelines:
<PgnChildNode<PgnNodeData>>[].iterator, // empty iterator
startsVariation: true,
inVariation: false));
frame.inVariation = true;
} else {
if (frame.node.children.isNotEmpty) {
final variations = frame.node.children.iterator;
variations.moveNext();
stack.add(_PgnFrame(
state: _PgnState.pre,
ply: frame.ply + 1,
node: variations.current,
sidelines: variations,
startsVariation: false,
inVariation: false));
}
frame.state = _PgnState.end;
}
break;
}
case _PgnState.end:
{
stack.removeLast();
}
}
}
token.write(Outcome.toPgnString(Outcome.fromPgn(headers['Result'])));
builder.writeln(token.toString());
return builder.toString();
}