detectTSpin method

TSpinType detectTSpin(
  1. Tetromino piece,
  2. BoardState board, {
  3. int kickIndex = 0,
})

Classifies a T piece that has just been rotated into place using the Guideline 3-corner rule.

kickIndex is the kick test used by the last rotation; a T-Spin that needed the final kick (e.g. a T-Spin Triple setup) always counts as full. Walls and floor count as occupied corners.

Implementation

TSpinType detectTSpin(
  Tetromino piece,
  BoardState board, {
  int kickIndex = 0,
}) {
  if (piece.type != TetrominoType.T) return TSpinType.none;

  bool occupied(int dr, int dc) {
    final r = piece.position.row + dr;
    final c = piece.position.col + dc;
    if (r < 0 || r >= board.rows || c < 0 || c >= board.cols) return true;
    return board.cellAt(r, c).filled;
  }

  // Corners around the T's center cell at offset (1, 1).
  final topLeft = occupied(0, 0);
  final topRight = occupied(0, 2);
  final bottomLeft = occupied(2, 0);
  final bottomRight = occupied(2, 2);

  final count = [
    topLeft,
    topRight,
    bottomLeft,
    bottomRight,
  ].where((c) => c).length;
  if (count < 3) return TSpinType.none;

  // The two corners on the side the T is pointing towards.
  final (frontA, frontB) = switch (piece.rotation % 4) {
    0 => (topLeft, topRight),
    1 => (topRight, bottomRight),
    2 => (bottomLeft, bottomRight),
    _ => (topLeft, bottomLeft),
  };
  if ((frontA && frontB) || kickIndex == 4) return TSpinType.full;
  return TSpinType.mini;
}