implemented bisic moves

This commit is contained in:
Didictateur 2025-10-15 15:32:50 +02:00
parent 97ef669cbe
commit 0a8507b90c
5 changed files with 240 additions and 1 deletions

View file

@ -90,3 +90,5 @@ La position de toutes les pièces sont échangées aléatoirement.
Une reine est dégradée en pion
### Tricherie
Regarde les trois prochaines cartes de la pioche
### Tout ou rien
Une pièce choisie ne peut maintenant se déplacer que si elle capture

View file

@ -0,0 +1,50 @@
// Utilities for movement generation
// The movement modules receive a context object with at least:
// - board: instance exposing getWidth(), getHeight(), getCell(x,y) and setPiece(x,y,piece)
// - from: { x, y }
// - piece: the moving piece (with getColor())
/**
* Walk in linear directions (array of dx,dy) until blocked.
* Returns an array of move objects: { x, y, capture: boolean }
*
* Options:
* - maxSteps (default: Infinity)
* - allowCapture=true
* - allowEmpty=true
*/
export function generateLinearMoves({ board, from, piece, directions, maxSteps = Infinity, allowCapture = true, allowEmpty = true }) {
const moves = [];
const w = board.getWidth();
const h = board.getHeight();
const color = piece.getColor();
for (const [dx, dy] of directions) {
let steps = 0;
let x = from.x + dx;
let y = from.y + dy;
while (x >= 0 && x < w && y >= 0 && y < h && steps < maxSteps) {
const cell = board.getCell(x, y);
const target = cell?.piece ?? null;
if (target == null) {
if (allowEmpty) moves.push({ x, y, capture: false });
// continue along this direction
} else {
// occupied
if (target.getColor() !== color) {
if (allowCapture) moves.push({ x, y, capture: true });
}
// stop after encountering any piece
break;
}
steps++;
x += dx;
y += dy;
}
}
return moves;
}

View file

@ -0,0 +1,13 @@
// Central export for movement modules
import {RookMove, BishopMove, KnightMove, QueenMove, KingMove, PawnMove} from './moves.js';
import { generateLinearMoves } from './generateMoves.js';
export default {
RookMove,
BishopMove,
KnightMove,
QueenMove,
KingMove,
PawnMove,
generateLinearMoves,
};

View file

@ -0,0 +1,172 @@
import { generateLinearMoves } from './generateMoves.js';
class RookMove {
/**
* Return possible moves for a rook-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const orthogonals = [
[1, 0],
[-1, 0],
[0, 1],
[0, -1],
];
return generateLinearMoves({
board: ctx.board,
from: ctx.from,
piece: ctx.piece,
directions: orthogonals,
});
}
}
class BishopMove {
/**
* Return possible moves for a bishop-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const diagonals = [
[1, 1],
[1, -1],
[-1, 1],
[-1, -1],
];
return generateLinearMoves({
board: ctx.board,
from: ctx.from,
piece: ctx.piece,
directions: diagonals,
});
}
}
class KnightMove {
/**
* Return possible moves for a knight-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const knightMoves = [
[2, 1], [2, -1], [-2, 1], [-2, -1],
[1, 2], [1, -2], [-1, 2], [-1, -2],
];
return generateLinearMoves({
board: ctx.board,
from: ctx.from,
piece: ctx.piece,
directions: knightMoves,
maxSteps: 1,
allowEmpty: true,
allowCapture: true,
});
}
}
class QueenMove {
/**
* Return possible moves for a queen-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const directions = [
[1, 0], [-1, 0], [0, 1], [0, -1], // orthogonals
[1, 1], [1, -1], [-1, 1], [-1, -1], // diagonals
];
return generateLinearMoves({
board: ctx.board,
from: ctx.from,
piece: ctx.piece,
directions: directions,
});
}
}
class KingMove {
/**
* Return possible moves for a king-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const directions = [
[1, 0], [-1, 0], [0, 1], [0, -1], // orthogonals
[1, 1], [1, -1], [-1, 1], [-1, -1], // diagonals
];
return generateLinearMoves({
board: ctx.board,
from: ctx.from,
piece: ctx.piece,
directions: directions,
maxSteps: 1,
});
}
}
class PawnMove {
/**
* Return possible moves for a pawn-like piece from `from` on the given `board`.
* The move format is { x, y, capture: boolean }
*
* ctx: { board, from: {x,y}, piece }
*/
static moves(ctx) {
const color = ctx.piece.getColor();
const forward = (color === 'white') ? -1 : 1; // assuming y=0 is top
const moves = [];
const w = ctx.board.getWidth();
const h = ctx.board.getHeight();
const x = ctx.from.x;
const y = ctx.from.y;
// Forward move
if (y + forward >= 0 && y + forward < h) {
const forwardCell = ctx.board.getCell(x, y + forward);
if (forwardCell?.piece == null) {
moves.push({ x: x, y: y + forward, capture: false });
// Double step from starting position
const startingRow = (color === 'white') ? h - 2 : 1;
if (!ctx.piece.hasMoved) {
const doubleForwardCell = ctx.board.getCell(x, y + 2 * forward);
if (doubleForwardCell?.piece == null) {
moves.push({ x: x, y: y + 2 * forward, capture: false });
}
}
}
}
// Captures
for (const dx of [-1, 1]) {
if (x + dx >= 0 && x + dx < w && y + forward >= 0 && y + forward < h) {
const diagCell = ctx.board.getCell(x + dx, y + forward);
const target = diagCell?.piece ?? null;
if (target != null && target.getColor() !== color) {
moves.push({ x: x + dx, y: y + forward, capture: true });
}
}
}
return moves;
}
}
export { RookMove, BishopMove, KnightMove, QueenMove, KingMove, PawnMove };

View file

@ -22,6 +22,8 @@ class Piece {
this.color = color;
/** @type {PieceType} */
this.type = type;
/** @type {boolean} */
this.hasMoved = false;
}
/**