@Test public void testEraseCompleteLines() throws Exception { board.placeTetromino(Tetromino.S, 0, 0); board.placeTetromino(Tetromino.Z, 0, 1); board.placeTetromino(Tetromino.Z, 3, 1); board.placeTetromino(Tetromino.S, 5, 1); board.placeTetromino(Tetromino.S, 7, 1); IntArrayList changed = board.placeTetromino(Tetromino.S, 8, 1); assertArrayEquals(new int[] { 3, 4, 2, 2, 3, 3, 2, 3, 4, 3 }, board.getSkyline()); int lines = board.eraseCompleteLines(changed).size(); Assert.assertEquals(1, lines); assertArrayEquals(new int[] { 2, 3, 0, 1, 2, 2, 1, 2, 3, 2 }, board.getSkyline()); }
public IntSortedSet eraseCompleteLines(IntArrayList changedPositions) { IntAVLTreeSet erased = new IntAVLTreeSet(); for (int i = 0; i < changedPositions.size(); i++) { int rowToErase = BoardUtils.rowFromPos(changedPositions.get(i), BOARD_WIDTH); if (rowWidth[rowToErase] == BOARD_WIDTH) { int highestRow = BOARD_HEIGHT - maxColumnHeight; int pos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow, 0); if (rowToErase == highestRow) { Arrays.fill(buf, pos, pos + BOARD_WIDTH, EMPTY); } else { int newPos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow + 1, 0); System.arraycopy(buf, pos, buf, newPos, WIDTH * (rowToErase - highestRow)); Arrays.fill(buf, pos, newPos, EMPTY); } System.arraycopy(rowWidth, highestRow, rowWidth, highestRow + 1, rowToErase - highestRow); rowWidth[highestRow] = 0; erased.add(rowToErase); maxColumnHeight--; for (int j = 0; j < skyline.length; j++) { skyline[j] = computeColumnHeight(j); } } } return erased; }
TetrisBoard implements Board { public IntSortedSet eraseCompleteLines(IntArrayList changedPositions) { IntAVLTreeSet erased = new IntAVLTreeSet(); for (int i = 0; i < changedPositions.size(); i++) { int rowToErase = BoardUtils.rowFromPos(changedPositions.get(i), BOARD_WIDTH); if (rowWidth[rowToErase] == BOARD_WIDTH) { int highestRow = BOARD_HEIGHT - maxColumnHeight; int pos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow, 0); if (rowToErase == highestRow) { Arrays.fill(buf, pos, pos + BOARD_WIDTH, EMPTY); } else { int newPos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow + 1, 0); System.arraycopy(buf, pos, buf, newPos, WIDTH * (rowToErase - highestRow)); Arrays.fill(buf, pos, newPos, EMPTY); } System.arraycopy(rowWidth, highestRow, rowWidth, highestRow + 1, rowToErase - highestRow); rowWidth[highestRow] = 0; erased.add(rowToErase); maxColumnHeight--; for (int j = 0; j < skyline.length; j++) { skyline[j] = computeColumnHeight(j); } } } return erased; } }
TetrisBoard implements Board { public IntSortedSet eraseCompleteLines(IntArrayList changedPositions) { IntAVLTreeSet erased = new IntAVLTreeSet(); for (int i = 0; i < changedPositions.size(); i++) { int rowToErase = BoardUtils.rowFromPos(changedPositions.get(i), BOARD_WIDTH); if (rowWidth[rowToErase] == BOARD_WIDTH) { int highestRow = BOARD_HEIGHT - maxColumnHeight; int pos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow, 0); if (rowToErase == highestRow) { Arrays.fill(buf, pos, pos + BOARD_WIDTH, EMPTY); } else { int newPos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow + 1, 0); System.arraycopy(buf, pos, buf, newPos, WIDTH * (rowToErase - highestRow)); Arrays.fill(buf, pos, newPos, EMPTY); } System.arraycopy(rowWidth, highestRow, rowWidth, highestRow + 1, rowToErase - highestRow); rowWidth[highestRow] = 0; erased.add(rowToErase); maxColumnHeight--; for (int j = 0; j < skyline.length; j++) { skyline[j] = computeColumnHeight(j); } } } return erased; } TetrisBoard(); private  TetrisBoard(TetrisBoard board); }
TetrisBoard implements Board { public IntSortedSet eraseCompleteLines(IntArrayList changedPositions) { IntAVLTreeSet erased = new IntAVLTreeSet(); for (int i = 0; i < changedPositions.size(); i++) { int rowToErase = BoardUtils.rowFromPos(changedPositions.get(i), BOARD_WIDTH); if (rowWidth[rowToErase] == BOARD_WIDTH) { int highestRow = BOARD_HEIGHT - maxColumnHeight; int pos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow, 0); if (rowToErase == highestRow) { Arrays.fill(buf, pos, pos + BOARD_WIDTH, EMPTY); } else { int newPos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow + 1, 0); System.arraycopy(buf, pos, buf, newPos, WIDTH * (rowToErase - highestRow)); Arrays.fill(buf, pos, newPos, EMPTY); } System.arraycopy(rowWidth, highestRow, rowWidth, highestRow + 1, rowToErase - highestRow); rowWidth[highestRow] = 0; erased.add(rowToErase); maxColumnHeight--; for (int j = 0; j < skyline.length; j++) { skyline[j] = computeColumnHeight(j); } } } return erased; } TetrisBoard(); private  TetrisBoard(TetrisBoard board); RectSize getSize(); int getMaxColumnHeight(); int[] getSkyline(); boolean isHeightExceeded(); @Override int getWidth(); @Override int getHeight(); @Override int getValue(int row, int col); @Override void setValue(int row, int col, int color); @Override int getValue(int pos); @Override void setValue(int pos, int color); @Override void invert(); @Override Board createAfterState(int row, int col, int player); @Override TetrisBoard clone(); IntArrayList placeTetromino(Tetromino tetromino, int column, int rotation); IntArrayList placeTetrominoCustom(Tetromino tetromino, int column, int rotation, int piece); Pair<IntArrayList, Integer> simulatePlaceTetrominoNaive(Tetromino tetromino, int column, int rotation); SimulationResult simulatePlaceTetromino(Tetromino tetromino, int column, int rotation); IntSortedSet eraseCompleteLines(IntArrayList changedPositions); @Override String toString(); @Override boolean equals(Object obj); @Override int hashCode(); int getHolesCount(); }
TetrisBoard implements Board { public IntSortedSet eraseCompleteLines(IntArrayList changedPositions) { IntAVLTreeSet erased = new IntAVLTreeSet(); for (int i = 0; i < changedPositions.size(); i++) { int rowToErase = BoardUtils.rowFromPos(changedPositions.get(i), BOARD_WIDTH); if (rowWidth[rowToErase] == BOARD_WIDTH) { int highestRow = BOARD_HEIGHT - maxColumnHeight; int pos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow, 0); if (rowToErase == highestRow) { Arrays.fill(buf, pos, pos + BOARD_WIDTH, EMPTY); } else { int newPos = BoardUtils.toMarginPos(DEFAULT_BOARD_SIZE, highestRow + 1, 0); System.arraycopy(buf, pos, buf, newPos, WIDTH * (rowToErase - highestRow)); Arrays.fill(buf, pos, newPos, EMPTY); } System.arraycopy(rowWidth, highestRow, rowWidth, highestRow + 1, rowToErase - highestRow); rowWidth[highestRow] = 0; erased.add(rowToErase); maxColumnHeight--; for (int j = 0; j < skyline.length; j++) { skyline[j] = computeColumnHeight(j); } } } return erased; } TetrisBoard(); private  TetrisBoard(TetrisBoard board); RectSize getSize(); int getMaxColumnHeight(); int[] getSkyline(); boolean isHeightExceeded(); @Override int getWidth(); @Override int getHeight(); @Override int getValue(int row, int col); @Override void setValue(int row, int col, int color); @Override int getValue(int pos); @Override void setValue(int pos, int color); @Override void invert(); @Override Board createAfterState(int row, int col, int player); @Override TetrisBoard clone(); IntArrayList placeTetromino(Tetromino tetromino, int column, int rotation); IntArrayList placeTetrominoCustom(Tetromino tetromino, int column, int rotation, int piece); Pair<IntArrayList, Integer> simulatePlaceTetrominoNaive(Tetromino tetromino, int column, int rotation); SimulationResult simulatePlaceTetromino(Tetromino tetromino, int column, int rotation); IntSortedSet eraseCompleteLines(IntArrayList changedPositions); @Override String toString(); @Override boolean equals(Object obj); @Override int hashCode(); int getHolesCount(); static final int EMPTY; static final int PIECE; static final int NUM_VALUES; static final int MARGIN_WIDTH; static final int BOARD_WIDTH; static final int BOARD_HEIGHT; static final int WIDTH; static final int HEIGHT; static final RectSize DEFAULT_BOARD_SIZE; }