CS 160, Summer 2016
Programming Assignment P8
Terriers and Squirrels
Programming due Monday, Aug. 1 at 11:59pm, no late submissions.
This programming assignment has four objectives:
- Learn how to read and understand code.
- Write code that fits into an existing game.
- Keep the squirrels alive as long as possible.
- Help the terriers hunt down the squirrels.
Description
The purpose of the assignment is to finish two Java classes that implement
the behavior of 1) a squirrel that is trying to evade terriers, and 2) a
terrier that feels compelled to chase squirrels. The game is played on a board,
with some number of terriers and squirrels whose placement is determined by
a file. The board is a two-dimensional array, with 'S' for Squirrel, 'D' for
Terrier, 'T' for Tree, 'F' for Fence, and '-' for empty squares with Grass.
The game engine reads the file specified on the command line, builds a
user interface. Approximately every couple of seconds it asks each squirrel and
terrier which way they want to move. You are going to code the behavior of
both animals.
Terrier behavior is defined in Terrier.java. Terriers always try to chase after
the nearest squirrel and eat it. Terriers must avoid running into other terriers
or going off the board, and they cannot climb trees or pass through Fences.
Squirrel behavior is defined in Squirrel.java. Squirrels look for the closest terrier
and always move in the opposite direction. Squirrel must avoid running into other squirrels
or terriers, but they can pass through fences or climb trees. If they make it to a Tree,
they are safe and disappear from the board.
The game continues until all squirrels are safe or eaten, or for 30 iterations, whichever
comes first. None of the supplied fields require that many iterations. The game engine
reports all movements and significant events.
Instructions
NOTE: This assignment is complex, make sure and read the instructions carefully!
Part One
Create a project called P8, and download the following files:
- Copy the code from UserInterface.java into P8/src.
- Copy the code from GameEngine.java into P8/src.
- Copy the code from AnimalInterface.java into P8/src.
- Copy the code from Terrier.java into P8/src.
- Copy the code from Squirrel.java into P8/src.
- Copy the image file iconTerrier.png into the project.
- Copy the image file iconSquirrel.png into the project.
- Copy the image file iconMunch.png into the project.
- Copy the image file iconFence.png into the project.
- Copy the image file iconTree.png into the project.
- Copy the image file iconGrass.png into the project.
- Copy the image file squirrelPrints.png into the project.
- Copy the image file dogPrints.png into the project.
- Copy the data file SimpleGame.txt into the project.
- Copy the data file TwoTerriers.txt into the project.
- Copy the data file TwoSquirrels.txt into the project.
- Copy the data file SquirrelEscape.txt into the project.
- Copy the data file SquirrelFence.txt into the project.
- Copy the data file SquirrelNightmare.txt into the project.
- Only modify Squirrel.java and Terrier.java, do not modify other provided files.
- Submit a P8.jar file with (only) Squirrel.java and Terrier.java.
- Don't forget to put your name and the date in the comments.
After downloading and building the files, you should be able to run the GameEngine, but the
Squirrel will always move right, and the Terrier will always move left. Both will soon go off
the board, causing an exception. If GameEngine is not running at all, get some help in the lab.
Part Two
Next, modify the code in Terrier.java and Squirrel.java, which both implement the following
interface:
public interface AnimalInterface{
public enum eMove {
NO_MOVE,
LEFT,
UP_LEFT,
UP,
UP_RIGHT,
RIGHT,
DOWN_RIGHT,
DOWN,
DOWN_LEFT
}
// Find the closest squirrel or terrier
public void findClosest();
// Report the closest position
public int getClosestCol();
public int getClosestRow();
// Move the animal, according to the rules
public void moveAnimal();
// Report the current position
public int getCurrentRow();
public int getCurrentCol();
// Report the previous position
public int getPreviousRow();
public int getPreviousCol();
}
Complete the Squirrel object, as follows:
- Complete the non-static method findClosest to find which Terrier is the closest:
- To do so you must scan the board from top to bottom and left to right, computing the Euclidean distance for each Terrier that you find. The Euclidean distance calculation is shown here.
- Store the row and column of the closest terrier so that you can return it when getClosestRow and getClosestCol are called.
- If more than one Terriers are at an equal distance, store the row and column for the first Terrier you find.
- Write the moveAnimal method in AnimalInterface. This move has several steps, which can all be included in the method, or you can add private methods for each step:
- STEP 1) Select the move (of type eMove) which is in the exact opposite direction from the closest Terrier. For example, if the Terrier is left on the same row, move right. If the Terrier is below on the same column, move up. If the Terrier is above and right, move down and left. If the Terrier is below and right, move up and left, and so on.
- STEP 2) Adjust the selected move (of type eMove) to avoid going off the board, running into a Terrier, or running into another Squirrel by carefully implementing the following behavior (in the order shown). You probably will want implement a private method to see if a particular move is valid.
- If you are planning on moving DOWN_LEFT, but that move is not valid for
one of the reasons above, move LEFT instead.
- If you are planning on moving LEFT, but that move is not valid for
one of the reasons above, move UP_LEFT instead.
- If you are planning on moving UP_LEFT, but that move is not valid for
one of the reasons above, move UP instead.
- If you are planning on moving UP, but that move is not valid for
one of the reasons above, move UP_RIGHT instead.
- If you are planning on moving UP_RIGHT, but that move is not valid for
one of the reasons above, move RIGHT instead.
- If you are planning on moving RIGHT, but that move is not valid for
one of the reasons above, move DOWN_RIGHT instead.
- If you are planning on moving DOWN_RIGHT, but that move is not valid for
one of the reasons above, move DOWN instead.
- If you are planning on moving DOWN, but that move is not valid for
one of the reasons above, move DOWN_LEFT instead.
- If you get through adjusting the move as specified above, and the move is
still not valid, set the move to NO_MOVE and return without updating the position.
- STEP 3) Make the move by modifying the currentRow and currentCol based on the adjusted move. For example, if the move is DOWN, increment currentRow, if the move is LEFT, decrement currentCol, if the move is UP_RIGHT, decrement currentRow and increment currentCol, and so on.
- To give you an idea of the scope of Squirrel.java, I wrote a method of
~15 actual lines to find the closest Terrier, ~20 lines to select the move,
~30 lines to adjust the move, ~10 lines to make the move, and ~10 lines for
a private method to see if a particular move is valid. There is virtually all
of the code required.
Complete the Terrier object, as follows:
- Write the findClosest method to which is similar to the Squirrel class, but instead of finding the closest Terrier you'll be finding the closest Squirrel.
- Write the move method in AnimalInterface that selects the desired move for the Terrier, which should be in the direction of the closest Squirrel.
- If the Squirrel is left on the same row, move left. If the Squirrel is below on the same column, move down. If the Squirrel is above and right, move up and right. If the Squirrel is below and right, move down and right, and so on.
- Next you must avoid going off the board, or running into another Terrier, Fence, or Tree by carefully implementing the same algorithm as for the Squirrel, except that deciding whether a move is valid differs.
- If you get through adjusting the move as specified above, and the move is
still not valid, set the move to NO_MOVE and return without updating the position.
- Otherwise, update the current position based on the move, before returning
from moveAnimal.
- Terrier.java is similar in size to Squirrel.java, and most of the code
can be cloned, with minor changes.
Testing
Start by testing using the Simple Game (SimpleGame.txt) field, and make sure the
Squirrel locates the closest Terrier, and moves in the opposite direction, and avoids
going off the board. Then make sure the Terrier locates the closet Squirrel and chases
it, and avoids going off the board. The Simple Game has only one of each animal. Then
proceed to the more difficult boards.
Grading Rules
Please follow the usual rules for submitting Java programs.
- Work on your own.
- The name of the Java archive must be exactly P8.jar and must
contain only Squirrel.java and Terrier.java.
- Comments at the top with your name, date and course.
- We expect programming assignments to be implemented in Eclipse
using Java 1.5 or 1.6 or 1.7 or 1.8.
- We will be testing the code on the machines in the CS computer lab,
so make sure your code runs on those machines.
- We will be checking programs for plagiarism, so please don't copy
from anyone else.
Grading Criteria
- 100 points for perfect submission.
- 0 points for no submission, will not compile, submitted class file, etc.
- Preliminary Tests
- compileTest: checks that program compiles. (0 points)
- test1: checks the behavior of both animals on "SimpleGame.txt". (15 points)
- test2: checks the behavior of both animals on "TwoTerriers.txt". (15 points)
- test3: checks the behavior of both animals on "TwoSquirrels.txt". (15 points)
- test4: checks the behavior of both animals on "SquirrelEscape.txt". (20 points)
- test5: checks the behavior of both animals on "SquirrelNightmare.txt". (20 points)
- Final Tests
- Final grading includes the preliminary tests.
- test6: checks the behavior of both animals on "SquirrelFence.txt". (15 points)
Submission
To create the P8.jar file containing Terriers.java and Squirrels.java,
you must export the project from Eclipse in the JAR format. The default in Eclipse is to
make a JAR with Terriers.class and Squirrels.class. This will not pass
automated grading. To avoid this and correctly submit the source files, follow these directions:
- Right click the project and select Export.
- Select Java JAR file format.
- Click the "Export Java source file and resources" tab.
- Name the file P8.jar, which will be stored in the workspace.
- Submit the resulting P8.jar to the Checkin tab.
The default on the second to last item is "Export Java class files and resources",
which will not work. Here is an image that shows which box to select:
© 2016 CS160 Colorado State University. All Rights Reserved.