Published
Edited
Feb 9, 2021
2 forks
2 stars
Insert cell
Insert cell
// see: https://github.com/ornicar/chessground/blob/master/src/config.ts
// see also: https://github.com/ornicar/chessground-examples/blob/master/src/units/play.ts
board = {
const container = html`<div id="board-container"></div>`;
// This is the chess.js game engine (imported below).
const game = new Chess();
// This sets up the chess board in the div provided above
const cg = Chessground(container, {
movable: {
color: 'white', // only allow white pieces to be moved (it's white's turn to start)
free: false, // don't allow movement anywhere ...
dests: util.toDests(game), // ... only allow these moves. Accepts {square: [list of squares]} in Algebraic notation
},
draggable: {
showGhost: true
}
}); // There's a lot of other options, and their defaults are listed here: https://github.com/ornicar/chessground/blob/master/src/state.ts#L105
// Now we add an event callback for what happens after a move.
// This triggers a function defined in the next cell that sets up the
// board for the next move (and will continue being called after each move.
cg.set({
movable: { events: { after: util.playOtherSide(cg, game) } }
});
return container
}
Insert cell
util = {
// from https://github.com/ornicar/chessground-examples/blob/master/src/util.ts
// Gets the set of legal moves for the current chess.js game state.
// Returns {square: [list of squares]}, like {'a4': ['a5', 'a6']}.
const toDests = (chess) => {
const dests = new Map();
chess.SQUARES.forEach(s => {
const ms = chess.moves({square: s, verbose: true});
if (ms.length) dests.set(s, ms.map(m => m.to));
});
return dests;
}

// Translate colors between chess.js & chessground
const toColor = (chess) => {
return (chess.turn() === 'w') ? 'white' : 'black';

}

// Update the chess engine and board based on the most recent move
const playOtherSide = (cg, chess) => {
return (orig, dest) => {
// Update chess.js
// Note: we don't check the return value here which would tell
// us if this is a legal move. That's because we only allowed legal moves by setting "dests"
// on the board.
chess.move({from: orig, to: dest});
cg.set({
// I'm not sure what this does! You can comment it out and not much changes
// turnColor: toColor(chess),
// this highlights the checked king in red
check:chess.in_check(),
movable: {
// Only allow moves by whoevers turn it is
color: toColor(chess),
// Only allow legal moves
dests: toDests(chess)
}
});
};
}
return {toDests, toColor, playOtherSide}

}
Insert cell
Chess = require("chess.js@0.11")
Insert cell
Chessground = (await require('https://bundle.run/chessground@7.9.3')).Chessground
Insert cell
sideLength = Math.min(480, width) // Used for styling the div above.
// Should be a multiple of 160 to have things line up
Insert cell
html`<style>
#board-container {
width: ${sideLength}px;
height: ${sideLength}px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
}


${chessgroundStylesheets}
</style>`
Insert cell
// see: https://github.com/ornicar/chessground/tree/master/assets
// Without these sheets, the board doesn't look too good.
chessgroundStylesheets = {
const fetchStylesheet = (name) => {
const url = `https://raw.githubusercontent.com/ornicar/chessground/master/assets/chessground.${name}.css`;
return fetch(url).then(response => response.text());
};
const names = ["base", "brown", "cburnett"]
const requests = names.map(fetchStylesheet);
return Promise.all(requests)
.then(values => values.join("\n"))
.catch(() => FileAttachment("chessground.css").text());
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more