Skip to content

Instantly share code, notes, and snippets.

@psygo
Created November 26, 2023 00:30
Show Gist options
  • Save psygo/f29b3bf6b3cec5b89be6e82126223600 to your computer and use it in GitHub Desktop.
Save psygo/f29b3bf6b3cec5b89be6e82126223600 to your computer and use it in GitHub Desktop.
Custom SGF Parsing
export const sgf1 =
"(;GM[1]FF[4]CA[UTF-8]AP[Sabaki:0.52.2]KM[6.5]SZ[19]DT[2023-11-16]AB[qc][pc][oc]AW[od][pd][qd]C[Hello there]PB[Player 1]BR[1p]PW[Philippe Fanaro]WR[2d]GN[Game Name]EV[Event 1]GC[This is an info comment]RE[B+1.5];B[pg]C[This is the second comment];W[qi](;PL[B]AB[qk][ok];B[pm](;W[qo];B[dp];W[dl];B[dn])(;W[rm];B[ro]))(;B[dd];W[df]))";
export const sgf7 =
"(;GM[1]FF[4]CA[UTF-8]AP[Sabaki:0.52.2]KM[6.5]SZ[19]DT[2023-11-25];B[pd](;W[md])(;W[pf]))(;GM[1]FF[4]CA[UTF-8]AP[Sabaki:0.52.2]KM[6.5]SZ[19]DT[2023-11-25];B[qd](;W[oc])(;W[pd]))";
export type BranchSegments = {
id?: number;
parentId?: number | null;
data: string;
children: BranchSegments[];
};
export function parseStringToTrees(s: string) {
return parseBranchSegmentsToTree(
parseStackToBranchSegments(parseStringToStack(s))
);
}
function recursivelyDismantleBranch(
data: string,
pastChildren: BranchSegments[]
): BranchSegments {
const possibleMoves = data
.split(";")
.filter((pb) => pb !== "");
const firstMove = possibleMoves.first();
const otherMoves = possibleMoves.slice(1).join(";");
return {
data: firstMove,
children:
possibleMoves.length > 1
? [
recursivelyDismantleBranch(
otherMoves,
pastChildren
),
]
: pastChildren.map((c) =>
recursivelyDismantleBranch(c.data, c.children)
),
};
}
export function parseBranchSegmentsToTree(
bs: BranchSegments[]
) {
const newBs: BranchSegments[] = [];
for (const b of bs) {
newBs.push(
recursivelyDismantleBranch(b.data, b.children)
);
}
return newBs;
}
export function parseStackToBranchSegments(
stack: string[]
) {
const trees: BranchSegments[] = [];
const treeTempArray: BranchSegments[] = [];
let currentParentId: number | null = null;
for (let i = 0; i < stack.length; i++) {
const s = stack[i];
if (s === "(") {
const newId = treeTempArray.length;
const data = stack[i + 1];
const newTree: BranchSegments = {
id: newId,
parentId: currentParentId,
data,
children: [],
};
if (currentParentId === null) {
trees.push(newTree);
treeTempArray.push(newTree);
currentParentId = newId;
} else {
treeTempArray[currentParentId].children.push(
newTree
);
treeTempArray.push(newTree);
currentParentId = newId;
}
} else if (s === ")") {
const currentParent = treeTempArray
.filter((t) => t.id === currentParentId)
.first();
const grandParentId = currentParent.parentId!;
currentParentId = grandParentId;
}
}
return trees;
}
export function parseStringToStack(sgf: Sgf) {
const stack: string[] = [];
let currentString = "";
for (let i = 0; i < sgf.length; i++) {
const char = sgf[i];
if (char === "(" || char === ")") {
if (currentString) stack.push(currentString);
currentString = "";
stack.push(char);
} else {
currentString += char;
}
}
return stack;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment