Queen's Gambit Trainer

Details

Author:Mark
Rating:
Difficulty:Beginner
Date:2nd February 2021
Description:A trainer to help you learn and memorize 86 variations of the Queen's Gambit Opening.

Code

//Please feel welcome to copy this code for your own creations.

//fromFen("rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq - 0 1");
let root = [
    "d4",
    "d5",
    "c4",
    [
        "e6",
        {
            info: "This is Queen's Gambit Declined, Orthodox Line"
        },
        "Nc3", //3.
        [
            "Nf6",
            [
                "Bg5", //4.
                [
                    "Be7",
                    "Nf3", //5.
                    [
                        "h6",
                        [
                            "Bh4", //6.
                            {
                                info: "This is the Tartakower Defense or Tartakower–Makogonov–Bondarevsky System (TMB system)",
                            },
                            "O-O",
                            "e3",
                            "b6"
                        ],
                        [
                            "Bxf6", //6.
                            {
                                info: "This is the Anti-Tartakower–Makogonov–Bondarevsky (Anti-TMB)"
                            },
                            "Bxf6"
                        ]
                    ],
                    [
                        "O-O",
                        "e3", //6.
                        [
                            "h6",
                            {
                                info: "This is the Lasker Defense"
                            },
                            "Bh4",
                            "Ne4",
                            "Bxe7",
                            "Qxe7"
                        ],
                        [
                            "Nbd7",
                            {
                                info: "This is the Orthodox Defense"
                            },
                            "Rc1",
                            "c6"
                        ]
                    ]
                ],
                [
                    "Nbd7",
                    {
                        info: "This is the Cambridge Springs Defense"
                    },
                    "e3", //5.
                    "c6",
                    "Nf3", //6.
                    "Qa5"
                ]
            ],
            [
                "cxd5", //4.
                {
                    info: "This is the Exchange Variation"
                },
                "exd5",
                "Bg5", //5.
                "c6",
                "Qc2" //6.
            ],
            [
                "Nf3", //4.
                [
                    "Bb4",
                    {
                        info: "This is the Ragozin Variation"
                    },
                    "Bg5", //5.
                    {
                        info: "This is the Vienna Variation"
                    },
                    "dxc4",
                    "e4", //6.
                ],
                [
                    "Be7",
                    {
                        info: "This is the Harrwitz Attack"
                    },
                    "Bf4", //5.
                    "O-O",
                    "e3", //6.
                    "c5",
                    "dxc5", //7.
                    "Bxc5"
                ]
            ]
        ],
        [
            "c5",
            {
                info: "This is the Tarrasch Defense"
            }
        ],
        [
            "Be7",
            {
                info: "This is the Alatortsev Variation"
            },
            [
                "Nf3", //4.
                "Nf6",
                "Bg5", //5.
            ],
            [
                "cxd5", //4.
                "exd5",
                "Bf4", //5.
                "c6",
                [
                    "e3", //6.
                    "Bf5",
                    "g4" //7.
                ],
                [
                    "Qc2", //6.
                ]
            ]
        ],
        [
            "c6",
            [
                "Nf3", //4.
                [
                    "Nf6",
                    {
                        info: "This is the Semi-Slav Defense"
                    }
                ],
                [
                    "dxc4",
                    {
                        info: "This is the Noteboom Variation, aka the Abrahams Variation"
                    }
                ]
            ],
            [
                "e4", //4.
                "dxe4",
                "Nxe4", //5.
                "Bb4+",
                "Bd2", //6.
                "Qxd4",
                "Bxb4", //7.
                "Qxe4+",
                "Be2" //8.
            ],
        ]
    ],
    [
        "dxc4",
        {
            info: "This is Queen's Gambit Accepted"
        },
        [
            "Nf3", //3.
            [
                "Nf6",
                [
                    "e3", //4.
                    {
                        info: "This is the main line"
                    },
                    [
                        "e6",
                        "Bxc4", //5.
                        "c5",
                        [
                            "O-O", //6.
                            [
                                "a6",
                                [
                                    "Bb3", //7.
                                ],
                                [
                                    "a4"
                                ]
                            ],
                            [
                                "cxd4",
                                {
                                    info: "This is called the Steinitz Variation"
                                },
                            ]
                        ],
                        [
                            "Qe2", //6.
                            {
                                info: "This is called the Furman Variation"
                            }
                        ]
                    ],
                    [
                        "Bg4",
                        "Bxc4", //5.
                        "e6"
                    ]
                ],
                [
                    "Qa4+", //4.
                    {
                        info: "This leads to the Mannheim Variation"
                    },
                    "Nc6"
                ],
                [
                    "Nc3", //4.
                    {
                        info: "This leads to the Two Knights Variation"
                    },
                    [
                        "a6",
                        "e4", //5.
                        "b5"
                    ],
                    [
                        "Nc6",
                        {
                            info: "This will likely transpose to the Chigorin Defense"
                        },
                    ],
                    [
                        "e6",
                        {
                            info: "This will likely transpose to the QGD Vienna Variation"
                        },
                    ],
                    [
                        "c6",
                        {
                            info: "This will likely transpose to the Slav Defense"
                        },
                    ]
                ]
            ],
            [
                "a6",
                {
                    info: "This is the Alekhine Variation"
                },
                "e3", //4.
                "Nf6"
            ]
        ],
        [
            "e4", //3.
            {
                info: "This is called the Central Variation"
            },
            [
                "e5",
            ],
            [
                "Nc6"
            ],
            [
                "Nf6",
                "e5"
            ],
            [
                "c5"
            ]
        ],
        [
            "e3", //3.
            [
                "e5",
                "Bxc4", //4.
                "exd4",
                "exd4", //5.
            ],
            [
                "e6"
            ],
            [
                "Be6",
                "Ne2" //4.
            ]
        ],
        [
            "Nc3", //3.
            [
                "e5"
            ],
            [
                "Nf6"
            ],
            [
                "a6"
            ],
            [
                "Nc6",
                {
                    info: "This leads to the Chigorin Defense"
                }
            ]
        ],
        [
            "Qa4+", //3.
            "Nc6",
            "Nf3"
        ],
    ],
    [
        "c6",
        {
            info: "This is the Slav Defense"
        },
        [
            "Nf3", //3.
            "Nf6",
            [
                "Nc3", //4.
                [
                    "e6",
                    {
                        info: "This is the Semi-Slav"
                    }
                ],
                [
                    "dxc4",
                    [
                        "a4", //5.
                        [
                            "Bf5",
                            {
                                info: "This is the main line (aka the Czech Variation)"
                            },
                            [
                                "Nh4", //6.
                                {
                                    info: "This is the bled attack"
                                }
                            ],
                            [
                                "e3", //6.
                                {
                                    info: "This is the Dutch Variation"
                                },
                                [
                                    "e6",
                                    "Bxc4", //7.
                                    "Bb4",
                                    "O-O", //8.
                                    "O-O",
                                ],
                                [
                                    "Na6",
                                    {
                                        info: "This is the Dutch, Lasker Variation"
                                    }
                                ]
                            ],
                            [
                                "Ne5", //6.
                                {
                                    info: "This is the Krause Attack"
                                },
                            ]
                        ],
                        [
                            "Bg4",
                            {
                                info: "This is the Steiner Variation, (aka the Bronstein Variation)"
                            },
                            "Ne5", //6.
                            "Bh5",
                        ],
                        [
                            "Na6",
                            {
                                info: "This is the Smyslov Variation"
                            },
                            "e4", //6.
                            "Bg4",
                            "Bxc4", //7.
                            "e6",
                            "O-O", //8.
                            "Nb4",
                        ],
                        [
                            "e6",
                            {
                                info: "This is the Soultanbéieff Variation"
                            }
                        ]
                    ],
                    [
                        "e4", //5.
                        {
                            info: "This is the Slav Geller Gambit"
                        },
                        "b5",
                        "e5", //6.
                        "Nd5",
                        "a4", //7.
                        "e6"
                    ],
                    [
                        "e3", //5.
                        {
                            info: "This is the Alekhine Variation"
                        },
                        "b5",
                        "a4", //6.
                        "b4",
                        [
                            "Na2", //7.
                            "e6",
                            "Bxc4" //8.
                        ],
                        [
                            "Nb1", //7.
                            "Ba6",
                            "Nbd2", //8.
                            "c3",
                            "bxc3", //9.
                            "Bxf1",
                            "Nxf1", //10.
                            "bxc3"
                        ]
                    ]
                ],
                [
                    "a6",
                    {
                        info: "This is the a6 (Chebanenko) Slav"
                    },
                    "c5", //5.
                    "Bf5",
                    "Bf4", //6.
                    "Nbd7",
                    "h3", //7.
                    "e6",
                    "e3" //8.
                ]
            ],
            [
                "Qc2", //4.
                "dxc4",
                "Qxc4", //5.
                [
                    "Bf5"
                ],
                [
                    "Bg4"
                ]
            ],
            [
                "e3", //4.
                {
                    info: "This is the Slow Slav"
                },
                [
                    "Bf5",
                    [
                        "Nc3", //5.
                        "e6",
                        "Nh4" //6.
                    ],
                    [
                        "cxd5", //5.
                        "cxd5",
                        "Qb3", //6.
                        "Qc7"
                    ]
                ],
                [
                    "Bg4"
                ]
            ]
        ],
        [
            "e3", //3.
            [
                "Nf6",
                "Nc3", //4.
            ],
            [
                "Bf5"
            ]
        ],
        [
            "cxd5", //3.
            {
                info: "This is called the Exchange Slav"
            },
            "cxd5",
            "Nf3", //4.
            "Nf6",
            "Nc3", //5.
            "Nc6",
            "Bf4", //6.
            "Bf5",
        ],
        [
            "Nc3", //3.
            [
                "e5",
                {
                    info: "This is called the Winawer Countergambit"
                }
            ],
            [
                "Nf6",
                [
                    "Nf3", //4.
                    {
                        info: "This transposes to the mainline"
                    },
                ],
                [
                    "e3", //4.
                    "Bf5",
                    "cxd5", //5.
                    "cxd5",
                    "Qb3", //6.
                    "Nc6",
                    "Qxb7", //7.
                    "Bd7"
                ]
            ],
            [
                "dxc4",
                {
                    info: "This is the Argentinian Defense"
                }
            ]
        ]
    ],
    [
        "e5",
        {
            info: "This is the Albin Countergambit"
        },
        "dxe5", //3.
        "d4",
        [
            "Nf3", //4.
            "Nc6",
            "g3", //5.
            "Be6",
            "Nbd2", //6.
            "Qd7",
            "Bg2", //7.
            "O-O-O",
            "O-O", //8.
            "Bh3",
        ],
        [
            "e4",
            {
                info: "This is the Spassky Variation"
            },
            "Bb4+",
            "Bd2"
        ]
    ],
    [
        "Nc6",
        {
            info: "This is the Chigorin Defense"
        },
        [
            "Nc3", //3.
            [
                "Nf6",
                "cxd5", //4.
                "Nxd5",
                "e4", //5.
                "Nxc3",
                "bxc3", //6.
                "e5",
                [
                    "d5", //7.
                    "Nb8",
                ],
                [
                    "Nf3", //7.
                    "exd4"
                ]
            ],
            [
                "dxc4",
                "Nf3", //4.
                "Nf6",
                "e4", //5.
                "Bg4",
                "Be3", //6.
                "e6",
                "Bxc4", //7.
                "Bb4",
            ]
        ],
        [
            "Nf3", //3.
            [
                "Bg4",
                "cxd5", //4.
                "Bxf3",
                [
                    "gxf3", //5.
                    "Qxd5",
                    "e3", //6.
                    [
                        "e5",
                        "Nc3", //7.
                        "Bb4"
                    ],
                    [
                        "e6",
                        "Nc3", //7.
                        "Qh5"
                    ]
                ],
                [
                    "dxc6", //5.
                    "Bxc6",
                    "Nc3", //6.
                    [
                        "Nf6"
                    ],
                    [
                        "e6"
                    ]
                ]
            ],
            [
                "e6"
            ]
        ],
        [
            "cxd5", //3.
            "Qxd5",
            [
                "e3", //4.
                "e5",
                "Nc3", //5.
                "Bb4",
                "Bd2", //6.
                "Bxc3",
                [
                    "bxc3", //7.
                    [
                        "Nf6"
                    ],
                    [
                        "Qd6"
                    ]
                ],
                [
                    "Bxc3", //7.
                    "exd4",
                    "Ne2", //8.
                    [
                        "Nf6",
                        "Nxd4", //9.
                        "O-O",
                    ],
                    [
                        "Bg4"
                    ]
                ]
            ],
            [
                "Nf3"
            ]
        ]
    ],
    [
        "Bf5",
        {
            info: "This is the Baltic Defense"
        },
        [
            "Nf3", //3.
            "e6",
            [
                "Qb3", //4.
                "Nc6"
            ],
            [
                "e3", //4.
                "Nf6",
                "Qb3", //5.
                "Nc6"
            ],
            [
                "Nc3", //4.
                "Nf6",
                "Qb3", //5.
                "Nc6"
            ],
            [
                "cxd5", //4.
                "exd5",
                "Qb3", //5.
                "Nc6"
            ]
        ],
        [
            "cxd5", //3.
            "Bxb1",
            "Qa4+", //4.
            "Qd7",
            "Qxd7+", //5.
            "Nxd7",
            "Rxb1", //6.
            "Ngf6",
            "Nf3", //7.
        ],
        [
            "Qb3", //3.
            "e5",
            "Qxb7", //4.
            "Nd7",
            "Nf3", //5.
            "Rb8",
            "Qxd5", //6.
            "Bb4+",
            "Nfd2", //7.
        ]
    ],
    [
        "c5",
        {
            info: "This is the Symmetrical Defense (aka Austrian Defense)"
        },
        "cxd5", //3.
        "Nf6",
        [
            "Nf3", //4.
            "cxd4",
            "Nxd4", //5.
            "Nxd5",
            "e4", //6.
            "Nc7"
        ],
        [
            "e4", //4.
            "Nxe4",
            "dxc5", //5.
            "Nxc5",
            "Nc3", //6.
            "e6"
        ]
    ],
];

let targetMove = "";
onPieceClicked(function (squareName) {
    if (typeof targetMove == "string") {
        if (squareName == sourceOfSan(targetMove)) {
            return true;
        }
    } else if (Array.isArray(targetMove)) {
        for (let temp of targetMove) {
            if (squareName == sourceOfSan(temp)) {
                return true;
            }
        }
    } else {
        throw new Error();
    }
    if (targetMove == "") {
        return false;
    }

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

    highlightSquareRed(squareName);
    return false;
});

onMoveAttempted(function (san) {
    if (typeof targetMove == "string") {
        if (san == targetMove) {
            current.index++;
            setTimeout(next, 50);
            return true;
        }
    } else if (Array.isArray(targetMove)) {
        for (let temp of targetMove) {
            if (san == temp) {
                for (let i = current.index; i < current.length; i++) {
                    if (current[i][0] == san) {
                        current[i].parent = current;
                        current = current[i];
                        current.index = 1;
                        break;
                    }
                }

                setTimeout(next, 50);
                return true;
            }
        }
    } else {
        throw new Error();
    }

    return false;
});

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

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

function onUndoClicked() {
    undo();

    if (current.index > 0) {
        current.index--;

        if (current.index > 0 && current[current.index].info != undefined) {
            current.index--;
        }
    }

    if (current.index == 0) {
        if (current.parent != undefined) {
            current = current.parent;
        } else {
            //showButton("undo", false);
        }
    }

    next();
}

let current = root;
current.index = 0;

let preInfo = "";

createButton("Undo", onUndoClicked);
showButton("Undo", false);
let undoButtonVisible = false;

function next() {
    let showUndoButton = current != root || current.index > 0;
    if (undoButtonVisible != showUndoButton) {
        showButton("Undo", showUndoButton);
        undoButtonVisible = showUndoButton;
    }

    if (preInfo != "") {
        preInfo += "<br><br>";
    }

    if (current.index >= current.length) {
        info(preInfo + "End of the line");
        preInfo = "";
        return;
    }

    let step = current[current.index];

    if (typeof step == "string") {
        if (isWhitesTurn()) {
            info(preInfo + "White to play <b>" + currentMoveNumber() + "." + step + "</b>");
        } else {
            info(preInfo + "Black to play <b>" + currentMoveNumber() + "..." + step + "</b>");
        }

        targetMove = step;
        preInfo = "";
    } else if (Array.isArray(step)) {
        ///assume that the rest of the steps in the current array are also arrays
        //i.e. different options from this point

        let possibleSteps = [];
        for (let i = current.index; i < current.length; i++) {
            //assume that the first step in every array is a string
            //otherwise it would be seperated out into an array at the previous level
            possibleSteps.push(current[i][0]);
        }

        targetMove = possibleSteps;

        if (isWhitesTurn()) {
            possibleSteps = possibleSteps.map(x => "<li><b>" + currentMoveNumber() + "." + x + "</b></li>");
            info(preInfo + "White can play: <ul>" + possibleSteps.join("") + "</ul>");
        } else {
            possibleSteps = possibleSteps.map(x => "<li><b>" + currentMoveNumber() + "..." + x + "</b></li>");
            info(preInfo + "Black can play: <ul>" + possibleSteps.join("") + "</ul>");
        }

        preInfo = "";
    } else {
        if (step.info != undefined) {
            preInfo = step.info;
            current.index++;
            next();
        }
    }
}

next();