selectPiece method

Future<void> selectPiece(
  1. int pieceId
)

Implementation

Future<void> selectPiece(int pieceId) async {
  if (_state.phase != LudoTurnPhase.awaitingPieceSelection) {
    throw StateError('Roll the dice first.');
  }
  if (_isAnimating) return;

  final move  = _state.legalMoves.firstWhere(
    (m) => m.pieceId == pieceId,
    orElse: () => throw ArgumentError('Piece $pieceId is not a legal move.'),
  );
  final piece = _state.pieces.firstWhere((p) => p.id == pieceId);
  final steps = move.toPosition - move.fromPosition;

  // ── step-by-step animation ────────────────────────────────────
  _isAnimating    = true;
  _animatingPiece = piece;

  for (var step = 1; step <= steps; step++) {
    _animatingStep  = piece.trackPosition + step;
    _animatingPiece = piece.copyWith(trackPosition: _animatingStep!);
    notifyListeners();
    // await _audio.playPieceMove();
    await Future.delayed(stepAnimationDuration);
  }

  _animatingPiece = null;
  _animatingStep  = null;
  _isAnimating    = false;

  // ── commit to engine ──────────────────────────────────────────
  final result = _engine.move(_state, pieceId);
  _state = result.state.copyWith(lastMovedPiece: result.movedPiece);

  onPieceMoved?.call(result.movedPiece, result.fromPosition, result.toPosition);

  for (final captured in result.capturedPieces) {
    // _audio.playCapture();
    onPieceCaptured?.call(captured, result.movedPiece);
  }

  if (result.playerWon) {
    // _audio.playWin();
    final place = _state.winners.indexOf(result.movedPiece.playerIndex) + 1;
    onPlayerWon?.call(result.movedPiece.playerIndex, place);
  } else if (result.movedPiece.isFinished) {
    // _audio.playPieceHome();
  }

  // Teams mode: fire team-won callback
  if (result.teamWon) {
    final myTeam = teamOf(result.movedPiece.playerIndex, _teams);
    if (myTeam != null) onTeamWon?.call(myTeam);
  }

  if (result.gameFinished) {
    // _audio.playGameOver();
    onGameFinished?.call(List.unmodifiable(_state.winners));
  } else if (result.turnPassed) {
    _state = _state.copyWith(clearLastMovedPiece: true);
    onTurnChanged?.call(_state.currentPlayerIndex);
  }

  notifyListeners();
}