Skip to content

Commit b862725

Browse files
committed
✨ Implement King Pseudo-Legal Move Generation (Issue #7)
- Add generateKingMoves() method following established patterns - Implement single-square movement in all 8 directions - Add isValidKingMove() helper method for boundary validation - Prevent board wrapping with file difference validation - Follow consistent move object structure - Add comprehensive input validation with descriptive errors - Foundation for future castling rules implementation
1 parent fc5e06a commit b862725

File tree

1 file changed

+73
-6
lines changed

1 file changed

+73
-6
lines changed

src/core/MoveGenerator.js

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,62 @@ export class MoveGenerator {
316316
return moves;
317317
}
318318

319+
/**
320+
* Generate pseudo-legal moves for the king.
321+
* Handles single-square movement in all 8 directions.
322+
* (Does not yet handle castling or check prevention).
323+
*
324+
* @param {Piece} piece - The king piece
325+
* @param {number} position - Current position index (0-63)
326+
* @returns {Array} Array of move objects
327+
*/
328+
generateKingMoves(piece, position) {
329+
const moves = [];
330+
const color = piece.getColor();
331+
332+
// Validate position
333+
if (position < 0 || position >= 64) {
334+
throw new Error(`Invalid position: ${position} must be between 0 and 63`);
335+
}
336+
337+
// King movement directions (all 8 surrounding squares)
338+
const directions = [-9, -8, -7, -1, 1, 7, 8, 9];
339+
340+
for (const direction of directions) {
341+
const currentSquare = position + direction;
342+
343+
// Check if the target square is on the board and the move is valid
344+
if (this.isValidSquare(currentSquare) && this.isValidKingMove(position, currentSquare)) {
345+
const targetPiece = this.board.squares[currentSquare];
346+
347+
if (!targetPiece) {
348+
// Empty square - add normal move
349+
moves.push({
350+
from: position,
351+
to: currentSquare,
352+
type: 'normal',
353+
piece: piece.getType(),
354+
color: color,
355+
});
356+
} else {
357+
// Square occupied - can capture if it's an enemy piece
358+
if (targetPiece.getColor() !== color) {
359+
moves.push({
360+
from: position,
361+
to: currentSquare,
362+
type: 'capture',
363+
piece: piece.getType(),
364+
color: color,
365+
captured: targetPiece.getType(),
366+
});
367+
}
368+
}
369+
}
370+
}
371+
372+
return moves;
373+
}
374+
319375
/**
320376
* Check if a square index is valid (0-63)
321377
* @param {number} square - Square index to validate
@@ -390,13 +446,24 @@ export class MoveGenerator {
390446
return fileDiff === 1 || fileDiff === 2;
391447
}
392448

393-
generateQueenMoves(_piece, _position) {
394-
// TODO: Implement queen move generation
395-
return [];
449+
/**
450+
* Check if a king move is valid (doesn't wrap around board edges).
451+
* @param {number} fromSquare - Starting square index.
452+
* @param {number} toSquare - Target square index.
453+
* @returns {boolean} True if the move is valid, false otherwise.
454+
*/
455+
isValidKingMove(fromSquare, toSquare) {
456+
const fromFile = fromSquare % 8;
457+
const toFile = toSquare % 8;
458+
const fileDiff = Math.abs(fromFile - toFile);
459+
460+
// A king's move should not wrap around the board.
461+
// The file difference for a valid king move will always be 0 or 1.
462+
return fileDiff <= 1;
396463
}
397464

398-
generateKingMoves(_piece, _position) {
399-
// TODO: Implement king move generation
465+
generateQueenMoves(_piece, _position) {
466+
// TODO: Implement queen move generation
400467
return [];
401468
}
402-
}
469+
}

0 commit comments

Comments
 (0)