demin-dmitriy / PlayDots SGF Downloader

// ==UserScript==
// @name         PlayDots SGF Downloader
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Загрузка партий в приложении "спортивные точки" в формате SGF
// @author       Demin Dmitriy
// @match        http*://game.playdots.ru/*
// @grant        GM_registerMenuCommand
// ==/UserScript==
/* jshint -W097 */
'use strict';

function assert(condition, message) {
    if (!condition) {
        throw message || "Assertion failed";
    }
}

function create_sfg(width, height, points) {
    function int_to_char(value) {
        var table = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return table.charAt(value);
    }
    
    function prop(name, value) {
        return name + "[" + value + "]";
    }
    
    function move(color, x, y) {
        assert(color == "B" || color == "W");
        return prop(color, int_to_char(x) + int_to_char(y));
    }
    
    function side_to_color(side) {
        if (side == "left") return "B";
        if (side == "right") return "W";
        assert(false);
    }
    
    function node(props) {
        return ";" + props;
    }
    
    function tree(nodes) {
        return "(" + nodes + ")";
    }

    var firstSide = 'B';
    var game =
        [ prop('GM', '40')                 // Dots game
        , prop('FF', '4')                  // sfg version
        , prop('CA', 'UTF-8')              // Encoding
        , prop('SZ', width + ':' + height) // Field size
        , prop('RU', 'russian')            // Russian ruleset
        , prop('PB', 'Первый игрок')
        , prop('PW', 'Второй игрок')
        ].join('');
    var moves = points.map(function(point) { return move(side_to_color(point.side), point.x, point.y); });
    var nodes = [game].concat(moves);
    return tree(nodes.map(node).join(""));
}

var save_data = (function() {
    var a = document.createElement("a");
    return function (data, fileName) {
        var blob = new Blob([data], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

GM_registerMenuCommand('Save game as SGF', function() {
    var practicePage = app.pages.practice;
    var points = practicePage.points;
    var height = practicePage.canvasStepHeight;
    var width = practicePage.canvasStepWidth;
    var id = practicePage.gameId;
    var sfg = create_sfg(width, height, points);
    save_data(sfg, "game_" + id + ".sgf");
}, 'r');