undoMove method Null safety

Move? undoMove()

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

Implementation

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

  Move move = old.move;
  kings = old.kings;
  turn = old.turn;
  castling = old.castling;
  epSquare = old.epSquare;
  halfMoves = old.halfMoves;
  moveNumber = old.moveNumber;

  Color us = turn;
  Color them = swapColor(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 castlingTo, castlingFrom;
    if ((move.flags & BITS_KSIDE_CASTLE) != 0) {
      castlingTo = move.to + 1;
      castlingFrom = move.to - 1;
    } else if ((move.flags & BITS_QSIDE_CASTLE) != 0) {
      castlingTo = move.to - 2;
      castlingFrom = move.to + 1;
    }

    board[castlingTo] = board[castlingFrom];
    board[castlingFrom] = null;
  }

  return move;
}