64 lines
1.9 KiB
JavaScript
64 lines
1.9 KiB
JavaScript
import { Chessground } from 'chessground';
|
|
import { Chess } from 'chess.js';
|
|
|
|
export const ChessBoard = {
|
|
mounted() {
|
|
// Initialize chess.js for local rule validation
|
|
this.chess = new Chess();
|
|
|
|
// Initialize Chessground
|
|
this.ground = Chessground(this.el, {
|
|
fen: this.chess.fen(),
|
|
movable: {
|
|
color: 'white',
|
|
free: false, // Don't allow completely arbitrary drops
|
|
dests: this.getValidDests() // Only allow legal chess moves
|
|
},
|
|
events: {
|
|
// Triggered when a piece is successfully dropped
|
|
move: (orig, dest, _metadata) => {
|
|
this.handleMove(orig, dest);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
getValidDests() {
|
|
// Convert chess.js moves into the Map format Chessground expects
|
|
const dests = new Map();
|
|
this.chess.moves({ verbose: true }).forEach(m => {
|
|
if (!dests.has(m.from)) dests.set(m.from, []);
|
|
dests.get(m.from).push(m.to);
|
|
});
|
|
return dests;
|
|
},
|
|
|
|
handleMove(orig, dest) {
|
|
// 1. Try to execute the move in chess.js state
|
|
const move = this.chess.move({ from: orig, to: dest, promotion: 'q' });
|
|
|
|
if (move) {
|
|
// 2. Telemetry back up to Phoenix LiveView
|
|
this.pushEvent("move_played", {
|
|
from: orig,
|
|
to: dest,
|
|
fen: this.chess.fen()
|
|
});
|
|
|
|
// 3. Determine whose turn it is now ('w' or 'b')
|
|
const nextTurnColor = this.chess.turn() === 'w' ? 'white' : 'black';
|
|
|
|
// 4. Force Chessground to update its internal state for the next player
|
|
this.ground.set({
|
|
turnColor: nextTurnColor, // Switches turn tracking
|
|
movable: {
|
|
color: nextTurnColor, // 👈 THIS IS CRITICAL: Changes who is allowed to drag pieces!
|
|
dests: this.getValidDests() // Re-calculates valid legal squares for Black
|
|
}
|
|
});
|
|
} else {
|
|
// If chess.js says it's an illegal move, snap the piece back instantly
|
|
this.ground.set({ fen: this.chess.fen() });
|
|
}
|
|
}
|
|
} |