private bool PlacePiece(Piece piece, int[] origin, int orientation) { int[,] toOccupy = piece.DetermineCellsToOccupy(origin, orientation); List <int> occupiedRows = new List <int>(); //verify placement i.t.o board edge and existing pieces for (int i = 0; i < toOccupy.GetLength(0); i++) { try { if (boardOccupation[toOccupy[i, 0], toOccupy[i, 1]]) { // Already occupied return(false); } if (!occupiedRows.Contains(toOccupy[i, 1])) { occupiedRows.Add(toOccupy[i, 1]); } } catch (IndexOutOfRangeException) { // Not a valid placement return(false); } } // Keep the game up to date game.ManuallyPlacePiece(piece, origin, orientation); occupiedRows.Sort(); game.ClearRows(occupiedRows.ToArray(), new int[occupiedRows.Count]); for (int i = 0; i < toOccupy.GetLength(0); i++) { this.boardOccupation[toOccupy[i, 0], toOccupy[i, 1]] = true; boardFills[toOccupy[i, 0], toOccupy[i, 1]].Fill = piece.Brush; } //Clear the board as necessary, not optimized. List <int> rowsToOccupy = new List <int>(); for (int i = 0; i < toOccupy.GetLength(0); i++) { if (!rowsToOccupy.Contains(toOccupy[i, 1])) { rowsToOccupy.Add(toOccupy[i, 1]); } } /* * The logic is pretty simple, we don't care about efficiency, so start at the bottom row, if it's full, remove it and bring down all the rows above. * Repeat for that row, once done, test the row up, until every row is tested. */ for (int i = this.height - 1; i >= 0; i--) { bool rowFull = true; for (int j = 0; j < this.width; j++) { if (!this.boardOccupation[j, i]) { rowFull = false; break; } } if (rowFull) { for (int j = i - 1; j >= 0; j--) // Start at the row above to send it down { for (int x = 0; x < width; x++) // Move horizontally along the board { boardFills[x, j + 1].Fill = boardFills[x, j].Fill; //Grid.SetColumn(boardFills[x, j + 1], j + 1); this.boardOccupation[x, j + 1] = this.boardOccupation[x, j]; // set the board occupation for later verification. } } i++; for (int x = 0; x < width; x++) { boardFills[x, 0].Fill = transparentBrush; this.boardOccupation[x, 0] = false; } } } // Verify the two different calculations match if (!this.boardOccupation.ToString().Equals(this.game.Board.ToString())) { Console.WriteLine(this.boardOccupation.ToString()); Console.WriteLine(this.game.Board.ToString()); throw new Exception("TetrisGame and Tetris boards do not match"); } display_score.Text = this.game.Score.ToString(); return(true); }