Загрузка данных


 for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      if (x + j >= 0) {
        mainBoard[y + i][x + j] += mblock[i][j];
      }
    }
  }

  drawBoard();
}

// Функция обработки поворота блока
void rotateBlock() {
  // Временный блок с текущей фигурой
  List<List<int>> tmp = List.generate(4, (_) => List.filled(4, 0));

  // Заполняем временный блок
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      tmp[i][j] = mblock[i][j];
    }
  }

  // Поворачиваем фигуру
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      mblock[i][j] = tmp[3 - j][i];
    }
  }

  // Проверка на то, что фигура не пересекается с границей
  // или другими блоками ранее помещенных на доску фигур
  if (isFilledBlock(x, y)) {
    // если есть пересечения, то возвращаем старую фигуру
    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < 4; j++) {
        mblock[i][j] = tmp[i][j];
      }
    }
  }

  // Обновляем основную доску
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      // убираем старую фигуру
      mainBoard[y + i][x + j] -= tmp[i][j];

      // добавляем новую фигуру
      mainBoard[y + i][x + j] += mblock[i][j];
    }
  }

  drawBoard();
}

// Функция очистки заполненных строк
void clearLine() {
  for (int j = 0; j <= heightBoard - 3; j++) {
    // проверка заполненности строки
    int i = 1;
    while (i <= widthBoard - 3) {
      if (mainBoard[j][i] == posFree) {
        break;
      }
      i++;
    }

    if (i == widthBoard - 2) {
      // если строка заполнена
      // очистка строки и сдвиг строк игровой доски вниз
      for (int k = j; k > 0; k--) {
        for (int idx = 1; idx <= widthBoard - 3; idx++) {
          mainBoard[k][idx] = mainBoard[k - 1][idx];
        }
      }
      // увеличение очков
      scoreGame += 10;
    }
  }
}

// Функция проверки возможности сдвига блока в заданном направлении
bool isFilledBlock(int x2, int y2) {
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      if (mblock[i][j] != 0 && mainCpy[y2 + i][x2 + j] != 0) {
        return true;
      }
    }
  }
  return false;
}

bool get isGameOver => _isGameOver;

// Функция обработки шага игрового цикла
void nextStep() {
  // можно сдвинуть фигуру?
  if (!isFilledBlock(x, y + 1)) {
    // да
    moveBlock(x, y + 1);
  } else {
    // нет
    clearLine();
    savePresentBoardToCpy();
    newBlock();
    drawBoard();
  }
}