move method

bool move(
  1. Position from,
  2. Position to
)

Move a piece from one position to another, with complete validations.

Implementation

bool move(Position from, Position to) {
  ChessPiece? piece = getPiece(from);
  if (piece == null || piece.color != turn) {
    return false; // No piece or wrong turn.
  }

  // Check for castling move: king moving two squares horizontally.
  bool isCastlingMove =
      piece.type == PieceType.king &&
      (to.col - from.col).abs() == 2 &&
      from.row == to.row;

  // For normal moves, use the validator.
  if (!isCastlingMove && !MoveValidator.isValidMove(this, from, to)) {
    return false; // Illegal move.
  }

  // Save current state for undo.
  history.add(toFEN());

  // Handle castling separately.
  if (isCastlingMove) {
    // Determine kingside or queenside castling.
    if (to.col > from.col) {
      // Kingside castling.
      if (!MoveValidator.canCastleKingSide(this, piece.color)) {
        return false;
      }
      // Move the king.
      movePiece(from, to);
      // Move the rook: from the corner to the square adjacent to the king.
      Position rookFrom = Position(row: from.row, col: 7);
      Position rookTo = Position(row: from.row, col: 5);
      movePiece(rookFrom, rookTo);
    } else {
      // Queenside castling.
      if (!MoveValidator.canCastleQueenSide(this, piece.color)) {
        return false;
      }
      // Move the king.
      movePiece(from, to);
      // Move the rook: from the corner to the square adjacent to the king.
      Position rookFrom = Position(row: from.row, col: 0);
      Position rookTo = Position(row: from.row, col: 3);
      movePiece(rookFrom, rookTo);
    }
  } else {
    // Normal move: handle en passant, captures, etc.
    // Handle En Passant capture (if applicable).
    if (piece.type == PieceType.pawn &&
        enPassantTarget != null &&
        to == enPassantTarget) {
      int captureRow =
          piece.color == PieceColor.white ? to.row + 1 : to.row - 1;
      board[captureRow][to.col] = null;
    }

    // Set en passant target if pawn moves two squares.
    enPassantTarget =
        (piece.type == PieceType.pawn && (from.row - to.row).abs() == 2)
            ? Position(row: (from.row + to.row) ~/ 2, col: from.col)
            : null;

    // Capture any piece on the destination and move the piece.
    ChessPiece? capturedPiece = getPiece(to);
    movePiece(from, to);

    // Validate that the move doesn't leave the king in check.
    if (isKingInCheck()) {
      // Undo the move if it puts the king in check.
      movePiece(to, from);
      board[to.row][to.col] = capturedPiece;
      return false;
    }
  }

  // Update half-move clock and full-move number (using your existing logic)...
  // For example:
  // if (move resets half-move clock) halfMoveClock = 0; else halfMoveClock++;
  // if (turn == PieceColor.black) fullMoveNumber++;

  // Switch turn after a successful move.
  switchTurn();

  // Clear redo history.
  redoHistory.clear();

  return true;
}