cm-chessboard-mini-games
Version:
Mini games as extensions for the cm-chessboard
157 lines (151 loc) • 5.72 kB
JavaScript
/**
* Author and copyright: Stefan Haack (https://shaack.com)
* Repository: https://github.com/shaack/cm-chessboard-eight-queens-puzzle
* License: MIT, see file 'LICENSE'
*/
import {INPUT_EVENT_TYPE} from "cm-chessboard/src/Chessboard.js"
import {Extension} from "cm-chessboard/src/model/Extension.js"
import {MARKER_TYPE, Markers} from "cm-chessboard/src/extensions/markers/Markers.js"
import {Position} from "cm-chessboard/src/model/Position.js"
import {MOVE_CANCELED_REASON} from "cm-chessboard/src/view/VisualMoveInput.js"
import {HtmlLayer} from "cm-chessboard/src/extensions/html-layer/Htmllayer.js"
export class EightQueens extends Extension {
constructor(chessboard, props = {}) {
super(chessboard)
this.props = {
wonText: "Very good<br/>you did it!"
}
Object.assign(this.props, props)
chessboard.addExtension(Markers)
chessboard.addExtension(HtmlLayer)
chessboard.initialized.then(() => {
this.clickListener = this.onSquareClick.bind(this)
chessboard.context.addEventListener("click", this.clickListener)
chessboard.enableMoveInput((event) => {
switch (event.type) {
case INPUT_EVENT_TYPE.moveInputStarted:
return true
case INPUT_EVENT_TYPE.moveInputCanceled:
if (event.reason === MOVE_CANCELED_REASON.movedOutOfBoard) {
this.chessboard.setPiece(event.squareFrom, null)
}
return true
case INPUT_EVENT_TYPE.validateMoveInput:
return true
}
this.markThreatened()
})
this.markThreatened()
})
}
onSquareClick(event) {
const square = event.target.getAttribute("data-square")
if (square && !this.chessboard.getPiece(square)) {
const pieces = this.chessboard.state.position.getPieces()
if (pieces.length < 8) {
this.chessboard.setPiece(square, "bq")
this.markThreatened()
}
}
}
markThreatened() {
this.chessboard.removeMarkers()
let i = 0
let threadsFound = 0
for (let square of this.chessboard.state.position.squares) {
if (square) {
// mark all squares threatened by this piece
const rank = String.fromCharCode(97 + i % 8)
const file = Math.floor(i / 8) + 1
const square = "" + rank + file
if (this.isThreatened(square)) {
this.chessboard.addMarker(MARKER_TYPE.circleDanger, square)
threadsFound++
}
}
i++
}
if (threadsFound === 0) {
const pieces = this.chessboard.state.position.getPieces()
if (pieces.length === 8) {
this.wonAnimation()
}
}
}
wonAnimation() {
const layer = this.chessboard.addHtmlLayer(`<div class='text fx-won'><div>${this.props.wonText}</div></div>`)
const text = layer.querySelector("div.text")
layer.classList.add("fx-fade-in")
setTimeout(() => {
layer.addEventListener("click", () => {
text.classList.remove("fx-won")
layer.classList.add("fx-fade-in")
text.classList.add("fx-vanish")
layer.classList.add("fx-fade-out")
setTimeout(() => {
this.chessboard.removeHtmlLayer(layer)
}, 1000)
})
}, 1000)
}
isThreatened(square) {
const [x, y] = Position.squareToCoordinates(square)
// console.log("isThreatened", square, x, y)
// test file
for (let sx = 0; sx < 8; sx++) {
const sSquare = Position.coordinatesToSquare([sx, y])
if (sSquare === square) {
continue
}
const piece = this.chessboard.getPiece(sSquare)
if (piece) {
// console.log("a) threatened by", piece, sSquare)
return true
}
}
// test rank
for (let sy = 0; sy < 8; sy++) {
const sSquare = Position.coordinatesToSquare([x, sy])
if (sSquare === square) {
continue
}
const piece = this.chessboard.getPiece(sSquare)
if (piece) {
// console.log("b) threatened by", piece, sSquare)
return true
}
}
// test diagonal
for (let sy = 0; sy < 8; sy++) {
const sx = x + sy - y
if (sx < 0 || sx > 7) {
continue
}
const sSquare = Position.coordinatesToSquare([sx, sy])
if (sSquare === square) {
continue
}
const piece = this.chessboard.getPiece(sSquare)
if (piece) {
// console.log("c) threatened by", piece, sSquare)
return true
}
}
// test diagonal
for (let sy = 0; sy < 8; sy++) {
const sx = x - sy + y
if (sx < 0 || sx > 7) {
continue
}
const sSquare = Position.coordinatesToSquare([sx, sy])
if (sSquare === square) {
continue
}
const piece = this.chessboard.getPiece(sSquare)
if (piece) {
// console.log("d) threatened by", piece, sSquare)
return true
}
}
}
}