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