package initial; import java.util.ArrayList; import java.util.List; public class BoundaryFiller { // depth of recursion; used for informational purposes only private int depth; // The simulated screen to be filled with pixels private Screen screen; // constructor; initializes the attributes of this class public BoundaryFiller() { screen = new Screen(); depth = 0; } /** * @param args - not used */ public static void main(String[] args) { BoundaryFiller bf = new BoundaryFiller(); // initialize bf.screen.displayPixels(); // writes the current "screen" to the console bf.doRecursiveFill(2, 3); // start filling at the specified coordinates System.out.println("Done."); } /** * Recursive fill algorithm * @param row the row number of the starting pixel * @param col the column number of the starting pixel * Notes: This algorithm fills the interior of a closed region bounded by a * closed border defined by pixels already on. Starting at (row, col), * the algorithm recursively searches for all pixels within the closed region * whose value is not true (on), and when found, changes those * pixel values to ON. */ void doRecursiveFill( int row, int col ) { if( row <0 || row >= Screen.HEIGHT ) // out of bounds return; if( col <0 || col >= Screen.WIDTH ) // out of bounds return; System.out.println( "\nrecursion level: " + depth ); boolean isFilled = screen.getPixel( row, col ); // returns true if that square is already marked depth++; // increment the recursion level screen.setPixel( row, col, true ); // marks the square screen.displayPixels(); // draw the result to the console // We get here when the recursions invoked above cannot proceed any further depth--; } /******************************************************************************/ // This private inner class represents the Screen whose pixels are to be filled /******************************************************************************/ private class Screen { // dimensions of shape to be filled private static final int WIDTH = 8; // shape width (# columns) private static final int HEIGHT = 7; // shape height (# rows) // Simulated B&W VRAM (video memory). Each element of the list represents // a pixel in memory. If the value of memory is true, then // the pixel is displayed; otherwise, a dark pixel private List videoRAM = new ArrayList(); /** * Initializes the interior and border pixels of a simulated rectangle to be filled */ public Screen() { // Here is the shape beginning at row 0, column 0. // 6 xxxxxxxx // 5 x x // 4 x x // 3 x x // 2 x x // 1 x x // 0 xxxxxxxx // 01234567 clearMemory(); // clear video memory (all pixels off) // set pixels indicated by x in diagram to "on" (the border pixels) for( int row=0; rowHEIGHT) throw new UnsupportedOperationException("row size exceeded"); if( col<0 || col>WIDTH) throw new UnsupportedOperationException("column size exceeded"); int offset = row*WIDTH + col; // compute offset into VRAM videoRAM.set(offset, isOn ); } /** * Gets the state of the pixel (on=true) at (row,col) * @param row the row number (0-based) of the pixel * @param col the column number (0-based) of the pixel * @return true if the pixel is on */ private boolean getPixel(int row, int col) { if( row<0 || row>HEIGHT) throw new UnsupportedOperationException("row size exceeded"); if( col<0 || col>WIDTH) throw new UnsupportedOperationException("column size exceeded"); int offset = row*WIDTH + col; // compute offset into VRAM return videoRAM.get(offset); } /** * Clears simulated video memory * Turns all simulated pixels off * */ private void clearMemory() { // iterate through each row and column, clearing memory videoRAM.clear(); for( int index=0; index