CS 202 - Computer Science II - Fall 2004
Flood Fill


Loyola College > Department of Computer Science > Dr. James Glenn > CS 202 > Examples and Lecture Notes > Flood Fill

ImageModel.java

import java.util.*;
import java.awt.*;

/**
 * This abomination is an appalling attempt to shoehorn a simple drawing
 * application into the existing framework for board games.  Here the
 * piece at each position is a rectangular chit with a certain color.
 * A move at a position either cycles that position through the available
 * colors or does a flood fill.  A move from one location to another draws
 * a line in the color at the starting position.
 *
 * @author I refuse to take responsibility for this.
 * @version 0.1 11/1/2004
 */


public class ImageModel extends GameBoardModel
{
    /**
     * Determines the sequence of colors when the user clicks on the drawing.
     */

    private Map colorSequence;

    /**
     * Creates an all black drawing of the given size.
     */

    public ImageModel(int w, int h)
    {
	super(w, h);

	for (int r = 0; r < h; r++)
	    for (int c = 0; c < w; c++)
		pieces[r][c] = new GamePiece(GamePiece.BLACK);

	// establish the sequence of colors to cycle through on clicks

	colorSequence = new HashMap();
	colorSequence.put(GamePiece.BLACK, GamePiece.RED);
	colorSequence.put(GamePiece.RED, GamePiece.BLUE);
	colorSequence.put(GamePiece.BLUE, GamePiece.GREEN);
	colorSequence.put(GamePiece.GREEN, GamePiece.YELLOW);
	colorSequence.put(GamePiece.YELLOW, GamePiece.ORANGE);
	colorSequence.put(GamePiece.ORANGE, GamePiece.PURPLE);
	colorSequence.put(GamePiece.PURPLE, GamePiece.BROWN);
	colorSequence.put(GamePiece.BROWN, GamePiece.WHITE);
	colorSequence.put(GamePiece.WHITE, GamePiece.BLACK);
    }

    /**
     * Returns the color at the given point in this drawing.
     *
     * @param r the row
     * @param c the column
     */

    public Color getBoardAt(int r, int c)
    {
	return pieces[r][c].getColor();
    }

    /**
     * Determines if the given positions are within the borders of
     * this drawing.
     *
     * @param fromR a row
     * @param fromC a column
     * @param toR a row
     * @param toC a column
     */

    public boolean isLegalMove(int fromR, int fromC, int toR, int toC)
    {
	return inBounds(fromR, fromC) && inBounds(toR, toC);
    }

    /**
     * Determines if the given positions are within the borders of
     * this drawing.
     *
     * @param r a row
     * @param c a column
     */

    public boolean isLegalMove(int r, int c)
    {
	return inBounds(r, c);
    }

    /**
     * Draws a line from the given from position to the given to position.
     * The color of the line will be the same as the color at the
     * from position.
     * @param fromR the starting row of the line
     * @param fromC the starting column of the line
     * @param toR the ending row of the line
     * @param toC the ending column of the line
     */

    public void makeMove(int fromR, int fromC, int toR, int toC)
    {
	int steps = Math.max(Math.abs(toR - fromR), Math.abs(toC - fromC));

	for (int i = 1; i <= steps; i++)
	    pieces[(int)(fromR + ((double)i / steps) * (toR - fromR))]
		[(int)(fromC + ((double) i / steps) * (toC - fromC))]
		= pieces[fromR][fromC];
    }

    /**
     * Changes the color at the given location in this drawing.
     *
     * @param r the row
     * @param c the column
     */

    public void makeMove(int r, int c)
    {
	pieces[r][c] = new GamePiece((Color)(colorSequence.get(pieces[r][c].getColor())));
    }

    /**
     * Does a flood fill in this drawing starting at the given position.
     * All positions 4-connected to the starting point through positions
     * that are the same color as the starting point are recolored.
     *
     * @param r the row to start filling from
     * @param c the column to start filling from
     */

    public void makeMove2(int r, int c)
    {
	Color oldColor = pieces[r][c].getColor();
	Color newColor = (Color)(colorSequence.get(oldColor));

	floodFill(r, c, oldColor, newColor);
    }

    /**
     * Does a flood fill in this drawing starting at the given position.
     * All positions 4-connected to the starting point through positions
     * colored using the first color are recolored using the second color.
     *
     * @param r the row to start filling from
     * @param c the column to start filling from
     * @param bgColor the color of the positions to change
     * @param fillColor the color to change those positions to
     */

    private void floodFill(int r, int c, Color bgColor, Color fillColor)
    {
	if (r >= 0 && r < getWidth()
	    && c >= 0 && c < getWidth()
	    && pieces[r][c].getColor().equals(bgColor))
	    {
		pieces[r][c] = new GamePiece(fillColor);
		floodFill(r + 1, c, bgColor, fillColor);
		floodFill(r - 1, c, bgColor, fillColor);
		floodFill(r, c + 1, bgColor, fillColor);
		floodFill(r, c - 1, bgColor, fillColor);
	    }
    }
}

This code can also be downloaded from the file ImageModel.java.