A quick tutorial through the main lines of the Scotch Game and it's variations.
Code
//Please feel welcome to copy this code for your own creations.
let data = [
"e4",
"e5",
"Nf3",
"Nc6",
"d4",
"exd4",
[
{
info: "The main line is 4.Nxd4",
move: "Nxd4"
},
[
[
{
info: "The Classical Variation is 4...Bc5",
move: "Bc5"
},
[
{
move: "Nxc6",
info: "Option 1 is to play 5.Nxc6 here"
},
"Qf6",
"Qd2",
"dxc6",
"Nc3"
],
[
{
move: "Be3",
info: "Option 2 is to play 5.Be3 here"
},
"Qf6",
"c3",
"Nge7",
"Bc4"
],
[
{
move: "Nb3",
info: "Option 3 is to play 5.Nb3 here"
},
"Bb6",
"a4",
"a6",
"Nc3"
]
],
[
{
info: "The Schmidt Variation is 4...Nf6",
move: "Nf6"
},
[
{
move: "Nxc6",
info: "Option 1 is to play 5.Nxc6, the Mieses Variation"
},
"bxc6",
"e5",
"Qe7",
"Qe2",
"Nd5",
"c4"
],
[
{
move: "Nc3",
info: "Option 2 is to play 5.Nc3, the Scotch Four Knights Game"
},
"Bb4",
"Nxc6",
"bxc6",
"Bd3",
"d5",
"exd5",
"cxd5",
"O-O",
"O-O",
"Bg5",
"c6"
]
],
[
{
info: "The Steinitz Variation is 4...Qh4",
move: "Qh4"
},
"Nc3",
"Bb4",
"Be2",
"Qxe4",
"Nb5",
"Bxc3+",
"bxc3",
"Kd8",
"O-O"
]
],
],
[
{
info: "The Scotch Gambit is 4.Bc4",
move: "Bc4"
},
[
{
info: "Option 1 is for black to transpose into the Two Knights Defense with 4...Nf6",
move: "Nf6"
}
],
[
{
info: "Option 2 is for black to play 4...Bc5",
move: "Bc5"
},
"c3",
{
info: "Black can play 5..Nf6, which transposes to a safe variation of the Giuoco Piano",
move: "Nf6"
},
],
[
"Bc5",
"c3",
{
info: "Option 3 is for black to accept the gambit with 5...dxc3",
move: "dxc3"
},
"Bxf7+",
"Kxf7",
"Qd5+"
],
],
];
let targetMove = "";
onPieceClicked(function (squareName) {
if (targetMove == "") {
return false;
}
if (squareName == sourceOfSan(targetMove)) {
return true;
}
highlightSquareRed(squareName);
return false;
});
onMoveAttempted(function (san) {
if (san == targetMove) {
targetMove = "";
setTimeout(next, 50);
return true;
}
return false;
});
onNextClicked(function () {
showNextButton(false);
next();
});
function nextDelayed() {
setTimeout(next, 500);
}
var steps = [];
function treeToSteps(root, currentPath) {
if (Array.isArray(root) == false) {
console.error("root must be an array");
}
for (let child of root) {
if (Array.isArray(child)) {
//clone the currentPath
treeToSteps(child, currentPath.slice());
} else {
currentPath.push(child);
}
}
///if we have come to the end of the array
///and it's an object
///then we treat it as a leaf node
///and build steps for it
let last = root[root.length - 1];
if (Array.isArray(last) == false) {
if (steps.length > 0) {
steps.push({
info: "This concludes our analysis of this line",
showNextButton: true
});
steps.push({
reset: true
});
}
steps.push.apply(steps, currentPath);
}
}
treeToSteps(data, []);
console.log(steps);
function next() {
if (steps.length == 0) {
info("This completes our analysis of the Scotch Game");
complete();
return;
}
let step = steps.shift();
let shouldMoveNext = true;
if (typeof step == "string") {
if (isWhitesTurn()) {
targetMove = step;
info("Play " + currentMoveNumber() + "." + step);
} else {
setTimeout(function () {
performMove(step);
nextDelayed();
}, 500);
}
return;
}
if (isWhitesTurn()) {
if (step.info != undefined) {
info(step.info);
} else if (step.move != undefined) {
info("Play " + currentMoveNumber() + "." + step.move);
}
if (step.move != undefined) {
targetMove = step.move;
shouldMoveNext = false;
}
} else {
if (step.info == undefined) {
if (step.move != undefined) {
setTimeout(function () {
performMove(step.move);
nextDelayed();
}, 500);
shouldMoveNext = false;
}
} else {
info(step.info);
if (step.move != null) {
showNextButton(true);
///so if this pathway is repeated again
///then we probably don't want to have to click next again
///so we remove the info from the step
///the treeToSteps() function makes shallow copies of arrays
///so each object is repeated multiple times, and can be edited once
step.info = undefined;
steps.unshift({
move: step.move
});
shouldMoveNext = false;
}
}
}
if (step.showNextButton == true) {
showNextButton(true);
shouldMoveNext = false;
}
if (step.call != undefined) {
step.call();
}
if (step.reset == true) {
fromFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
}
if (shouldMoveNext) {
next();
}
}
next();