This is the multi-page printable view of this section. Click here to print.
Labs
1 - Eclipse Lab
Introduction
In this lab, you will practice the process of creating a class in Eclipse and submitting it through Gradescope.
Before working on this lab, you should already have completed the steps in Installing Java and Eclipse .
Part 1 - Coding in Eclipse
- Create a new Eclipse project named
PointLab
:
File -> New -> Java Project- Also uncheck the box that says “Create module-info.java file” or you will get an error saying “No source folder exists in the project”. (This error is harmless and can be ignored.) You should not have a module-info.java file in your project at any point this semester unless explicitly required by an assignment.
- Download the
Point class that implements the specifications outlined in the UML and other notes below.
- right-click the link and choose
Save Link As...
and save the file in the newly createdPointLab
project, in itssrc
folder.
- right-click the link and choose
Refresh
Often, when you have added a file to the workspace, Eclipse will not automatically refresh the package explorer. If you don’t see the file in the package explorer, right-click the project and chooseRefresh
.classDiagram
class Point
Point : -double xPosition
Point : -double yPosition
Point : +Point(xPosition double, yPosition double)
Point : +getX() double
Point : +getY() double
Point : +setX(newX double) void
Point : +setY(newY double) void
Point : +equals(other Object) boolean
Point : +toString() String
🚨Exception
We won’t typically listvoid
in UML diagrams. If a method has no return type in the UML diagram, either its name matches the class and it’s actually the constructor
which has no return type, or else it’s a void
method.Requirements
The return value of the
toString
method should consist of an open-parenthesis followed by the x-coordinate, followed by a comma, then a space, then the y-coordinate followed by a close-parenthesis. For example:"(1.0, 2.0)"
.The
equals
method:- should return true if the other point has the same x and y coordinates.
- Notice that the parameter type for the
equals
method isObject
, notPoint
. This is the standard signature for anequals
method: objects of different types should generally be considered not-equal, but it should still be possible to perform the comparison. - This means that
equals
method implementations are typically structured to use theinstanceof
operator as in the following example comparing instances of the (abridged)Person
class below in which we imagine we consider aPerson
equal
to anotherPerson
only when theirname
s are the same (when in reality of course we all agree that all people are equal no matter their names 🟰):public class Person { private String name; // Other methods not shown... public boolean equals(Object other) { // Return false if other is not a Person. if (!(other instanceof Person)) { return false; } // Cast other to Person so that we can access // members. Person otherPerson = (Person) other; // Now we can safely compare. return name.equals(otherPerson.name); } }
Once you have completed a syntactically correct
Point
class, move on to the next step.
Part 2 - Checkstyle Eclipse Integration
- Recall that Checkstyle needs to be explicitly enabled for each new Eclipse project. Right click your
PointLab
project in the “Package Explorer” tab and then select Checkstyle -> Activate Checkstyle. - Once you have completed the previous step, navigate to your file. Many lines of code in
Point.java
should now be marked with Checkstyle warnings. Each of these marked lines contains a violation of the style guidelines that would prevent you from successfully submitting a programming assignment. Clicking on the magnifying glasses in the left margin will show you a description of the problem. We’ll fix these problems in the next part of the lab.
Part 3 - Eclipse Auto-Formatting
Assuming that your auto-formatter is configured correctly, you should
be able to re-format your Point.java
file by selecting
the entire file CTRL + A and then pressing CTRL + SHIFT + F. (usually on a mac the hotkeys are the same but you swap in command in place of CTRL)
- Once you have auto-formatted your code you must save it before Checkstyle will recheck it. Hopefully, many of the flagged formatting errors should now be gone. Most of the remaining issues probably relate to missing Javadocs.
- Add appropriate Javadoc comments to your
Point
class. Eclipse will automatically generate a Javadoc template for any method. You can either type/**
+ENTER just above the method, or select the method and press SHIFT + ALT + J. - Re-run Checkstyle, and address any remaining formatting issues.
Part 4 - Adding a .jar File
One standard mechanism for distributing Java code is through .jar files. A .jar file is a compressed archive that can hold any number of Java classes in either source or binary form (as .java files or as .class files). For some projects in this course you will be provided with .jar files containing support code.
- Create a new folder named ’lib’ in your Java project. Download the file PointCode.jar , and drag it into the newly-created folder.
- Right click
PointCode.jar
and select Build Path -> Add to Build Path. - There should now be a “Referenced Libraries” entry in your
project explorer. Expanding that entry should allow you to inspect
the details of the
PointCode.jar
archive. All classes included in that archive are now available within your project. In this case there is only one class: PointDisplay.
Part 5 - Running
- Download the file PointDemo.java to your Desktop, then drag it into the default package section of your project.
- Look over the
PointDemo
class to get a feel for what it should do. Run the code to confirm that everything is working as expected.
Part 6 - JUnit
JUnit is a tool that makes it possible to automate the execution of Java test code. It is also the tool that is used by Gradescope to test your submissions. Don’t worry if you haven’t used JUnit before, we’ll spend more time on testing and JUnit later in the semester. For now, the goal is just to practice executing pre-written JUnit tests.
- Download the file
PointTest.java and drag
it into your PointLab project. These are exactly the tests that will
be used by Gradescope when you submit
Point.java
at the conclusion of this activity. - Initially, this file will not compile. If you open it up you will see that many of the lines of code are labeled as errors. The problem here is that JUnit isn’t part of the Java language. It is an external library that must be added to the Java Build path before it can be used. There are several different ways that this can be managed in Eclipse:
- Option 1: You should see that the first underlined statement at the top of
PointTest.java
is this:import static org.junit.jupiter.api.Assertions.*;
org.junit
on this line, Eclipse will pop up a box with an error message (“the import org.junit cannot be resolved
”) and the message “three quick fixes available:
”. If you scroll to the bottom and select “Fix project setup
” you should see a dialog offering toAdd JUnit 5 library to build path
. Click OK. Be careful! If it offers to addJUnit 4
, cancel and try the next option instead.- Option 2: A simple trick that you can use to add JUnit to the build path is to ask Eclipse to auto-generate a JUnit test file. Just right-click on any file in your project and select New -> JUnit Test Case. Make sure the top radio button in the dialog is set to “New JUnit Jupiter test”. Keep the rest of the default options and click “Finish”. This should create a new test file (which you can delete) and add JUnit 5 to the build path.
- Option 1: You should see that the first underlined statement at the top of
- Once everything is compiling successfully, you can execute the tests by right-clicking
PointTest.java
and selecting Run As -> JUnit Test . Hopefully, all of the tests will pass. If not, fix the errors inPoint.java
before moving on to the next step.
Part 7 - Submitting Through Gradescope
- Submit
Point.java
through https://www.gradescope.com/ . You should have an email from your instructor that indicates you have been added to the course. If you have not used Gradescope before, you may need to create an account. If your code fails any of the submission tests, make any necessary modifications and resubmit until there are no failures.
2 - Classes and UML Lab
Introduction
The goal for this activity is to implement a Car class so that it conforms to the UML below:
classDiagram
class Car
Car: -String make
Car: -int year
Car: -double speed
Car: +Car(m String, y int)
Car: +toString() String
Car: +getMake() String
Car: +getSpeed() double
Car: +getYear() int
Car: +accelerate() String
Car: +brake() void
ℹ️ Note
UML diagrams often omit the return type onvoid
methods. While they’re present above, we’ll likely omit them in the future.Part 1: Driver, Constructor and toString
- Create two Java class files: CarTester.java and Car.java. Only CarTester.java should include a main method.
- Add the three instance variables from the UML diagram to
your
Car
class. - Code the constructor for your
Car
class. This should initialize themake
andyear
fields using the arguments to the constructor. Thespeed
should be initialized to0
. - Code the
toString
method. This method should take no parameters and should return aString
that looks like this (except with the angle-bracketed parts replaced with this car's values):"A <year> <make> that is going <speed> mph"
- Test your partially completed
Car
class by adding code to themain
in CarTester.java that creates and prints two car objects. The contents ofmain
should look something like the following.Car car1; Car car2; car1 = new Car("Ford", 1997); car2 = new Car("Toyota", 2014); System.out.println(car1.toString()); System.out.println(car2.toString());
Part 2: Remaining Methods
Complete each of the remaining methods of the Car
class.
Test each method by adding appropriate calls to main
.
- The three "getter" methods should each return the value of the appropriate instance variable.
- The
accelerate
method should increase the currentspeed
of the car by 5.0 mph. It should also return aString
that describes the change to thespeed
, e.g."15.0 + 5.0 = 20.0"
. It should NOT be possible to increase the speed beyond 150.0 mph. If a call toaccelerate
would push the speed beyond 150.0, the speed should be set to 150.0. (reaching this limit should be reflected in the returned String as well, i.e."150.0 + 0.0 = 150.0"
)(How will you test that this is working correctly? How many times do you need to call
accelerate
before the upper speed limit is reached? Might a loop be helpful here?) - The
brake
method should decrease the current speed by 5.0 mph. It should not be possible for the speed to drop below 0 mph.
Submit Car.java only to Gradescope per your section's deadline. Gradescope will run Checkstyle tests on your submission.
Acknowledgements
Thank you to Dr. Sprague for this activity.
3 - Decisions
Background
CodingBat is a free site of live problems to build skill in Java and/or Python. It was created by Nick Parlante, who is Computer Science lecturer at Stanford. The name “CodingBat” was based on the Greek word “bat” meaning “this domain was available” (or so they say).
Objectives
- Practice writing small methods with conditionals and decisions.
- Explore combined conditionals as substitutes for decision statements.
- Observe the range of test cases needed to test decision statements.
Key Terms
- unit test
- A single example of running a small program unit, often a method.
- expected value
- The correct value a program should return for a unit test (aka test case).
- actual value
- The value a program actually returns for a unit test.
- simplified code or boolean expression
- A version of a piece of code that is less complicated or shorter than the original.
Part 0: Account Setup
- Go to codingbat.com and create an account (click the link on the upper right).
- Please use your JMU email when setting up your account.
- After logging in, click the “prefs” link (upper right) and “share to” your instructor’s email (
duanzx@jmu.edu
,stewarmc@jmu.edu
,wangid@jmu.edu
, orweikleda@jmu.edu
) so you will get credit. - Also make sure your name is entered as shown: Last, First
Part 1: Warm Up
As you begin to work CodingBat’s logic problems, you might find the CodingBat Boolean Logic page or their videos helpful:
Work through the following problems (all from Warmup-1 ). As you work through the problems notice that all of these have solutions available to you. Spend about 5 minutes trying each problem, before you look at the solution. When you are trying the problem and get the results, look at the test cases displayed by codingbat. Identify the expected and actual values. Notice that you may pass several tests, but not all of them. Unlike straight line code without decisions, conditionals and decision statements take a variety of test cases to make sure they work.
Part 2: String methods
Many of the problems on codingbat require you to use String methods that you may not yet have encountered. Check out especially:
Part 3: Warm-up with strings
Work through some of the Warmup-1 problems that require String methods:
Part 4: Problem Solving
- Solve the following problems (all from Logic-1 problems):
- Solve the following problems ( from Logic-2 problems):
4 - Arrays Lab
Background
You will write today’s program from scratch. Create a new Java class named ArrayPlay
with a main
method. For each step below, you should add code to the program without replacing prior code. When you are finished, this program will provide you with a reference for working with arrays including initializing, printing, and comparing. This lab involves formatting String
s. If you haven’t completed the (Horstmann) Chapter 4 reading (especially 4.3.2), consider skimming it. You may also find the JDK documentation of the Formatter class (especially the Format String Syntax section) useful. Dr. Mayfield (et al.)’s ThinkJava2 available free online is also a handy supplemental resource (see e.g. its 3.5 Formatting Output , and consider learning this search engine operator since this version of the book doesn’t seem to provide a search mechanism).
🎲 Di(c)e
This lab assumes you have some level of familiarity with dice :
- specifically that the singular of “dice” is (unfortunately) “die” (😱💀 In my opinion, every language - natural and otherwise - has bugs 🪲, and this is one of many in English, don’t come at me, I also think it’s ridiculous. I think we get to blame this one on French ).
- dice (or a die) can be “thrown”, “rolled”, or “cast”, all meaning to drop it and let it land on a random face.
- in this lab, the “Die” we refer to is assumed to be a so-called D6 (as the gamers do) , meaning a die with 6 faces (or “sides”).
🛑🧐 Stop and check:
Ensure that:
- the
ArrayPlay
class you created is spelled correctly (including upper- vs. lowercase) - the
ArrayPlay
class is in the default package (i.e. nopackage
statement in the source code, and the Eclipse Package Explorer shows the class in the(default package)
)
Objectives
- Use an array to store a sequence of values.
- Display the contents of an array with a loop.
- Practice manipulating various types of arrays.
- Write methods using array parameters.
Key Terms
- Array Initializer
- list of values used to instantiate and initialize an array in one step (see more on
Array Creation Expressions vs. Array Initializers, if you're curiousactually those both go to higher dimensional arrays which is out of scope for this activity. Probably skimming ThinkJava2's Creating Arrays is a sufficient quick reference) array.length
- read-only attribute of an array that stores the number of elements
- subscript (also "index")
- integer value in brackets [ ] that specifies an element of an array
ArrayIndexOutOfBoundsException
- error raised when trying to access
a[i]
wherei < 0
ori >= a.length
Part 1: Sequentially accessing an array
Whenever you are asked to do something to your array and then print it, you should finish the update step first and then have a separate loop to do the printing.
- In the
main
method, create a single array of integers that is6
elements long. - Initialize each of the array elements to the value
-1
using a loop of your choice. - In another loop, print each element of the array with messages that look like:
array[0] = -1 array[1] = -1 ...
- Add code to change the value of each element of the array to its subscript. For example,
array[3]
should hold the value3
. - Print the new contents of the array with the same message format as step 3. (You may copy and paste the code from step 3. Your program should now print both versions of the array.)
- add code to re-initialize your array contents to all zeros.
- Print the string
Array Play
(on its own line) to conclude Part 1.
Part 2: Randomly accessing an array
- Download
Die.class for use in this Part and later. Assuming you created the
Prerequisite File Hierarchy
, you should then:
- Create a new directory (call it something about this activity, e.g.
lab04
) in theprovided
directory. - move the
Die.class
file you downloaded into the newly directory. - In Eclipse, right-click on the the current Java Project you’re using, and choose
Properties...
(last entry in thecontext menu
). - in the left pane, select
Java Build Path
. - in the right pane, select the tab, labeled
Libraries
. - click the
Classpath
item in the center pane. - click the button no the far right, labeled
Add External Class Folder...
. - navigate to the
provided
directory and select thelab04
directory. - Click
Apply and Close
.
- Create a new directory (call it something about this activity, e.g.
- Create a new Die object.
- (Refer to
the Die javadoc for the documentation for the class
Die
.) - If the compiler insists
Die cannot be resolved to a type
, it’s likely you made an error in the preceding steps to add the class folder, or need to double-check the 🛑🧐 Stop and check after the background section above.
- (Refer to
the Die javadoc for the documentation for the class
- Create a loop that will iterate at least 100 times. In the loop body:
- Roll the die. (Don’t create a new object, just roll it again.)
- Based on the result of the roll, increment the corresponding cell of your array. The value of each array element should be the number of times that roll is made.
- After the loop finishes, print the results of the simulation. For example, if the array holds
{20, 17, 19, 15, 12, 17}
you would output (notice the empty line between each message):1 was rolled 20 times. 2 was rolled 17 times. ...
Part 3: Working with multiple arrays
For this exercise, you will need two arrays of double values (I think I’ll name mine, minogue
and oLeary
).
- Use an array initializer { } to assign one of the arrays to
10
double
values starting at0.0
with each element1.0
more than the previous (ending with the last element being set to9.0
). - Instantiate the other array to store 10 elements, but do not initialize the contents yet.
- Print the contents of both arrays side by side on your screen, but first label this output by printing
Before
.- format the output as follows:
Before 0 A1 = 0.0 A2 = 0.0 1 A1 = 1.0 A2 = 0.0 ...
- Copy the contents of the first array into the second, then print their contents again. Label this output
After
. - Finally, change the element at index
0
of the first array to99.0
and the element at index5
of the second array to99.0
. - Again, print the contents of the two arrays side by side. Label this output
After Change
. - Check that the contents of the two arrays are indeed different. If not, make the appropriate corrections.
This is the expected output file for ArrayPlay.exp
Part 4: Refactoring
In the lab so far, you were required to print all of the contents of an array several different times. Perhaps (as the instructions permitted) you did this by copying and pasting the same code several times. This is a bad practice. Instead, you should write a method that prints the contents of an array. This method should take the array as a parameter and print the contents of the array. You should then call this method from the appropriate places in your code.
🤔Why?
- Why is it a bad practice to copy and paste?
- Why is it better to write a method?
- What are the advantages and disadvantages of copy/paste vs. creating and invoking a method?
- Consider saving a copy of
ArrayPlay.java
as you have it now somewhere else, and after completing and submitting this lab, change the behavior of the class up to this point to have a different format of message when printing. Compare that to the code you submit to Gradescope for this activity.
+printArray(a: int[])
Write a (static
and void
) method named printArray
that prints the contents of an array. The method should take the array as a parameter and print the contents of the array following the message format from Part 1. If the array is null
, it should print the String null
. If the array is empty, it should not print anything. You should then replace the code in your main
method that prints the contents of the array with a call to this method.
+formMessage(a: int[], index: int, format: String): String
Write a static
method named formMessage
that defines 3 formal parameters:
a
is an array of integers.index
is an integer that is the index of the array.format
is aString
that is a format string for the message. and from these parameters, returns aString
that is the message for the provided array’s element at positionindex
, with the givenformat
. For example, ifa
holds{20, 17, 19, 15, 12, 17}
,index
is3
, andformat
isarray[%d] = %d\n
, the message would be:array[3] = 15\n
. You should then replace the code in yourprintArray
method that constructs theString
to print with a call to this method. Note:- you should not print anything in this method.
- if the provided array is null, you should return the String
null
. - if the provided index is out of bounds, you should return the String
index out of bounds
.
+printArray(a: double[], b: double[])
Overload the printArray
method to take two arrays of doubles as parameters. The method should print the contents of the two arrays side by side, with the first array’s elements on the left and the second array’s elements on the right. The method should print the contents of the arrays following the message format from Part 3. If either array is null
, it should print the String null
. If either array is empty, or if the arrays are not the same length as each other, it should not print anything. You should then replace the code in your main
method that prints the contents of the arrays with a call to this method.
Submitting
Submit your final ArrayPlay.java
file to Gradescope.
Acknowledgements 🙏
This lab is with thanks to at least Alvin Chao (, but likely also Nathan Sprague and David Bernstein ).
5 - Multi-Dimensional Arrays Lab
Introduction
The goal of this lab is to gain experience working with two-dimensional arrays.
Instructions
- Create a new Eclipse project. Download and import the files Array2D.java and Array2DTest.java .
- Complete the unfinished methods in
Array2D.java
according to the provided JavaDoc comments. - Once all of your methods are implemented and tested, submit your finished work through Gradescope. There is no limit on the number of submissions.
⚠️ Note
Notice that the methods inArray2D.java
use a return
value of Double.MIN_VALUE
to indicate an error
condition. Typically, it would make more sense to design these methods
to throw exceptions.6 - ArrayList Lab
Introduction
The goal of this lab is to practice working with ArrayList
s by
completing a Document
class that represents a text
document as an ArrayList
of String
objects,
where each entry in the ArrayList
corresponds to a single
line of text.
This lab was designed as a command-line Java application, so you should consider compiling and executing in the terminal. As a reminder, you can follow the following steps to compile and execute a Java program in a Unix-style terminal:
cd the_directory_where_your_code_is_stored
javac File1.java File2.java ...
java File1
This example assumes that File1.java
contains the
main method for the application.
Resources
Useful API documents:
Files
The following files are provided:
Document.java UNFINISHED
DocumentTestDriver.java This is a simple driver class for testing
Document.java
. Take a minute to look over this code to get a better idea of the expected behavior.Editor.java This is an editor application that provides a command-line interface to the
Document
class.
Instructions
Download the files above and complete Document.java
so that all methods conform to the Javadoc comments. Test your completed
file by running the two provided application programs.
Your solution should use only enhanced for loops.
Submitting
Submit your completed version of Document.java
through Gradescope . You have an unlimited
number of submissions. If you have trouble with your submission, you
may find it helpful to look at the JUnit submission tests:
DocumentTest.java
.
7 - File I/O Lab
Introduction
The goal of this lab is to practice working with Java file I/O by
adding load/save functionality to the Document
class you
completed in a previous lab.
The code for this lab was originally designed as a command-line Java application so you may want to run it in the terminal. It is also fine to run it through the Eclipse console.
As a reminder, you can follow the following steps to compile and execute a Java program in a Linux/OSX terminal:
cd the_directory_where_your_code_is_stored
javac File1.java File2.java ...
java File1
This example assumes that File1.java
contains the
main method for the application.
Resources
Useful API documents:
Files
The following unfinished files are provided:
Instructions - Part 1
Download the files above and complete Document.java
so that the unfinished methods conform to the Javadoc comments. Test
your completed file by running the provided application program.
Instructions - Part 2
The current implementation of the Editor
class does not
include code for handling exceptions related to file I/O: If you
attempt to open a non-existent file, or to write a file to a location
where do not have permission, the application will crash.
Modify Editor.java
by removing
all throws
declarations and adding try/catch blocks
to saveFile
and loadFile
. If an exception
occurs, these methods should print a helpful error message and
then allow execution to proceed normally.
Instructions - Part 3 (If Time)
Most text editors allow you to save the current document without re-entering the file name. Modify the Editor class so that it provides this functionality. If the file is already associated with a file name (because of an earlier save or load) then the “s” command should now save the current version without prompting for a file name. You should also add a save-as command to allow specifying a file name even if one already exists. Use “w” to trigger save-as. Make sure to update the help message to conform to the new functionality.
Submitting
Submit your completed versions of Document.java
and Editor.java
to Gradescope . You have an unlimited
number of submissions. If you have trouble with your submission, you
may find it helpful to look at the JUnit submission tests:
8 - Design Lab - Bob's Grocery Mart
Introduction
Bob’s Grocery Mart has 73 locations distributed across 12 States. Bob would like to increase the profitability of his stores by improving cashier scheduling: If too few cashiers are scheduled, customers become frustrated and may not return to the store. With too many cashiers, Bob pays more wages than necessary. You have been tasked with writing a checkout simulation program that will be used to analyze the impact of increasing or decreasing the number of cashiers.
Program Specification
Your program should simulate the activity of any number of staffed check-out aisles in a Bob’s Grocery Mart. The simulation will proceed in one-second time steps. It takes between one and five seconds for a cashier to process a single object. During each one-second interval there is a .5% chance that a new customer will finish shopping and enter a checkout aisle. Customers purchase between 1-100 items. If there are any empty aisles, customers choose one arbitrarily. If all aisles are occupied, customers choose the aisle with the shortest line. The program should simulate a single eight hour shift. At the end of the simulation the program should display:
- The total number of customers served.
- The average wait time across all customers.
- The maximum wait time for any individual customer.
Design Steps
- Highlight all of the nouns and noun phrases from the program specification above. Circle entries that are good candidates for classes and cross out entries that are duplicates or do not need to be represented in the program. Any remaining highlighted words should represent entities that do need to be represented in the program but should not be classes.
- Draw a largish UML box for each of the classes that you selected in the previous step. In the upper part of the box, list an appropriate set of attributes along with their types. Think about persistent values that constitute the state of an object vs. computed values that make more sense as local variables.
- In the lower part of the box, List the necessary constructors for your Classes, along with the required arguments. Does it make sense to have a default constructor? Are there classes that may need more than one constructor?
- For each class, define an appropriate set of methods including getters
and setters,
equals
andtoString
, and others. Think about the parameters and return types for each method. Should all methods be public, or are there some that are only needed within the class? - Once you are satisfied with your design and you have cleared it with your instructor submit it as a pdf to Canvas.
If Time
- Create .java files for each of your proposed classes. Include Javadocs containing the authors, version, and a description of the class. Add the necessary instance variables and method stubs to your classes. You do not need to provide the code for your methods, but you should include a brief Javadoc comment for each. Make sure that your .java files compile. Now you have completed your first Object Oriented Design!
9 - Inheritance Lab
Inheritance in Bob’s Grocery Mart
Introduction
The Bob's Grocery Mart Simulator has been a big success. Cashiers are being scheduled more efficiently, and profits are up. However, Bob is concerned that some important factors are not captured by the current program. In particular, the simulation allows checkout lines to grow arbitrarily long. Beyond a certain length, real customers would choose to leave the store rather than waiting.
Your goal for this assignment is to modify the simulation so that customers will refuse to enter a checkout line if that line has reached some maximum capacity.
Instructions
- Download the following files:
- Take a few minutes to look over the existing classes to get a feel for
how they work. Try executing
MartDriver
several times to see what the output looks like.- What is the average wait time with 12 cashiers?
- What is the average wait time with 6 cashiers?
- Create a new class that extends
Aisle
. As always, you should think carefully about what to name your class. One common convention in naming subclasses is to prefix the superclass name with an adjective the clarifies how the subclass specializes the superclass. For example, theCar
class might have a subclass namedElectricCar
. We recommended you call your classLimitedAisle
.- Your new class must:
- Override the
addCustomer
method so that new customers are added only if the line is below some maximum capacity. - Track the number of customers that refuse to wait because the line was too long.
- Override the
- Your new class must:
- Modify the simulation class so that it uses your new
LimitedAisle
subclass: everywhere “Aisle” appears in the existing class should be replaced with your “LimitedAisle”. You should modify the simulation constructor so that it accepts a “maximum length” parameter that describes maximum allowable length for a checkout line. - Modify the
printResults
method so that it reports the total number of customers that left the store because of excessive line lengths. - Test your new simulation using eight aisles, while keeping the other parameters at their default values. How many customers depart when maximum line length is 1? 5?, 20? (INCLUDE AN ANSWER TO THIS QUESTION IN A COMMENT AT THE BOTTOM OF YOUR NEW CLASS. )
- Submit your completed
LimitedAisle
subclass and modifiedMartSimulation
in Gradescope. It is your responsibility to make sure that the behavior is correct as the submission only checks if your code compiles. If you aren’t sure, check with your instructor or a TA. - If you have extra time:
- Each time this simulation is
executed, there is a different result. It might be valuable to know
the average results across many different simulation runs. Add a new
method to the
MartSimulation
class with the signature:public void runMany(int numRuns)
This method should run the simulation the indicated number of times, and calculate averages for each of the quantities reported.
- Each time this simulation is
executed, there is a different result. It might be valuable to know
the average results across many different simulation runs. Add a new
method to the
- If you have even more time:
It would be useful to be able to systematically adjust simulation parameters in small increments to see what effect this has on wait times etc. Add a loop to your
main
that systematically increases the maximum line length from 0 to 100. For each increment, run your simulation 100 times and report the average results.
10 - Enum Lab
Experimenting with Enumerated Types
📖 Prereq
Be sure to consult the Java Enumerated Types reading on the JMU CS Wiki . You may also enjoy Dr. Bernstein's slides on Developing Enumerated Types With Examples in JavaFor this lab you should:
- Ensure you know how to provide a command line argument for your program .
- complete the steps outlined on Dr. Bernstein’s Lab: Experimenting with Enumerated Types
- Submit your completed
ShowAQI.java
andAirQuality.java
files to the Lab 10 assignment on Gradescope.
11 - Code Review Lab
Find this lab’s instructions in your Canvas course. It’s looking back at some reference implementations and noticing differences between those and your own code.
12 - Polymorphism Lab
This is a “Bernstein Lab”. You can find the current version here .
⚠️ Note
While this course is in the intro sequence, it’s not the beginning of it. Your instructors are working to support your metacognitive development. You’ve survived over a decade of compulsory education where if you didn’t show up police might turn up asking your guardians about it. All of your academic program in University is elective. You don’t have to be here (but we’re so glad you are!). This kind of assignment intentionally has all of the answers built in. There is no way to check whether you have done it. Most of the assignments in this course (and likely this whole major/minor program) are formative (i.e. rather than summative , like your final exams). You’re moving from doing assignments because you had to if you wanted good grades, to now being in a position where mathematically you may be able to forgo a large number of assignments and still have the possibility of making a good grade. You now are choosing to do these assignments that are of little mathematic significance to your final course grade. You are trusting that your instructors have assigned them because we believe they will help reveal misconceptions or conceptual gaps that you may have. This prepares you for the less structured world beyond these academic programs where you are obligated to very little, and you must choose how to spend your time to be or become the self you wish you were.13 - Midterm Exam Practice Lab
Saving and Loading Shapes (30pts)
Download the following files:
- Rectangle.java (finished) - A simple rectangle class that stores width and height as integers.
- Square.java (finished) - A subclass of
Rectangle
. ASquare
is-aRectangle
with equal width and height. - ShapeUtils.java (UNFINISHED) - File I/O methods. This is the only file you will need to submit.
- ShapeUtilsTest.java - Submission tests, in case you want to test locally before submitting.
- shapes.txt - Sample text file illustrating the correct file format.
Finish the two unfinished methods in ShapeUtils.java
so that they conform to the provided Javadoc comments.
Submit your completed ShapeUtils.java
via Gradescope .
14 - PA3C Jump-start Lab
Overview
Our goal for today is to help you to get a non-zero submission on Gradescope for PA3C.
Stub out all (remaining) classes for PA3
Follow the course staff’s guidance for quickly stubbing all the classes.
Ensure that all classes compile
- Once you have stubbed out all your classes, ensure that they all pass Checkstyle’s checks and that there are no compiler errors. ✅
- ⬇️ Download the provided test classes, add them to your project, and ensure that they all compile in the project with your classes (if they don’t correct your classes 😅).
Get at least 1 Unit test to pass
- Right-click on your project and run the JUnit tests.
- Probably many will fail, since you haven’t implemented any of the methods yet.
- work to get at least 1 passing for this lab.
15 - Interfaces Lab
Introduction
Your goal for this assignment is to modify the Bob’s simulation in two ways: by adding a SortedAisle class, and by making it possible for the user to select the aisle type at run time.
Instructions
Interface
Download the following files:
Create a new class SortedAisle
that extends Aisle. Your new class should override the addCustomer
method so that every time a new customer is added, the entire list of customers is sorted. This way, the customer with the fewest items is always moved to the front. This type of aisle will model the effect of friendly customers that let other customers “cut” if they have fewer items.
- Implement the constructor. It should be only one line of code.
- In
Aisle.java
, make theline
attribute visible to SortedAisle. (Hint: Don’t makeline
private to Aisle. But don’t make it public either. - In
SortedAisle.java
, override theaddCustomer
method so that every time a new customer is added, the line of customers is sorted. - Use the Collections.sort method to sort your ArrayList. Since this method only works when the items in the list implement the Comparable interface, you will also need to modify the
Customer
class to implementComparable
.
Comparable
is a generic interface. This means you can use it like this:
public class MyClass implements Comparable<MyClass>
or like this (not recommended):
public class MyClass implements Comparable
In the former class your compareTo
method must take an argument of type MyClass
in the latter it must take an argument of type Object
.
Once you have completed your SortedAisle
class modify MartSimulation
so that it uses SortedAisle
s instead of LimitedAisle
s. (Simply find and replace LimitedAisle with SortedAisle.)
- Notice the compiler error when calling
getLeftStore
. That method was added toLimitedAisle
to get the number of customers who left the store.SortedAisle
doesn’t have such a method. - Implement a new
getLeftStore
method inAisle
that simply returns 0. (By default, no customers leave the store.)SortedAisle
will inherit that method, andLimitedAisle
will override it.
Run the simulation a few times, and confirm that your code is working. Using SortedAisle
should result in relatively short average waits, but very long longest waits. People with lots of items will tend to get stuck at the end of the line while others continually cut in front of them.
Polymporphism
It is unfortunate that the current version of the simulation requires the code to be modified and recompiled when we want to change the aisle type used in the simulation. Modify the file MartDriver
and MartSimulation
classes to allow the user to select any of the three aisle types at run time. Execute the simulation several times to see the effect of changing aisle types.
Submit Customer.java
, MartDriver.java
, and SortedAisle.java
to Gradescope .
16 - Object-Oriented Design Lab
Introduction
Frogger 🐸 is a classic 2D sprite-based1 video game from the
1980’s (which you can play right now in your browser! 😁 ). The goal for this exercise is to design an appropriate class
hierarchy for implementing this game in Java.
You may assume that you have access to a drawing library that provides
methods like the following:
StdDraw.drawImage(ImageObject image, double xPosition, double yPosition)
You may also assume that you have access to image files for each of the game entities and the game background.
Instructions
Carefully read the game specification below, underlining words that may correspond to classes in your finished hierarchy.
Brainstorm a class hierarchy that would allow you to implement the game logic with a minimum of code duplication. Look for opportunities to take advantage of polymorphism and dynamic binding. Make use of interfaces and abstract classes where appropriate.
Draw a “syntactically correct” UML diagram representing your design. You should include all public and protected methods, including constructors, as well as all instance variables.
Game Specification
The following screen-shot and description of game play are taken from the Frogger Wikipedia page :
The game starts with three, five, or seven frogs (lives), depending on the settings used by the operator. The player guides a frog which starts at the bottom of the screen, to his home in one of 5 slots at the top of the screen. The lower half of the screen contains a road with motor vehicles, which in various versions include cars, trucks, buses, dune buggies, bulldozers, vans, taxis, bicyclists, and/or motorcycles, speeding along it horizontally. The upper half of the screen consists of a river with logs, alligators, and turtles, all moving horizontally across the screen. The very top of the screen contains five “frog homes” which are the destinations for each frog. Every level is timed; the player must act quickly to finish each level before the time expires.
The only player control is the 4 direction joystick used to navigate the frog; each push in a direction causes the frog to hop once in that direction. On the bottom half of the screen, the player must successfully guide the frog between opposing lanes of trucks, cars, and other vehicles, to avoid becoming roadkill.
The middle of the screen, after the road, contains a median where the player must prepare to navigate the river.
By jumping on swiftly moving logs and the backs of turtles and alligators except the alligator jaws, the player can guide his or her frog safely to one of the empty lily pads. The player must avoid alligators sticking out at one of the five “frog homes”, snakes, and otters in the river, but may catch bugs or escort a frog friend for bonuses. When all five frogs are directed home, the game progresses to the next, level with an increased difficulty. After five levels, the game gets briefly easier yet again gets progressively harder to the next fifth level.
1 A sprite is a small image which may be moved.
16.1 - Class Design Tips
Class Design Tips
- Classes and instance variables should be nouns
- Classes should be singular unless they represent a collection. (Multiple ones come from multiple instantiations.)
- Question classes of just one instantiation. (e.g. should it be a class at all?)
- Methods should be verbs that describe behaviors/responsibilities.
- Use inheritance to add or change behaviors.
- Other differences can be managed by instance variable values most of the time. Add additional instance variables in subclass only if needed for new behavior, otherwise maybe it belongs in super class?
- Use inheritance to avoid code (and instance variable) duplication.
- If superclass has it, don’t redundantly add it to sub class.
- Use an interface to specify behavior (and anything needed for that behavior) that is common across classes without an is-a relationship.
- Names matter.
17 - Recursion in CodingBat Lab
Introduction
The goal of today’s lab is to practice writing recursive methods by competing as many CodingBat recursion exercises as possible in 50 minutes.
Creating an Account
Note 📝
If you:
- already have a CodingBat account, AND
- this semester you have already linked your coding bat account to your professor’s, AND
- you manage to login successfully to this existing account (i.e. many have reported the “forgot password” feature of this website not working for them 😞)
Then, you can of course skip the “Creating and Account” steps.
- Navigate to the CodingBat web-site
- If you already have an account, log in. Otherwise, use the “create account” link on the upper right portion of the page to create a new account.
- Please choose your official school email address unless you’re creating a second codingbat account due to being locked out.
- Once your account is created, click on the <code>prefs</code> link and:
- enter the email address of you instructor in the
Share To
box at the bottom of the page. (e.g.duanzx@jmu.edu
,stewarmc@jmu.edu
,wangid@jmu.edu
, orweikleda@jmu.edu
) and click theShare
button - enter your names in the
Memo
box and click theUpdate Memo
button.
- enter the email address of you instructor in the
- In principle, it should be possible to grade your work through the sharing mechanism from the previous step. Just in case that doesn’t work you should save copies of your solutions to a text file.
Advice
- Several of the exercises below involve string manipulation. Here are some
helpful String
methods:
someString.length()
returns the number of characters in a string.someString.substring(0, 1)
returns the the first letter ofsomeString
.someString.substring(1)
returns everything after the first letter. This will return the empty string ("") if the string only has one letter.
- Other methods involve processing integers one digit at a time. Here we can use the
/
and%
operators:int num = 745; int last = num % 10; // evaluates to 5, the last digit of 745. int rest = num / 10; // evaluates to 74, all of the digits except the last.
Start Programming
You are not required to work on these in order, but they do build on each other to some extent. If the exercises from Group 1 seem too easy, feel free to skip ahead to Group 2. To receive credit for the lab you must finish at least four exercises beyond “bunnyEars”.
Don’t use the “next” button to move between exercises: after you have completed an exercise come back to this page and select the next one.
Group 1
- bunnyEars (Includes hints and solution)
- count7
- sumDigits
- array6
- countX
- changeXY
- endX
- nestParen
- parenBit
Group 2
Submitting
By sharing your codingbat account with your instructor as outlined above, your instructor will be able to see your work. As long as you also followed the instructions about the Memo
field in coding bat, your instructor will be able to award you credit for the lab.
For full credit, you must finish at least four exercises beyond “bunnyEars”.
18 - Collections Lab
Introduction
Your goal in this lab is to complete the unfinished methods: CollectionExercises.java
The Gradescope JUnit tests are provided for your convenience: CollectionExercisesTest.java
For each method, you should first take a minute to think about the problem in order to select an appropriate collection type (or types) to use in your solution. The following documentation might be helpful.
You should take full advantage of the functionality provided by the collection classes to make your solutions as concise and efficient as possible. For example, the Collection
interface provides an addAll
method that makes it possible to add all of the elements of one collection to another using a single method call. Where appropriate, you should use that method rather than creating a loop that repeatedly calls the add
method.
Your solutions for these exercises must satisfy the following requirements:
- You may not use indexed for loops. Use only for-each loops or iterators, as appropriate.
- None of your methods may include nested loops. Nested loops generally take a long time to iterate over large collections. (You will look at this more formally in CS 240).
Submitting
Submit your completed file to Gradescope. You may submit as many times as you like.
19 - Maps in CodingBat Lab
Introduction
The goal of today’s lab is to practice working with Maps by competing as many CodingBat exercises as possible in 50 minutes.
Creating an Account
Note 📝
If you:
- already have a CodingBat account, AND
- this semester you have already linked your coding bat account to your professor’s, AND
- you manage to login successfully to this existing account (i.e. many have reported the “forgot password” feature of this website not working for them 😞)
Then, you can of course skip the “Creating and Account” steps.
- Navigate to the CodingBat web-site
- If you already have an account, log in. Otherwise, use the “create account” link on the upper right portion of the page to create a new account.
- Please choose your official school email address unless you’re creating a second codingbat account due to being locked out.
- Once your account is created, click on the prefs link and:
- enter the email address of you instructor in the
Share To
box at the bottom of the page. (e.g.duanzx@jmu.edu
,stewarmc@jmu.edu
,wangid@jmu.edu
, orweikleda@jmu.edu
) and click theShare
button - enter your names in the
Memo
box and click theUpdate Memo
button.
- enter the email address of you instructor in the
- In principle, it should be possible to grade your work through the sharing mechanism from the previous step. Just in case that doesn’t work you should save copies of your solutions to a text file.
Start Programming
You are not required to work on these in order, but they do build on each other to some extent. If the exercises from Group 1 below seem too easy, feel free to skip ahead to Group 2. To receive credit for the lab you must finish at least two from Group 1, and at least two beyond the required two from Group 2.
Don’t use the “next” button to move between exercises: after you have completed an exercise come back to this page and select the next one.
Group 1
Group 2
Submitting
By sharing your codingbat account with your instructor as outlined above, your instructor will be able to see your work. As long as you also followed the instructions about the Memo
field in coding bat, your instructor will be able to award you credit for the lab.
20 - Tracing Recursion Lab
Introduction
Follow the directions at Dr. Bernstein's Gaining Experience Tracing Recursive Methods Lab .
Note
When you get to section 2, instead of using cards, use one of the paper tracing methods either shown in class or on the videos in Canvas to trace each method. There is paper provided for this purpose.Submitting
Turn in your tracing of Searcher.java
only as a pdf to the corresponding Canvas assignment in your course.
21 - Recursive Structures Lab
Introduction
The goal of this lab is to practice using recursion to interact with recursively structured data. One example of a recursively structured collection is the file system of a computer. A file system is made up of directories, each of which may contain additional directories, and so forth.
Please watch this 6-minute video by Gayle Laakmann McDowell :
Source Files
The following files are provided:
- DirectorySearcher.java – This (unfinished) class is responsible for recursively traversing a directory tree starting from a designated directory.
- DirectoryDriver.java – This is a driver class for executing the methods provided by
DirectorySearcher
. As currently written, themain
method uses aDirectorySearcher
to list the contents of the current directory.
Instructions
- Download and test the two files above. Make sure you understand how the existing code works.
- if you run it as it is when you first download it, you should see something like:
bin (Directory) .classpath .settings (Directory) .project src (Directory)
- if you run it as it is when you first download it, you should see something like:
- Complete the
listDirectories
(plural) method of theDirectorySearcher
class. Test your method by modifying the driver so that it calls this method instead oflistDirectory
(singular).- Your solution should print a
"/"
after each directory name and indent the files under each directory. For example,- if the starting path is
"."
, the output might look like this:./ bin/ DirectorySearcher.class DirectoryDriver.class .classpath .settings/ org.eclipse.core.resources.prefs .project src/ DirectorySearcher.java DirectoryDriver.java
- if the starting path is
"../PA4"
, the output might look like this:PA4/ bin/ GameUtils.class AsteroidsGame.class Bullet.class Pose.class Asteroid.class Enemy.class Vector2D.class Ship.class AsteroidSize.class Playable.class Point.class Saucer.class Drawable.class Updatable.class GameElement.class StdDraw$RetinaImageIcon.class GameDriver.class StdDraw.class Star.class NumericDisplay.class .classpath .settings/ org.eclipse.core.resources.prefs .project src/ Playable.java Drawable.java Saucer.java Star.java Enemy.java Point.java AsteroidSize.java Ship.java GameElement.java GameUtils.java AsteroidsGame.java Bullet.java GameDriver.java NumericDisplay.java Pose.java Asteroid.java Vector2D.java StdDraw.java Updatable.java
- if the starting path is
- Your solution should print a
- Complete the
searchDirectories
method of theDirectorySearcher
class. Test your method by modifying the driver; search for different patterns to make sure it works.- Your solution should print the path to each file that is found. (Just print the File object itself, rather than calling getName.) For example, if the search string is
"se"
, the output might look like this:../PA4/bin/Pose.class ../PA4/.settings ../PA4/.settings/org.eclipse.core.resources.prefs ../PA4/src/Pose.java
- while if you searched for empty string
""
, the output might be:../PA4 ../PA4/.DS_Store ../PA4/bin ../PA4/bin/GameUtils.class ../PA4/bin/AsteroidsGame.class ../PA4/bin/Bullet.class ../PA4/bin/Pose.class ../PA4/bin/Asteroid.class ../PA4/bin/Enemy.class ../PA4/bin/Vector2D.class ../PA4/bin/Ship.class ../PA4/bin/AsteroidSize.class ../PA4/bin/Playable.class ../PA4/bin/Point.class ../PA4/bin/Saucer.class ../PA4/bin/Drawable.class ../PA4/bin/Updatable.class ../PA4/bin/GameElement.class ../PA4/bin/StdDraw$RetinaImageIcon.class ../PA4/bin/GameDriver.class ../PA4/bin/StdDraw.class ../PA4/bin/Star.class ../PA4/bin/NumericDisplay.class ../PA4/.classpath ../PA4/.settings ../PA4/.settings/org.eclipse.core.resources.prefs ../PA4/.project ../PA4/src ../PA4/src/Playable.java ../PA4/src/Drawable.java ../PA4/src/Saucer.java ../PA4/src/Star.java ../PA4/src/Enemy.java ../PA4/src/Point.java ../PA4/src/AsteroidSize.java ../PA4/src/Ship.java ../PA4/src/GameElement.java ../PA4/src/GameUtils.java ../PA4/src/AsteroidsGame.java ../PA4/src/Bullet.java ../PA4/src/GameDriver.java ../PA4/src/NumericDisplay.java ../PA4/src/Pose.java ../PA4/src/Asteroid.java ../PA4/src/Vector2D.java ../PA4/src/StdDraw.java ../PA4/src/Updatable.java
- Your solution should print the path to each file that is found. (Just print the File object itself, rather than calling getName.) For example, if the search string is
- Submit your completed
DirectorySearcher.java
file via GradeScope.
22 - *eroids Lab
Benefits of Polymorphism
Let’s make an expansion to the Asteroids Game that we built for PA4. Let’s add some new feature(s) that we like, and we’ll see how some parts of the design facilitate this, and possibly how some design choices make it more difficult.
Standing on the Shoulders of Giants
You’ve already done great work to complete PA4. For this lab, make a new Java Project in Eclipse, and begin by:
- downloading and reviewing 📄 the professors' reference solution (slightly updated here compared with earlier in the semester) and use this code for this lab or
- copying your own .java files from PA4 into the Java Project for this lab
⏲️ Take a minute
Take a minute and review the code to remind yourself about how things worked. The UML Diagram from P4 should still be mostly valid. **In general, you should be creating a new subclass of the things you want to change, and not modify existing code except AsteroidsGame slightly to invoke your new class’s constructor.Choose your own Adventure
What you think would be most interesting to modify about this game will likely differ from others. That’s fun! …and difficult to write an autograder for. You will not submit to gradescope for this lab, but will submit to Canvas if your instructor requires it. We have imagined a few things you might enjoy considering as the starting point for your own expansion. You are welcome, but not required to use any of these:
New Feature: Color Changing…
There’s a lot of fun to be had with changing some colors around.
- To change colors, you’ll need to change the
StdDraw
pen color before drawing each element, and - if you don’t want a change of color in drawing one instance of one object to persist for otherDrawable
s - set it back (to white) after drawing each element. - To cycle between different colors, consider adding a
counter
that gets incremented with eachdraw
similar to how it works withBullet
and itsupdate
method. Then, use the value of the counter to determine when to change color and/or which color to use.- if the cycle will be between more than 2 colors, it might be best to put the colors in an array, and use the counter as an index into the array (mod
%
being your friend here).
- if the cycle will be between more than 2 colors, it might be best to put the colors in an array, and use the counter as an index into the array (mod
Twinkling Stars
Perhaps with some random frequency, it would be neat if the stars “twinkled”…
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Star. (I called mine TwinklingStar.)
- Override draw and every so often, either don't super.draw or change the pen color before and after you do.
New Feature: Flashy Saucers
Saucers are scary! 😱 But they don’t look it. What if they flashed red?
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Saucer. (I called mine FlashingSaucer.)
- Override draw and every so often, change the pen color before and after you invoke super.draw.
New Feature: Rainbow Bullets
It’s dangerous to go alone, take this! 🌈 The bullets are the only defense the player has, they’re already fabulous, they should look it.
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Bullet. (I called mine RainbowBullet.)
- Add an instance variable that is an array of Color objects
- Override draw and every so often, change the pen color before and after you invoke super.draw.
New Feature: Rainbow Ship
This puny little vessel is the only thing standing between the player and certain doom of the cold void of space. It’s basically a superhero space unicorn 🦄, it should look like one.
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Ship. (I called mine RainbowShip.)
- Add an instance variable that's an array of Color objects
- Override draw and every so often, change the pen color before and after you invoke super.draw to the next color in the array.
New Feature: Face-steroids
At this point in the semester you may be interested in blowing 💨 off some steam 😤. Consider making a specialization of the Asteroid
class that looks a little different than the circles from PA4… Feel free to find your own image file or to grab one of these (you should right click on the image and choose “save image as..”):
Implementation Suggestions
- Begin from a ton of existing code as described in Standing on the Shoulders of Giants above.
- Create a new class that extends
Asteroid
. (Call it what you like, I tend to overdo it on portmanteaus if you haven’t noticed, so mine wasFacsteroid
.) - add a String field to the new class to hold the filename of the image you want to use.
- add 2 double fields to hold the scaled width and height of the image.
- implement the required constructor to invoke the super constructor (it will have to have the same parameter as the super constructor).
- either hardcode the image filename or add a parameter to your constructor to pass it in.
- Leverage
GameDriver.scaledWidthHeight
to compute the values required to set the scaled width and height fields.
- override the
draw()
method to draw the image (take a look at the variousStdDraw.picture
overloads). - What changes are necessary to
AsteroidsGame
?
New Feature: Homing Saucer
A Homing Saucer
could chase the Ship
rather than moving randomly.
Implementation Suggestions
- Begin from a ton of existing code as described in Standing on the Shoulders of Giants above.
- Create a new class that extends
Saucer
. (I called mineHomingSaucer
.) - Add a constructor that has a
GameElement
parameter which will be the target of the homing behavior. - Override the
newHeading
method to take advantage of theGameDriver.headingAb
rather than being random. - What changes are necessary to
AsteroidsGame
?
New Feature: Shrinking Asteroid
Rather than being destroyed by a single shot, a ShrinkingAsteroid
that was of an AsteroidSize > AsteroidSize.SMALL
could be reduced to the next smaller size (and then the smallest size would be destroyed as in the existing Asteroid
class).
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Asteroid. (I called mine ShrinkingAsteroid.)
- Implement a constructor that takes the required AsteroidSize you need to invoke the superconstructor, but consider adding a field to your ShrinkingAsteroid to keep a reference to this AsteroidSize.
- Override setDestroyed. It should only do the same behavior as the super's when this ShrinkingAsteroid's size is AsteroidSize.SMALL ...
New Feature: Bomb
This is perhaps the second-most difficult of the ideas listed here. Bomb
could be a specialization of Bullet
that is launched by the Ship
when a key is pressed (I went with b) and the player can detonate with the key press (I chose the same key). When detonated, the bomb could start increasing in radius until it reaches a maximum size, and then, any Asteroid
that is within the radius of the bomb when it is detonated would be destroyed.
Implementation Hints
Begin from a ton of existing code as described in Standing on the Shoulders of Giants above...
- Create a new class that extends Bullet. (I called mine Bomb.)
- Add a field to the bomb to track whether this bomb has been detonated.
- Add a constant to the bomb to limit its duration, but make it last longer than a Bullet.
- Add a constant to the bomb to limit its explosion radius.
- Implement a constructor that takes the required Pose you need to invoke the superconstructor, and initializes the new instance variable that tracks whether it's been detonated.
- Add a getter for the new field
- Add a mutator for the new field called detonate that takes no arguments (these bombs are not possible to un-detonate, at least not the way I made them)
- Override setDestroyed. It should only do the same behavior as the super's when this Bomb is undetonated
- Override update. It should start by performing super's update, but then if it is undetonated and it is older than the bomb's max duration, update the destroyed property to true. Also, if the bomb is detonated, ignore the duration, and increment the radius, only setting destroyed to true when it's reached its maximum explosion radius
- Update the AsteroidsGame.handleKeyboardInput method to watch for whatever key you like to be pressed
- Decide how many bombs a player can have (unlimited? only 3?) and how many they can launch at the same time (only 1 allowed in game a t a time? a few? unlimited???)
- Add the necessary code to AsteroidsGame to implement your decisions.
New Feature: Asteroids Split
This is perhaps the most difficult of the ideas listed here. The idea would be that if a SplittingAsteroid
of size AsteroidSize.LARGE
was shot, it would be replaced by two SplittingAsteroid
s of size AsteroidSize.MEDIUM
. If a SplittingAsteroid
of size AsteroidSize.MEDIUM
was shot, it would be replaced by two SplittingAsteroid
s of size AsteroidSize.SMALL
. If a SplittingAsteroid
of size AsteroidSize.SMALL
was shot, it would be destroyed.
Implementation Suggestions
Because it’s during the “destroying elements” phase of the game loop (see AsteroidsGame.update
), that this feature requires the creation of new enemies, it’s difficult to avoid concurrent modification exceptions. One way to avoid this is to create a new collection to temporarily hold the new enemies and only remove them from this collection (while adding to the enemies collection) at the end of the update method (after the colliding and destroying parts are done).
Student-sourced Ideas
- Enemy of my enemy…
- occasionally “spawn” a BadBomb that after a timeout will destroy everything on screen (enemies and allies alike)
- ToughAsteroid
- Asteroid that takes multiple hits to destroy
- levels
- as the player advances through “levels”, things get harder maybe smaller asteroids or tougher, faster, etc.
- ErraticAsteroid
- changes directions