The third section of code contains logic to unite a piece with the top row when it comes to rest:
void Board::unite(const Piece &piece) {
for (int column = 0; column < PieceSize; ++column) {
for (int row = 0; row < PieceSize; ++row) {
if (piece.isBlock(column, row)) {
int columnTarget = piece.getColumn() + column;
int rowTarget = piece.getRow() + row;
cells_[columnTarget][rowTarget] = true;
}
}
}
// Continuously loops through each of the rows until no full rows are
// detected and ensures the full rows are collapsed and non-full rows
// are shifted accordingly:
while (areFullRowsPresent()) {
for (int row = BoardRows - 1; row >= 0; --row) {
if (isRowFull(row)) {
updateOffsetRow(row);
currentScore_ += 1;
for (int column = 0; column < BoardColumns; ++column) {
cells_[column][0] = false;
}
}
}
}
}
bool Board::isRowFull(int row) {
for (int column = 0; column < BoardColumns; ++column) {
if (!cells_[column][row]) return false;
}
return true;
}
bool Board::areFullRowsPresent() {
for (int row = BoardRows - 1; row >= 0; --row) {
if (isRowFull(row)) return true;
}
return false;
}
void Board::updateOffsetRow(int fullRow) {
for (int column = 0; column < BoardColumns; ++column) {
for (int rowOffset = fullRow - 1; rowOffset >= 0; --rowOffset) {
cells_[column][rowOffset + 1] =
cells_[column][rowOffset];
}
}
}
The unite() function and the corresponding isRowFull(), areFullRowsPresent(), and updateOffsetRow() functions perform several operations. It updates the private cells_ variable with the rows and columns that the specified &piece argument occupies by setting the appropriate array location to true. It also clears any full rows (all columns filled) from the board by setting the corresponding cells_ array locations to false and increments the currentScore_. After the row is cleared, the cells_ array is updated to shift the row above the cleared row down by 1.