undo_move method

Move? undo_move()

Undoes a move and returns it, or null if move history is empty

Implementation

Move? undo_move() {
  if (history.isEmpty) {
    return null;
  }
  final old = history.removeLast();

  final move = old.move;
  kings = old.kings;
  turn = old.turn;
  castling = old.castling;
  ep_square = old.ep_square;
  half_moves = old.half_moves;
  move_number = old.move_number;

  final us = turn;
  final them = swap_color(turn);

  board[move.from] = board[move.to];
  board[move.from]!.type = move.piece; // to undo any promotions
  board[move.to] = null;

  if ((move.flags & BITS_CAPTURE) != 0) {
    board[move.to] = Piece(move.captured!, them);
  } else if ((move.flags & BITS_EP_CAPTURE) != 0) {
    var index;
    if (us == BLACK) {
      index = move.to - 16;
    } else {
      index = move.to + 16;
    }
    board[index] = Piece(PAWN, them);
  }

  if ((move.flags & (BITS_KSIDE_CASTLE | BITS_QSIDE_CASTLE)) != 0) {
    var castling_to, castling_from;
    if ((move.flags & BITS_KSIDE_CASTLE) != 0) {
      castling_to = move.to + 1;
      castling_from = move.to - 1;
    } else if ((move.flags & BITS_QSIDE_CASTLE) != 0) {
      castling_to = move.to - 2;
      castling_from = move.to + 1;
    }

    board[castling_to] = board[castling_from];
    board[castling_from] = null;
  }

  return move;
}