UNPKG

analyze-sgf

Version:

Analyze SGF file by KataGo Parallel Analysis Engine to produce Reviewed SGF file

119 lines (100 loc) 3.81 kB
/* eslint max-lines-per-function: ["error", 100] */ const fs = require('fs'); const assert = require('assert'); const yaml = require('js-yaml'); const sgfconv = require('../src/sgfconv'); const GameTree = require('../src/gametree'); const yamlpath = require.resolve('../src/analyze-sgf.yml'); const opts = yaml.load(fs.readFileSync(yamlpath)); opts.sgf.boardYSize = opts.analysis.boardYSize; const sgfopts = opts.sgf; // Removes line feeds and comments. function strip(sgf) { return sgf .replace(/\r\n/g, '') .replace(/\n/g, '') .replace(/\\\]/g, '@$$yy$$@') .replace(/\bC\[[^\]]*\]/g, '') .replace(/@$$yy$$@/g, '\\]'); } // Compares expected SGF except comments to the SGF generated by GameTree and // Analysis JSON. function compareButComments(json, expected) { const data = fs.readFileSync(json).toString(); const index = data.indexOf('\n'); const sgf = sgfconv.correctSGFDialects(data.substring(0, index)); const responses = data.substring(index + 1); const gametree = new GameTree(sgf, responses, sgfopts); const rsgf = strip(gametree.getSGF()); const esgf = strip(fs.readFileSync(expected).toString()); assert.equal(esgf, rsgf); } // Compares expected SGF to the SGF generated by Analysis JSON. function compare(json, expected) { const data = fs.readFileSync(json).toString(); const index = data.indexOf('\n'); const sgf = sgfconv.correctSGFDialects(data.substring(0, index)); const responses = data.substring(index + 1); const gametree = new GameTree(sgf, responses, sgfopts); const rsgf = gametree.getSGF(); assert.equal(fs.readFileSync(expected).toString(), rsgf); } describe('GameTree', () => { it('should remove the comment of root node, and add move comment.', () => { const compareButLines = (x, y) => assert.equal(x.replace(/\n/g, ''), y.replace(/\n/g, '')); const gametree = new GameTree('(PL[]C[12\n34];B[aa];W[bb])', '', opts); compareButLines( gametree.getSGF(), '(;PL[]CA[UTF-8];B[aa]C[Move 1];W[bb]C[Move 2])', ); }); it('should be expected values for "t-sabaki-1-default.sgf".', () => { sgfopts.maxVariationsForEachMove = 10; sgfopts.maxWinrateDropForGoodMove = 2; sgfopts.minWinrateDropForBadMove = 5; sgfopts.minWinrateDropForBadHotSpot = 20; sgfopts.minWinrateDropForVariations = 5; sgfopts.showVariationsAfterLastMove = false; sgfopts.analyzeTurns = undefined; compareButComments( 'test/examples/t-sabaki-1.json', 'test/examples/t-sabaki-1-default.sgf', ); }); it('should add passing move for "t-sabaki-1-lastmove.sgf".', () => { sgfopts.showVariationsAfterLastMove = true; sgfopts.analyzeTurns = undefined; compareButComments( 'test/examples/t-sabaki-1.json', 'test/examples/t-sabaki-1-lastmove.sgf', ); }); it('should add passing move and all the variations.', () => { sgfopts.showVariationsAfterLastMove = true; sgfopts.analyzeTurns = [0, 1, 2, 3, 4, 5]; compareButComments( 'test/examples/t-sabaki-1.json', 'test/examples/t-sabaki-1-turns-lastmove.sgf', ); }); it('should add all the variations.', () => { sgfopts.showVariationsAfterLastMove = false; compareButComments( 'test/examples/t-sabaki-1.json', 'test/examples/t-sabaki-1-turns.sgf', ); }); it('should be same for each comment of "t-sabaki-2.sgf".', () => { sgfopts.minWinrateDropForVariations = -100; sgfopts.showBadVariations = true; sgfopts.maxVariationsForEachMove = 20; sgfopts.showVariationsAfterLastMove = true; sgfopts.analyzeTurns = [0, 1, 2, 3, 4]; // Be careful. Easy to fail with the changes of comments formats. compare( 'test/examples/t-sabaki-2.json', 'test/examples/t-sabaki-2-analyzed.sgf', ); }); });