This project will allow you to use nested loops - a programming pattern that occurs frequently when working with multi-dimensional data, such as in image analysis. We'll start off easy with a simple grid within which you have to create some of the flags from the international maritime signal code.
Pay close attention to the requirements of the different flags as described below.
The starter code that you are given includes a simple library for drawing the flags, library which is described in more detail below. You will also find a 'FlagDriver' class that helps call the appropriate method based on user input. All you need to do is implement the required methods.
Please read all this document carefully through the end before starting your project.
To create flags you need to use the RectangularGrid class provided to you by the project. Here is a description of methods you may find useful.
Creating a new RectangularGrid object
You won't really have to create any new objects for this assignment. Should you, for any reason, want to create one, you can use the following statement:
RectangularGrid grid = new RectangularGrid(height, width);
In the code above, the height and width are variables defined by you, or literals, defining the height and width of the grid.
Getting the dimensions of the grid
Your code will receive an already created grid. To find out its size, and determine whether it is of appropriate size for the flag you are creating, you can use the methods:
public static int getHt(); // returns the height of the grid
public static int getWd(); // returns the width of the grid
Setting the color of specific locations in the grid
You can set the color of the pixel at position (row, col) to a color defined by the Java Color class, using the command:
public static void setColor(int row, int col, Color color); // set the pixel at (row, col) to color
The Color class defines a number of colors in an easy to use fashion. For example, Color.red represents the red color, Color.blue, the blue color, etc. See more in the documentation for the Color class.
Getting the color from a pixel
You can get the color of a pixel at position (row, col) using the method:
public static Color getColor(int row, int col); // get the color of pixel (row, col)
To help you test your code, we have provided driver code in the file GridDriver.java. When you run it it will ask you for a letter corresponding to one of the flags we are asking you to create, and then for a grid dimension, with additional information about acceptable grid sizes. The code will continue to ask you for input until you enter the number '0' at which point the code will terminate.
For this project you will have to implement code that draws several signal flags.For each of the flags carefully note the requirements for the size of the grid. If the grid provided to you does not meet these requirements, you must draw instead a completely red flag, irrespective of the size of the grid provided to you.
The flags you must implement are:
This is an entirely yellow square (height and width of the grid provided to you must be square).
This is a square evenly split horizontally with blue on top and red on bottom. The size of the grid must be an even number.
This is a square evenly split vertically with white on the left side and red on the right. The size of the grid must be an even number.
This is a square evenly split into five horizontal rows with alternating colors blue, white, red, white, blue. The size of the grid must be a multiple of 5.
This is a square split evenly into a simple checkerboard with yellow squares on the main diagonal and black squares on the anti-diagonal. The size of the grid must be even.
This is a square evenly split diagonally. The bottom left triangle is yellow and the top right is red. The grid must be a square. Also, the main diagonal must be red.
This is a white square on a blue background. The side of the inner square is 1/3 of the size of the grid. The size of the grid must be a multiple of 3.
This is a red diamond on a white background. The size of the grid must be an odd number.
Ungraded challenge questions
For those of you who want an extra challenge, I have set up release tests for two more flags:
This is a square flag with a blue and white checkered pattern with 4 rows and 4 columns. The top let square is blue. The size of the grid must be a multiple of 4.
This is a black circle on a yellow background. The size of the grid must be an odd number.
You can try to make any of the other flags, as well as other patterns (e.g., Minecraft characters). If you implement flags not listed above you will have to modify the driver code provided. Also, please let us know if you have come up with either an interesting pattern design, or an interesting way of implementing it in your code. We will publish them in a 'flag hall of fame', and depending on the number of entries we can have you present to the class as well.
You can make this project much easier for some flags if you implement a helper method called, for example, fillRectangle. Such a method would take as parameters a grid, four integers, and a color. The four integers represent the boundaries of a rectangle within the grid. This method would fill the corresponding region of the grid with the color provided as parameter.
With this helper method written you can very quickly build many of the flags. For example, fillRectangle(grid, 0, 0, grid.getWd(), grid.getHt(), Color.blue) would make the full grid blue.
We have made the public test code available to you (studentTests.java) - this is the code that gets run to check that you pass public tests. You can (and should) add your own tests to make sure you are on the right track.
Assumptions about grid size
It should be apparent by now that you should not make any assumptions about the size of the grid provided to you beyond the specific requirements specified for each flag. In other words, your code should create correct flags for grids of arbitrary size. To allow you to focus on the main task at hand, I will not provide you with grids smaller than 2x2, i.e., you don't need to bother checking if I provide you an empty or too small grid.
- A common access paradigm when dealing with two-dimensional data is loop over the different dimensions separately. In plain English you would say something along the lines of "for each row and for each column process the element at the intersection of the row and the column". This is an extension over what you had to do for the cipher code where you only had one dimension.
- A time/code saving strategy you can use involves overwriting information you already wrote earlier. For example, imagine you have a grid that needs to be 'painted' yellow with a black dot in the middle. One way to do it is to carefully paint the grid yellow with the exception of the center square, then paint that one black. A simpler way to do it is to simply paint everything yellow then over-paint the middle square black. This is actually what painters do (including the great masters), and also what many computer graphics applications do to render complex 3-dimensional scenes in 2 dimensions.
Computationally, this approach is a bit more expensive as certain pixels are visited multiple times during the execution of your code. The savings in coding (and debugging) effort more than make up for the slight increase in run time.
- All of the methods you will write have the same basic structure: first you need to check that the conditions for the grid hold, if they don't you need to fill the grid with red and return. If the grid dimensions are OK, then you need to draw the specific flag for each method. The first thing you should do is make sure that the dimension check code works and that you correctly create the error flag.
This initial exercise will also make sure you know how to create the code that fills the whole grid with a single color, i.e., solving the Quebec flag will be a trivial extension. Once you know the dimension checks work properly, you can simply duplicate that code within each of your methods and make small changes according to the specific requirements of each flag.