Scotch Game Trainer

Details

Author:Mark
Rating:
Difficulty:Beginner
Date:16th January 2021
Description:A quick tutorial through the main lines of the Scotch Game and it's variations.

Code

//Please feel welcome to copy this code for your own creations.
let data = [
    "e4",
    "e5",
    "Nf3",
    "Nc6",
    "d4",
    "exd4",
    [
        {
            info: "The main line is 4.Nxd4",
            move: "Nxd4"
        },
        [
            [
                {
                    info: "The Classical Variation is 4...Bc5",
                    move: "Bc5"
                },
                [
                    {
                        move: "Nxc6",
                        info: "Option 1 is to play 5.Nxc6 here"
                    },
                    "Qf6",
                    "Qd2",
                    "dxc6",
                    "Nc3"
                ],
                [
                    {
                        move: "Be3",
                        info: "Option 2 is to play 5.Be3 here"
                    },
                    "Qf6",
                    "c3",
                    "Nge7",
                    "Bc4"
                ],
                [
                    {
                        move: "Nb3",
                        info: "Option 3 is to play 5.Nb3 here"
                    },
                    "Bb6",
                    "a4",
                    "a6",
                    "Nc3"
                ]
            ],
            [
                {
                    info: "The Schmidt Variation is 4...Nf6",
                    move: "Nf6"
                },
                [
                    {
                        move: "Nxc6",
                        info: "Option 1 is to play 5.Nxc6, the Mieses Variation"
                    },
                    "bxc6",
                    "e5",
                    "Qe7",
                    "Qe2",
                    "Nd5",
                    "c4"
                ],
                [
                    {
                        move: "Nc3",
                        info: "Option 2 is to play 5.Nc3, the Scotch Four Knights Game"
                    },
                    "Bb4",
                    "Nxc6",
                    "bxc6",
                    "Bd3",
                    "d5",
                    "exd5",
                    "cxd5",
                    "O-O",
                    "O-O",
                    "Bg5",
                    "c6"
                ]
            ],
            [
                {
                    info: "The Steinitz Variation is 4...Qh4",
                    move: "Qh4"
                },
                "Nc3",
                "Bb4",
                "Be2",
                "Qxe4",
                "Nb5",
                "Bxc3+",
                "bxc3",
                "Kd8",
                "O-O"
            ]
        ],
    ],
    [
        {
            info: "The Scotch Gambit is 4.Bc4",
            move: "Bc4"
        },
        [
            {
                info: "Option 1 is for black to transpose into the Two Knights Defense with 4...Nf6",
                move: "Nf6"
            }
        ],
        [
            {
                info: "Option 2 is for black to play 4...Bc5",
                move: "Bc5"
            },
            "c3",
            {
                info: "Black can play 5..Nf6, which transposes to a safe variation of the Giuoco Piano",
                move: "Nf6"
            },
        ],
        [
            "Bc5",
            "c3",
            {
                info: "Option 3 is for black to accept the gambit with 5...dxc3",
                move: "dxc3"
            },
            "Bxf7+",
            "Kxf7",
            "Qd5+"
        ],
    ],
];


let targetMove = "";
onPieceClicked(function (squareName) {
    if (targetMove == "") {
        return false;
    }

    if (squareName == sourceOfSan(targetMove)) {
        return true;
    }

    highlightSquareRed(squareName);
    return false;
});

onMoveAttempted(function (san) {
    if (san == targetMove) {
        targetMove = "";
        setTimeout(next, 50);
        return true;
    }

    return false;
});

onNextClicked(function () {
    showNextButton(false);
    next();
});

function nextDelayed() {
    setTimeout(next, 500);
}

var steps = [];

function treeToSteps(root, currentPath) {
    if (Array.isArray(root) == false) {
        console.error("root must be an array");
    }

    for (let child of root) {
        if (Array.isArray(child)) {
            //clone the currentPath
            treeToSteps(child, currentPath.slice());
        } else {
            currentPath.push(child);
        }
    }

    ///if we have come to the end of the array
    ///and it's an object
    ///then we treat it as a leaf node
    ///and build steps for it
    let last = root[root.length - 1];
    if (Array.isArray(last) == false) {
        if (steps.length > 0) {
            steps.push({
                info: "This concludes our analysis of this line",
                showNextButton: true
            });
            steps.push({
                reset: true
            });
        }

        steps.push.apply(steps, currentPath);
    }
}

treeToSteps(data, []);
console.log(steps);

function next() {
    if (steps.length == 0) {
        info("This completes our analysis of the Scotch Game");
        complete();
        return;
    }

    let step = steps.shift();
    let shouldMoveNext = true;

    if (typeof step == "string") {
        if (isWhitesTurn()) {
            targetMove = step;
            info("Play " + currentMoveNumber() + "." + step);
        } else {
            setTimeout(function () {
                performMove(step);
                nextDelayed();
            }, 500);
        }
        return;
    }

    if (isWhitesTurn()) {
        if (step.info != undefined) {
            info(step.info);
        } else if (step.move != undefined) {
            info("Play " + currentMoveNumber() + "." + step.move);
        }

        if (step.move != undefined) {
            targetMove = step.move;
            shouldMoveNext = false;
        }
    } else {
        if (step.info == undefined) {
            if (step.move != undefined) {
                setTimeout(function () {
                    performMove(step.move);
                    nextDelayed();
                }, 500);

                shouldMoveNext = false;
            }
        } else {
            info(step.info);

            if (step.move != null) {
                showNextButton(true);

                ///so if this pathway is repeated again
                ///then we probably don't want to have to click next again
                ///so we remove the info from the step
                ///the treeToSteps() function makes shallow copies of arrays
                ///so each object is repeated multiple times, and can be edited once
                step.info = undefined;

                steps.unshift({
                    move: step.move
                });
                shouldMoveNext = false;
            }
        }
    }

    if (step.showNextButton == true) {
        showNextButton(true);
        shouldMoveNext = false;
    }

    if (step.call != undefined) {
        step.call();
    }

    if (step.reset == true) {
        fromFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    }

    if (shouldMoveNext) {
        next();
    }
}

next();