implemented bisic moves
This commit is contained in:
parent
97ef669cbe
commit
0a8507b90c
5 changed files with 240 additions and 1 deletions
|
|
@ -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
|
||||
50
engine/core/movement/generateMoves.js
Normal file
50
engine/core/movement/generateMoves.js
Normal 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;
|
||||
}
|
||||
13
engine/core/movement/index.js
Normal file
13
engine/core/movement/index.js
Normal 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,
|
||||
};
|
||||
172
engine/core/movement/moves.js
Normal file
172
engine/core/movement/moves.js
Normal 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 };
|
||||
|
|
@ -22,6 +22,8 @@ class Piece {
|
|||
this.color = color;
|
||||
/** @type {PieceType} */
|
||||
this.type = type;
|
||||
/** @type {boolean} */
|
||||
this.hasMoved = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue