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