Benoni Defense 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 Benoni Defense and Benko Gambit.

Code

//Please feel welcome to copy this code for your own creations.
//fromFen("rnbqkb1r/pp1ppppp/5n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq - 0 1");

let root = [
    "d4", //1.
    "Nf6",
    "c4", //2.
    "c5",
    "d5", //3.
    {
        "info": "This is the Benoni Defense"
    },
    [
        "b5",
        {
            "info": "This is the Benko Gambit"
        },
        "cxb5",
        "a6",
        {
            "info": "This is the Benko Gambit (Half-Accepted)"
        },
        [
            "Nc3",
            {
                "info": "This is the Benko Gambit (Half-Accepted) Zaitsev System"
            },
            "axb5",
            "e4",
            "b4",
            "Nb5",
            "d6",
            "Bc4",
            {
                "info": "This is the Benko Gambit (Half-Accepted) Nescafé Frappe Attack"
            }
        ],
        [
            "bxa6",
            {
                "info": "This is the Benko Gambit Accepted"
            },
            "Bxa6",
            "Nc3",
            "d6",
            [
                "Nf3",
                "g6",
                "g3",
                {
                    "info": "This is the Benko Gambit: Accepted Fianchetto Variation"
                }
            ],
            [
                "e4",
                {
                    "info": "This is the Benko Gambit Yugoslav"
                },
                "Bxf1",
                "Kxf1",
                "g6",
                "g3",
                "Bg7",
                "Kg2",
                "O-O",
                "Nf3",
                {
                    "info": "This is the Benko Gambit Yugoslav King Walk Variation"
                }
            ]
        ]
    ],
    [
        "e6",
        {
            "info": "This is the Modern Benoni"
        },
        "Nc3",
        "exd5",
        "cxd5",
        [
            "Bd6",
            {
                "info": "This is the Snake Benoni"
            }
        ],
        [
            "d6",
            [
                "Nf3",
                [
                    "Be7",
                    {
                        "info": "This is the Modern Benoni Kurz"
                    }
                ],
                [
                    "g6",
                    {
                        "info": "This is the Modern Benoni Knight's Tour Variation"
                    },
                    [
                        "g3",
                        {
                            "info": "This is the Modern Benoni Knight's Tour Fianchetto Variation"
                        },
                        "Bg7",
                        "Bg2",
                        "O-O",
                        "O-O",
                        "a6",
                        "a4",
                        "Nbd7",
                        {
                            "info": "This is the Modern Benoni Fianchetto Variation Hastings Defense"
                        },
                        "Nd2",
                        "Re8"
                    ],
                    [
                        "Nd2",
                        {
                            "info": "This is the Modern Benoni Knight's Tour Nimzovich Variation"
                        }
                    ],
                    [
                        "Bd2",
                        {
                            "info": "This is the Modern Benoni Knight's Tour Penrose Attack"
                        }
                    ],
                    [
                        "Bg5",
                        {
                            "info": "This is the Modern Benoni Uhlmann Knight's Tour"
                        }
                    ]
                ]
            ],
            [
                "e4",
                {
                    "info": "This is the Modern Benoni King's Pawn Line"
                },
                "g6",
                [
                    "f4",
                    {
                        "info": "This is the Modern Benoni Pawn Storm Variation"
                    },
                    "Bg7",
                    [
                        "e5",
                        {
                            "info": "This is the Modern Benoni Pawn Storm Mikenas Variation"
                        }
                    ],
                    [
                        "Bb5+",
                        {
                            "info": "This is the Modern Benoni Pawn Storm Taimanov Variation"
                        }
                    ],
                    [
                        "Nf3",
                        "O-O",
                        {
                            "info": "This is the Modern Benoni: Pawn Storm Four Pawns Attack"
                        },
                        "Be2",
                        "Re8"
                    ]
                ],
                [
                    "Nf3",
                    {
                        "info": "This is the Modern Benoni Classical Variation"
                    },
                    "Bg7",
                    [
                        "Bg5",
                    ],
                    [
                        "Be2",
                        "O-O",
                        "O-O",
                        [
                            "a6",
                            "a4",
                            "Bg4",
                            {
                                "info": "This is the Modern Benoni Classical Argentine Counter-attack"
                            }
                        ],
                        [
                            "Re8",
                            {
                                "info": "This is the Modern Benoni: Classical Czerniak Defense"
                            },
                            "Nd2",
                            "Na6",
                            "f3"
                        ]
                    ]
                ]
            ]
        ]
    ],
    [
        "Ne4",
        {
            "info": "This is the Vulture Defense"
        }
    ],
    [
        "d6",
        {
            "info": "This is the Hromádka System"
        }
    ],
    [
        "g6",
        {
            "info": "This is the Fianchetto Variation"
        }
    ],
    [
        "e5",
        {
            "info": "This is the Czech Benoni"
        },
        "Nc3",
        "d6",
        "e4",
        "g6",
        {
            "info": "This is the Czech Benoni, King's Indian System"
        }
    ]
];

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