King's Indian Defence Trainer

Details

Author:Mark
Rating:
Difficulty:Beginner
Date:2nd February 2021
Description:A trainer to help you learn and memorize all the variations of the King's Indian Defence opening.

Code

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

//fromFen("rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq - 0 1");
let root = [
    "d4", //1.
    "Nf6",
    "c4", //2.
    "g6",
    [
        "Nc3", //3.
        "Bg7",
        "e4", //4.
        "d6",
        [
            "Nf3", //5.
            "O-O",
            [
                "Be2", //6.
                {
                    info: "This is the classical variation"
                },
                [
                    "e5",
                    [
                        "O-O", //7.
                        [
                            "Nc6",
                            {
                                info: "This is the Main Line (aka the Mar del Plata Variation)"
                            },
                            "d5", //8.
                            "Ne7",
                            [
                                "b4", //9.
                                {
                                    info: "This is the Bayonet Attack"
                                }
                            ],
                            [
                                "Ne1", //9.
                            ],
                            [
                                "Nd2", //9.
                            ]
                        ],
                        [
                            "Nbd7",
                            {
                                info: "This is the Old Main Line"
                            },
                        ],
                        [
                            "exd4",
                            "Nxd4", //8.
                        ],
                        [
                            "Na6",
                            [
                                "dxe5", //8.
                                "dxe5",
                                "Qxd8", //9.
                                "Rxd8"
                            ],
                            [
                                "d5", //8.
                                "Nc5",
                                "Qc2", //9.
                                "a5",
                                {
                                    info: "This may transpose into the Petrosian Variation"
                                }
                            ],
                            [
                                "Bg5", //8.
                                "h6",
                                "Bh4", //9.
                                "Qe8",
                                "Bxf6", //10.
                                "Bxf6",
                                "c5", //11.
                            ]
                        ]
                    ],
                    [
                        "d5", //7.
                        {
                            info: "This is the Petrosian Variation"
                        },
                        [
                            "a5",
                            "Bg5", //8.
                        ],
                        [
                            "Na6"
                        ]
                    ],
                    [
                        "Be3", //7.
                        {
                            info: "This is the Gligoric System"
                        },
                        [
                            "Ng4",
                            "Bg5", //8.
                            "f6",
                            "Bh4", //9.
                            "Nc6",
                        ],
                        [
                            "Na6",
                            "O-O", //8.
                            {
                                info: "This transposes into the Modern Defense"
                            }
                        ],
                        [
                            "h6",
                            "O-O", //8.
                            "Ng4",
                            "Bc1", //9.
                            "Nc6",
                            "d5", //10.
                            "Ne7",
                            "Ne1", //11.
                            "f5",
                            "Bxg4", //12.
                            "fxg4",
                        ],
                        [
                            "exd4",
                            "Nxd4", //8.
                            "Re8",
                            "f3", //9.
                            "c6",
                            "Qd2", //10.
                            "d5",
                            "exd5", //11.
                            "cxd5",
                            "O-O", //12.
                            "Nc6",
                            "c5", //13.
                        ]
                    ],
                    [
                        "dxe5", //7.
                        {
                            info: "This is the Exchange Variation"
                        },
                        "dxe5",
                        "Qxd8", //8.
                        "Rxd8",
                    ]
                ],
                [
                    "Bg4",
                    "Be3", //7.
                ],
                [
                    "c5",
                    "O-O", //7.
                    "cxd4",
                    "Nxd4", //8.
                    "Nc6",
                    {
                        info: "this transposes into the Accelerated Dragon variation of the Sicilian Defence"
                    }
                ]
            ],
            [
                "Bg5", //6.
                {
                    info: "This is the Zinnowitz Variation"
                },
                [
                    "h6"
                ],
                [
                    "Nbd7"
                ]
            ]
        ],
        [
            "f5", //5.
            {
                info: "This is the Sämisch Variation"
            },
            "O-O",
            [
                "Bg5", //6.
                "c5",
                "d5", //7.
                "e6",
                {
                    info: "This transposes into the Modern Benoni"
                }
            ],
            [
                "Be3", //6.
                [
                    "e5",
                ],
                [
                    "c5",
                    {
                        info: "This is the Sämisch Gambit"
                    },
                    [
                        "dxc5", //7.
                        "dxc5",
                        [
                            "Qxd8", //8.
                            "Rxd8",
                            "Bxc5", //9.
                            "Nc6",
    
                        ],
                        [
                            "e5", //8.
                            "Nfd7",
                            "f4", //9.
                            "f6",
                            "exf6", //10.
                        ]
                    ],
                    [
                        "Nge2", //7.
                    ]
                ],
                [
                    "Nc6",
                    {
                        info: "This is the Panno Variation of the Sämisch"
                    },
                    "Nge2", //7.
                    "a6",
                    "Qd2", //8.
                    "Rb8",
                ]
            ]
        ],
        [
            "Be2", //5.
            {
                info: "This is the Averbakh Variation"
            },
            "O-O",
            "Bg5", //6.
            [
                "c5"
            ],
            [
                "Nbd7"
            ],
            [
                "Na6"
            ]
        ],
        [
            "f4", //5.
            {
                info: "This is the Four Pawns Attack"
            },
            "O-O",
            "Nf3", //6.
            [
                "c5",
                "d5", //7.
                "e6",
                "Be2", //8.
                "exd5",
                "cxd5", //9.
                [
                    "Bg4"
                ],
                [
                    "Re8"
                ],
                [
                    "b5"
                ]
            ],
            [
                "Na6",
                {
                    info: "This is the Modern Variation"
                }
            ]
        ]
    ],
    [
        "Nf3", //3.
        {
            info: "This is the Fianchetto Variation"
        },
        "Bg7",
        "g3", //4.
        "O-O",
        "Bg2", //5.
        "d6",
        "O-O", //6.
        [
            "Nbd7",
            "Nc3", //7.
            "e5",
            "e4", //8.
            [
                "exd4",
                {
                    info: "This is the Gallagher Variation of the Fianchetto Variation"
                },
                "Nxd4", //9.
                "Re8",
                "h3", //10.
                "a6",
            ],
            [
                "c6"
            ],
            [
                "a6"
            ]
        ],
        [
            "Nc6",
            "Nc3", //7.
            "a6",
            "d5", //8.
            "Na5",
            "Nd2", //9.
            "c5",
            "Qc2", //10.
            "Rb8",
            "b3", //11.
            "b5",
            "Bb2", //12.
            "bxc4",
            "bxc4", //13.
            "Bh6",
            "f4", //14.
            "e5",
        ]
    ]
];

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();