In this assignment, you will be making a game in which you try and place blocks to minimize the height of the stack. You will be learning about Java exceptions, file I/O, and defensive programming.
In the first part, you will be creating a command line application CreateBlocks.java that builds random level files for use by the game. The program generates a certain number of blocks (rectangles). The blocks are given a random width and height and a random (x, y) location. The block has to be contained in the unit box (0.0) - (1.0, 1.0). The color of each block is choosen randomly from a file of possible color values.
Command line arguments. The program takes 3-5 command line arguments as shown below:
% java CreateBlocks
CreateBlocks
The first argument is a file containing a list of colors. The first line in the color file is the total colors in the file. Each subsequent line has four columns describing a color: name of the color, red, green, and blue components. The components are given as an integer between 0 and 255. The first line is the total number of colors in the file:
114
IndianRed 205 92 92
LightCoral 240 128 128
Salmon 250 128 114
DarkSalmon 233 150 122
...
The second argument is the filename which the program writes the generated data to. The third argument is a positive integer specifying the total number of random blocks to generate. If the fourth argument is given, it specifies the minimum width/height of a random block. If the fifth argument is given, it specifies the maximum width/height of a random block. The min and max size arguments must be in the interval (0.0, 1.0) (exclusive of the end points). The default min size is 0.05, the default max size if 0.25.
Reading colors. You can use our example file colors.txt which contains 114 colors. You should create a static method Color [] loadColors(String filename) that reads the color definition file and returns an array of Java Color objects. This method should handle any exceptions caused by a failure to open the input file or parse the data in the file:
Generating blocks. Generate a random block and write a line to the output file. Each line in the output file should contain seven columns separated by whitespace: x-location, y-location, width, height, red, green, and blue. For example running "java CreateBlocks colors.txt out.txt 2" generated:
0.6428429106060277 0.3951860163442299 0.22882435786316718 0.22606163038598928 199 21 133
0.18094746559427116 0.6966589213411483 0.1185965813651805 0.22550766462918148 218 112 214
The width and height are randomly chosen using in the (min, max) range specified by either the default (0.05, 0.25) or by the command line arguments. The x-position and y-position are the center of the rectangle representing the block. The (x, y) position is chosen randomly but such that the entire block is inside the unit box (i.e. no part of the block extends outside of (0.0) - (1.0, 1.0). The RGB color triplet is given by one of the triplets from a randomly selected color from the read in set of colors (i.e. the three RGB integer values appear together on one of the lines in the color text file).
Drawing and area calculation. After generating each random block, draw the block using StdDraw. Also calculate the total area of all blocks generated and print it out. The area represents a best case "score" when the level is used in a game.
Example runs:
% java CreateBlocks missing.txt
CreateLevel color file output file num blocks [min size] [max size]
% java CreateBlocks missing.txt out.txt 10
Could not read color file: missing.txt
% java CreateBlocks StdDraw.class out.txt 1 0
Could not parse color file: StdDraw.class
% java CreateBlocks colors.txt . 10
Read in 114 colors.
Failed to open output file: .
% java CreateBlocks colors.txt out.txt -2
Read in 114 colors.
Invalid number of blocks: -2
% java CreateBlocks colors.txt out.txt 0
Read in 114 colors.
Invalid number of blocks: 0
% java CreateBlocks colors.txt out.txt ick
Read in 114 colors.
Invalid number of blocks: ick
% java CreateBlocks colors.txt out.txt 10 yo
Read in 114 colors.
Invalid min block size: yo
% java CreateBlocks colors.txt out.txt 10 0.0
Read in 114 colors.
Invalid min block size: 0.0
% java CreateBlocks colors.txt out.txt 10 0.1 -0.2
Read in 114 colors.
Invalid max block size: -0.2
% java CreateBlocks colors.txt out.txt 10 0.1 0.05
Read in 114 colors.
Invalid block size range: 0.1 > 0.05
% java CreateBlocks colors.txt out.txt 10 0.1 no
Read in 114 colors.
Invalid max block size: no
See more example: See image.
You will create a game in which you drag blocks around trying to minimize the height of the stack. The game will loads a text level file create by CreateBlocks. You need to develop three Java classes:
You need to develop three Java classes:
You need to create these files from scratch. Here is the API you should implement for the Block class: See image.
Here is the API you should implement for the Blocks class: See image.
Input file. The BlockGame program takes one command line option, the filename of the text file created by CreateLevel. If no command line options are given, the program should print "BlockGame blocks file" and terminate.
Coordinate system and screen. In this assignment, we will stick with the default StdDraw coordinate system. So (0.0, 0.0) is the lower-left corner and (1.0, 1.0) is the upper-right corner. You can also leave the canvas as the default 512 x 512 pixel size. You should draw a black square around the unit box showing the valid playing area.
Intersection of blocks. Two blocks intersect if any portion of the two axis-aligned rectangles overlap. It is actually easier to solve for when the two blocks do NOT overlap. This occurs if one rectangle is completely to the right of the other, or is to the left, or above, or below.
Moving blocks. In order to move a block, the user most put the mouse cursor over a block. If the mouse cursor is over multiple overlapping blocks, the block that is visually on top should be the one grabbed. When selected, the block immediately "snaps" to be centered on the mouse location. As long as the user holds the down the mouse button, the block will be dragged around. While dragging a block, it appears as a filled rectangle whenever the block could be placed at the current location. If a block intersects another block or extends outside the unit box, it should appear as the outline of a rectangle. When the mouse button is released and the block is in a valid location, it is dropped in the new location.
Rotating blocks. If the user is currently dragging a block (i.e. holding down the mouse button) and the user presses the spacebar, you should rotate the block 90 degrees. The block should draw itself as filled or outlined depending on whether the new rotated block is in a valid game location.
Height. At the top of the screen, the current height of the blocks should be displayed. A lower height is a better "score". The height should be displayed to three decimal places of precision. This is the maximum y-coordinate of the top side of any block in the game. If the user is currently dragging a block that is above all the other blocks, the height text should change to reflect the dragged block's current location.
Testing your classes. Here is the code we used to test our Block class along with sample output: See image. See code output.
Here is the code we used to test our Blocks class along with sample output: See image. See code output.