You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
1.9 KiB
76 lines
1.9 KiB
import { Chess } from 'chess.js';
|
|
|
|
function engine(state) {
|
|
const game = new Chess();
|
|
for (const move of state.moves) game.move(move);
|
|
return game;
|
|
}
|
|
|
|
export const chess = {
|
|
id: 'ajedrez',
|
|
version: '1.0.0',
|
|
minPlayers: 2,
|
|
maxPlayers: 2,
|
|
/** @returns {{ moves: string[], fen: string, turn: number }} */
|
|
create() {
|
|
return { moves: [], fen: new Chess().fen(), turn: 0 };
|
|
},
|
|
legal(state, seat) {
|
|
if (seat !== state.turn) return [];
|
|
return engine(state)
|
|
.moves({ verbose: true })
|
|
.map((m) => ({
|
|
type: 'move',
|
|
from: m.from,
|
|
to: m.to,
|
|
...(m.promotion ? { promotion: m.promotion } : {}),
|
|
}));
|
|
},
|
|
apply(state, action, seat) {
|
|
if (seat !== state.turn || action.type !== 'move')
|
|
throw new Error('No puedes hacer esa jugada.');
|
|
const game = engine(state);
|
|
const move = game.move({
|
|
from: action.from,
|
|
to: action.to,
|
|
...(action.promotion ? { promotion: action.promotion } : {}),
|
|
});
|
|
if (!move) throw new Error('Movimiento ilegal.');
|
|
const next = {
|
|
moves: [...state.moves, move.san],
|
|
fen: game.fen(),
|
|
turn: game.turn() === 'w' ? 0 : 1,
|
|
};
|
|
let result = null;
|
|
if (game.isCheckmate()) result = { winner: seat, reason: 'jaque mate' };
|
|
else if (game.isDraw())
|
|
result = {
|
|
winner: null,
|
|
reason: game.isStalemate() ? 'rey ahogado' : 'tablas por las reglas',
|
|
};
|
|
return {
|
|
state: next,
|
|
label: move.san,
|
|
result,
|
|
sound: result
|
|
? 'finish'
|
|
: game.isCheck()
|
|
? 'check'
|
|
: move.promotion
|
|
? 'promotion'
|
|
: move.captured
|
|
? 'capture'
|
|
: 'move',
|
|
};
|
|
},
|
|
view(state) {
|
|
const game = engine(state);
|
|
return {
|
|
...state,
|
|
board: game.board(),
|
|
check: game.isCheck(),
|
|
pgn: game.pgn(),
|
|
};
|
|
},
|
|
};
|