Old version
This is the CS 112 site as it appeared on May 12, 2022.
Problem Set 4
due by 11:59 p.m. on Wednesday, February 23, 2022
Preliminaries
In your work on this assignment, make sure to abide by the collaboration policies of the course.
If you have questions while working on this assignment, please come to office hours, post them on Piazza, or email instructor.
Make sure to follow the instructions outlined at the end of Part I and Part II when submitting your assignment.
Part I
40 points total
Creating the necessary folder
Create a subfolder called ps4
within your
cs112
folder, and put all of the files for this assignment in that folder.
Creating the necessary file
Problems in Part I will be completed in a single PDF file. To create it, you should do the following:
-
Access the template that we have created by clicking on this link and signing into your Google account as needed.
-
When asked, click on the Make a copy button, which will save a copy of the template file to your Google Drive.
-
Select File->Rename, and change the name of the file to
ps4_partI
. -
Add your work for the problems from Part I to this file.
-
Once you have completed all of these problems, choose File->Download->PDF document, and save the PDF file in your
ps4
folder. The resulting PDF file (ps4_partI.pdf
) is the one that you will submit. See the submission guidelines at the end of Part I.
Problem 1: Understanding and using inheritance
10 points total; individual-only
Imagine that you wanted to capture information about a collection of different types of vehicles (cars, trucks, motorcycles, etc.). To do so, you could use inheritance to create a collection of related classes whose inheritance hierarchy looks like this:

We have provided an implementation of most of these classes in this folder, and we encourage you to review the provided files. They include:
-
a class called
Vehicle
that defines the state (fields) and behavior (methods) that are common to all vehicles; it does not explicitly extend another class -
a class called
Motorcycle
that can be used to create objects that represent motorcycles; it inherits all of its fields and methods fromVehicle
, with the exception of its own constructor -
a class called
Automobile
that can be used to create objects that represent cars; it also inherits fields and methods fromVehicle
, but it adds some new fields and methods that are only needed by cars, and it overrides the inheritedtoString()
method with its own version -
a class called
Truck
that can be used to create objects that represent trucks; it also inherits fields and methods fromVehicle
, but it adds some new fields and methods that are only needed by trucks, and it overrides the inheritedtoString()
method with its own version -
a class called
Taxi
that can be used to create objects that represent cars; it inherits its fields and methods fromAutomobile
, but it adds some new fields and methods that are only needed by taxis, and it overrides the inheritedtoString()
method with its own version -
a class called
TractorTrailer
that can be used to create objects that represent tractor trailors; it inherits its fields and methods fromTruck
, but it adds some new fields and methods that are only needed by tractor trailers, and it overrides the inheritedgetNumAxles()
method with its own version.
The hierarchy diagram above includes a Limousine
class and a
MovingVan
class, but we have not defined those classes yet.
In the Problem 1 section of your ps4_partI
document (see above),
answer the following questions:
-
(1 point) Which of the classes that are shown in the diagram above are a superclass of the
TractorTrailer
class? -
(1 point) If we have a
TractorTrailer
object that has been assigned to a properly declared variablet
, is it possible to make the following call?t.getMileage()
Explain briefly why or why not.
-
Write a definition for the
Limousine
class that takes full advantage of inheritance.A
Limousine
object should have all of the same state and behavior as anAutomobile
object. In addition, it should maintain additional state that keeps track of:- whether the limousine has a sun roof (true or false)
- how many bottles of champagne it can chill (a non-negative integer)
When a
Limousine
object is printed, we should see its make, its model, and the number of seats available to customers, which is two fewer than the total number of seats. For example, if theLimousine
is a Cadillac XTS-L with a total of 8 seats, printing it should produce the following output:Cadillac XTS-L (seats up to 6 customers)
Note that the output mentions 6 seats, because only 6 of the 8 seats are available for customers.
In your
ps4_partI
file, add a definition of this class that includes the following:-
(1 point) a class header that sets up the appropriate inheritance
-
(2 points) whatever new fields are needed to capture the state of a
Limousine
object. Make sure that you take inheritance into account when deciding which fields to include. -
(2 points) a constructor that takes as parameters the make, model, year, and total number of seats, as well as a boolean value indicating whether the limo has a sun roof and an integer indicating how many bottles of champagne it can chill. The constructor should ensure that the object is not put in an invalid state (throwing an exception as needed), and it should take whatever steps are needed to initialize the object.
-
(3 points) any necessary methods. It should be possible for a client to obtain the value of any of the fields, and to change the value of any field that can be changed in an
Automobile
object. However, you should assume that the portion of the state specifying whether there is a sun roof and how many champagne bottles can be chilled will never change, and thus mutator methods are not needed for those fields. You also don’t need to define anequals
method for this class.
Problem 2: Inheritance and polymorphism
18 points total; 2 points each part; individual-only
Imagine that you have a set of related classes that have been defined using inheritance. Here are the key facts about these classes:
-
Class
Zoo
doesn’t explicitly extend a class (i.e., it doesn’t have anextends
clause in its class header). Its class members (i.e., its fields and methods) include:- an integer field called
a
- a
String
field calledb
- a non-static method called
one()
that takes an integer and returns adouble
- a non-static method called
two()
that takes no inputs and returns an integer - its own
equals()
method that overrides the inherited one.
- an integer field called
-
Class
Woo
extendsZoo
. In addition to the members that it inherits, it has:- integer fields called
x
andy
- its own method called
two()
that overrides the inherited one - its own
toString()
method that overrides the inherited one.
- integer fields called
-
Class
Too
extendsZoo
. In addition to the members that it inherits, it has:- integer fields called
t
andu
- its own method called
two()
that overrides the inherited one - its own method called
three()
that takes adouble
and returns aboolean
- an
equals()
method that overrides the inherited one.
- integer fields called
-
Class
Yoo
extendsWoo
. In addition to the members that it inherits, it has:- a
String
field calledc
- its own method called
one()
that overrides the inherited one.
- a
In addition, you should make the following assumptions:
-
All of the classes employ appropriate encapsulation.
-
Each class has a constructor that takes no parameters and initializes the newly created object’s fields with their default values.
-
Each class includes an appropriate accessor method for each field that is declared in that class. For example, the
Zoo
class would have accessor methods calledgetA()
andgetB()
. -
Each class includes an appropriate mutator method for each field that is declared in that class. For example, the
Zoo
class would have mutator methods calledsetA()
andsetB()
.
Answer the following questions in light of the above information about these classes. Before you begin, you may find it helpful to draw an inheritance hierarchy for the classes, although doing so is not required.
-
(2 points) The information above states that the
Zoo
class has its ownequals()
method that overrides the inherited one. Where does theequals()
method thatZoo
overrides come from? Be as specific as possible, and explain your answer briefly. -
(2 points) List all of the fields in a
Yoo
object – both the ones that it declares and the ones (if any) that it inherits. -
(5 points) Consider the following code fragment:
Yoo y1 = new Yoo(); System.out.println(y1.one(10)); System.out.println(y1.two()); System.out.println(y1.three(12.5)); System.out.println(y1.equals(y1)); System.out.println(y1);
Each of the
println
statements in this code fragment displays the result of a method call. (This includes the fifthprintln
statement, in which the Java interpreter calls a method on our behalf.) However, it is possible that one or more of these methods calls would fail to compile because the necessary method is neither defined in theYoo
class nor inherited from a superclass ofYoo
.In section 2-3 of
ps4_partI
, we have included a table that you should complete with appropriate information about each of these method calls. We have filled in the first row for you, and you should complete the remaining rows. -
(3 points) Now imagine that you want to add a non-static method to the
Too
class. It should be calledavg()
, it should take no parameters, and it should return the average of all of the integer fields in the calledToo
object. Add a full definition of that method to section 2-4 of yourps4_partI
file. Make sure to take into account the fact that the classes employ proper encapsulation. Make the average as precise as possible. -
(6 points) For each of the following assignment statements, indicate whether it would be allowed according to the rules of polymorphism, and explain briefly why or why not.
-
Woo w = new Too();
-
Zoo z = new Woo();
-
Zoo z = new Yoo();
-
Too t = new Zoo();
-
Problem 3: Memory management and the ArrayBag
class
12 points total; individual-only
In this problem, you will draw a series of memory diagrams that illustrate
the execution of a program that operates on objects of the ArrayBag
class from lecture.
Consider the following Java program:
public class ArrayBagTest { public static void main(String[] args) { ArrayBag b1 = new ArrayBag(3); ArrayBag b2 = new ArrayBag(3); ArrayBag b3 = b2; // part 1: what do things look like when we get here? // part 2: what do things look like at the start of // this method call? b1.add("hello"); b2.add("world"); b3.add("hello"); // part 3: what do things look like when we get here? System.out.println(b1); System.out.println(b2); System.out.println(b3); } }
-
In section 3-1 of
ps4_partI
, we have given you the beginnings of a memory diagram. On the stack (the region of memory where local variables are stored), we have included a frame for themain
method. On the heap (the region of memory where objects are stored), we have included theArrayBag
object to which the variableb1
refers and itsitems
array. As usual, we have used arrows to represent the necessary references.Complete the provided memory diagram so that it shows what things look like in memory just before the call
b1.add("hello")
.To do so, you should:
-
Click on the diagram and then click the Edit link that appears below the diagram.
-
Make whatever changes are needed to the diagram. Below the thick horizontal line, we have given you a set of extra components that you can use as needed by dragging them above the thick line and putting them in the correct position. These components include
String
objects representing the strings"hello"
and"world"
. You may not need all of the provided components. -
You can also edit any of the values in a field or array by clicking on the corresponding cell and editing the text that is inside the cell.
-
Once you have made all of the necessary changes, click the Save & Close button.
-
-
In section 3-2 of
ps4_partI
, we have given you the beginnings of a memory diagram that you should complete to show what things look like in memory at the start of the execution ofb1.add("hello")
—just before the first statement of that method is executed.Note: To save time, it should be possible to select and copy some of the components of your diagram for 3-1 and paste them into your diagram for 3-2.
-
In section 3-3 of
ps4_partI
, we have given you the beginnings of a memory diagram that you should complete to show what things look like in memory after all of the calls toadd
have returned—just before theprint
statements execute inmain()
.Note: We have included a method frame for
add
, but it may or not be needed in this diagram; you should delete it if you determine that it would no longer be present in memory. -
What would be printed by this program? You may find it helpful to consult the
toString
method of theArrayBag
class.
Submitting your work for Part I
Note: There are separate instructions at the end of Part II that you should use when submitting your work for that part of the assignment.
Submit your ps4_partI.pdf
file using these steps:
-
If you still need to create a PDF file, open your
ps4_partI
file on Google Drive, choose File->Download->PDF document, and save the PDF file in yourps4
folder. -
Login to Gradescope by clicking the link in the left-hand navigation bar, and click on the box for CS 112.
-
Click on the name of the assignment (
PS 4: Part I
) in the list of assignments on Gradescope. You should see a pop-up window labeled Submit Assignment. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.) -
Choose the Submit PDF option, and then click the Select PDF button and find the PDF file that you created. Then click the Upload PDF button.
-
You should see a question outline along with thumbnails of the pages from your uploaded PDF. For each question in the outline:
- Click the title of the question.
- Click the page(s) on which your work for that question can be found.
As you do so, click on the magnifying glass icon for each page and doublecheck that the pages that you see contain the work that you want us to grade.
-
Once you have assigned pages to all of the questions in the question outline, click the Submit button in the lower-right corner of the window. You should see a box saying that your submission was successful.
Important
-
It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.
-
If you are unable to access Gradescope and there is enough time to do so, wait an hour or two and then try again. If you are unable to submit and it is close to the deadline, email your homework before the deadline to
cs112-staff@cs.bu.edu
Part II
60 points total
Important
Don’t forget that each of your methods should be preceded by a comment that explains what your method does and what its inputs are. In addition, you should include a comment at the top of each Java file, and you should use good programming style more generally.
In addition, you should continue to follow the other guidelines
that we gave you in the prior problem sets. In particular, see the
section labeled Important guidelines that is available
here. You also should not use any methods
from the Arrays
class as part of the methods that your write, as
indicated in the guidelines found
here.
Problem 4: Implementing the game of CardMatch
30 points; pair-optional
This is the only problem of the assignment that you may complete with a partner. See the rules for working with a partner on pair-optional problems for details about how this type of collaboration must be structured.
Overview
In Problem Set 3, you implemented a Card
class for cards
that have a color and a numeric value. In this problem, you will
use that class as part of game called CardMatch.
In the game of CardMatch, cards have a color (blue, green, red, or yellow) and a value between 0 and 9. At the start of the game, each player is dealt a hand of five cards, and a single card is turned over to form the beginning of a discard pile.
Players take turns attempting to discard a single card from their hands. In order to discard a card, the card must match either the color or the value of the card at the top of the discard pile. For example, if the card at the top of the discard pile is a green 5, a player could play either a green card of any value or a 5 card of any color. If a player has no cards that match the top of the discard pile, they must draw a card and wait until their next turn.
The game continues until a player has no cards left or until a player has 10 cards in their hand. At the end of the game, the player whose final hand has the smallest total value wins the game and earns the total value of the other players’ final hands. To reduce the likelihood of a player winning with 10 cards, a penalty of 20 points is added to the value of any hand with 10 cards. If there are two or more players whose hands are tied the same smallest final value, no one wins any points.
For example, let’s say that there are two players and one of them accumulates 10 cards, ending the game. Assume that the final hands of the players are:
player 1: red 2, yellow 5, blue 1 player 2: green 3, red 1, blue 2, red 2, yellow 1, yellow 3, red 1, blue 0, green 1, red 5
Player 1 ends up with the final hand with the smallest total value (2+5+1 = 8) and thus wins the game. Player 2’s final hand value is 3+1+2+2+1+3+1+0+1+5 = 19, plus the added 20-point penalty, to give 39. Player 1 earns 39 points.
Because the player with the smallest total value wins, players have an incentive to discard cards with a high value.
Sample runs
The version of the game that you will implement will allow a human player to play against the computer. Here are some sample runs of the game:
- first sample run (random seed = 429)
- second sample run (random seed = 111)
- third sample run (random seed = 99)
Notes about the sample runs:
- See the section below entitled Testing your code for information about how to specify a random seed.
- In each sample run, user inputs are underlined.
- When selecting a card to play, the computer player in the sample runs uses the minimal approach described in Task 3 below. If there is more than one matching card, it selects the one with the highest value. If there are multiple matching cards that are tied for the highest value, it selects the one that comes closest to the beginning of the hand (i.e., the one with the smallest index).
- If you use a different algorithm for selecting the computer’s discard, you may get somewhat different results.
Getting started
-
If you haven’t already done so, create a folder named
ps4
for your work on this assignment. You can find instructions for doing so here. -
Put a copy of your
Card.java
file from Problem Set 3 in yourps4
folder. Note: If you are working with a partner and you both have your own version of theCard
class, you should pick one of them to use for this assignment. -
Download the following files:
Make sure to put both of these files in your
ps4
folder, along with yourCard.java
file. If your browser doesn’t allow you to specify where a file should be saved, try right-clicking on its link above and choosing Save as... or Save link as..., which should produce a dialog box that allows you to choose the correct folder for the file. -
In VS Code, select the File->Open Folder or File->Open menu option, and use the resulting dialog box to find and open the folder that you created for this assignment. (Note: You must open the folder; it is not sufficient to simply open the file.)
The name of the folder should appear in the Explorer pane on the left-hand side of the VS Code window, along with the names of the files.
Task 1: review the provided code
In the Explorer Pane, click on the name CardMatch.java
, which will
open an editor window for that file.
This class contains the main
method of the program; you will run
this class to start the program. In addition, this class serves
as a blueprint for objects that maintain the state of a CardMatch
game. It includes fields for things like the deck, the players,
and the card at the top of the discard pile, and it includes
methods that are used to execute the various stages of the game.
You should not make any modifications to this class except for
the single change specified in Task 3.
Begin by reading over the code that we have given you. In particular,
you should look at how the CardMatch
class will make use of the types
of objects that you will create below.
You do not need to fully understand how the Deck
class works,
but we encourage you to look it over. It is a fully implemented
class that serves as a blueprint for objects that represent a
deck of CardMatch cards. Deck
objects have several non-static
methods, the most useful of which are the shuffle
and dealCard
methods. It uses a random-number generator when shuffling the
cards to get a different ordering of the deck each time. When
testing your code, it’s possible to control the numbers generated
by the random-number generator so that you can get repeatable
hands of cards. See the section below entitled Testing your code
for more details. You should not modify the code in this
class.
Task 2: create a blueprint class for a player
Write a class named Player
that serves as a blueprint for objects
that represent a single CardMatch player. Make sure to save it in
your ps4
folder.
Import the java.util
package at the start of the file.
Each Player
object should have the following components:
-
three fields:
- one called
name
to keep track of the player’s name (a single string) - one called
hand
for an array to hold the cards in the player’s hand - one called
numCards
to keep track of how many cards are currently in the player’s hand Make sure that your field definitions prevent direct access by code from outside the class.
- one called
-
a constructor that takes a single parameter for the name of the player. It should initialize all of the fields. Among other things, it should create the array that will store the cards. Make the collection big enough to store the maximum number of cards in a given hand (10). Use the class constant
CardMatch.MAX_CARDS
to specify this value, rather than hard-coding the integer 10. -
an accessor named
getName
that returns the player’s name. -
an accessor named
getNumCards
that returns the current number of cards in the player’s hand. -
a
toString
method that just returns the player’s name. -
a mutator named
addCard
that takes aCard
object as a parameter and adds the specified card to the player’s hand, filling the array from left to right. It should throw anIllegalArgumentException
if the parameter isnull
, or if the player already has the maximum number of cards. -
an accessor named
getCard
that takes an integer index as a parameter and returns theCard
at the specified position in the player’s hand, without actually removing the card from the hand. For example, ifp
is aPlayer
,p.getCard(0)
should return the card at position 0 inp
‘s hand – i.e., the first/leftmost card. If the specified index does not correspond to one of the cards in the hand, the method should throw anIllegalArgumentException
. -
an accessor method named
getHandValue
that computes and returns the total value of the player’s current hand – i.e., the sum of the values of the individual cards, plus an additional 20-point penalty if the hand has the maximum number of cards. Use the class constants given inCardMatch.java
for the maximum number of cards and for the penalty associated with having that many cards. -
an accessor method named
displayHand
that prints the current contents of the player’s hand, preceded by a heading that includes the player’s name. Each card should be printed on a separate line, preceded by the index of its position in the hand. For example:John's hand: 0: red 7 1: green 2 2: blue 3
See the sample runs for additional examples. Note that the spacing matters. In particular, there should be:
- exactly two spaces before each index value
- no space between an index and its colon
- exactly one space after each colon
- exactly one space between each card’s color and value
- no spaces at the end of any line.
-
a mutator method named
removeCard
that takes an integer index as a parameter and both removes and returns theCard
at that position of the player’s hand. If the specified index does not correspond to one of the cards in the hand, the method should throw anIndexOutOfBoundsException
.If the card being removed is not the rightmost card in the hand, the rightmost card must be moved into the position of the card that is being removed. For example, if the hand is currently the four cards
{blue 3, red 2, yellow 7, green 1}
and you are removing the card at position 1 (thered 2
), you must replace it with the last card (thegreen 1
), and thus the resulting hand would be:{blue 3, green 1, yellow 7}
. -
an accessor method named
getPlay
that determines and returns the number corresponding to the player’s next play: either -1 if the player wants to draw a card, or the number/index of the card that the player wants to discard from his/her hand. The method should take two parameters: aScanner
object that can be used to read from the console, and aCard
object representing the card that is currently at the top of the discard pile.-
The method should print the appropriate prompt (see the sample runs) and read an integer from the console. If the number entered is invalid (i.e., if it is neither -1 nor an index of one of the cards in the hand), the method should continue asking for a new value until the player enters a valid one.
-
You do not need to worry about whether the specified card matches the top of the discard pile, because the code that we have given you in the
CardMatch
class already checks for that. -
You may assume that the player never enters a non-integer.
-
Because this version of the method is for a human player, it can ignore the second parameter (the card at the top of the discard pile). The version of this method that you will write in Task 3 will be for a computer user, and it will use the second parameter.
-
After completing all of Task 2, you should be able to run the
CardMatch
class, and run it to play the game.
When running the program, you should highlight CardMatch.java
in the
list of files before using F5 to run the program. Another option is
to right-click on the name of the file in the Explorer pane and choose
Run or Run Java.
At this point, the computer will be represented by a Player
object,
which means that you will be able to see the contents of its hand, and
that its plays will be determined using the getPlay
method that you
implemented above. In other words, you will need to enter the plays
for both players!
If VS Code reports problems in the CardMatch
class, that probably
means that there are problems in the headers of one or more of your
Player
methods. Change your Player
class as needed until the
CardMatch
class compiles and runs. Remember that you are not
allowed to change the Deck
class in any way. In addition, you should
not change the CardMatch
class at this point in the process.
Task 3: create a blueprint class for a computer player
The Player
class that you wrote for Task 3 serves
as a blueprint for the human player — since its getPlay
method asks the user of the program to enter the next play from
the console. In this task, you will write a class named
ComputerPlayer
that serves as a
blueprint for objects that represent a computer player.
Save it in the same folder as your other classes for this program.
Import the java.util
package at the start of the file.
Most of the state and behavior needed for a ComputerPlayer
is already present in Player
. Thus, you should
make ComputerPlayer
a subclass of Player
,
so that it will inherit the fields and methods of that class.
In addition to the inherited fields and methods, this class will need:
-
its own constructor, which should take the name of the player as a parameter and call the constructor of the superclass to do the actual work of initializing the inherited fields.
-
a
displayHand
method that overrides the inherited version of that method. This version of the method should simply print the number of cards in theComputerPlayer
‘s hand. For example:the computer's hand: 3 cards
- Use the name given to the player when the object was
created (which may not always be
"the computer"
). - If there is only one card, use the word
"card"
instead of"cards"
.
- Use the name given to the player when the object was
created (which may not always be
-
a
getPlay
method that overrides the inherited version of that method. This version of the method should figure out if the computer has a card that matches the card at the top of the discard pile (this card is passed in as the second parameter of the method). If the computer doesn’t have a matching card, the method should return -1 so that the computer will end up drawing a card. If the computer does have one or more matching cards, the method should return the index of the card that should be played.-
For full credit, this method should take into account the values and/or colors of the cards when choosing between two or more matching cards. Simply choosing the matching card with the highest value will earn full credit.
-
Optionally, you could also factor in the color of the cards. For example, if the computer has several different cards that match the value of the card at the top of the discard pile, it might make sense for it to choose the one with the color that is shared by the largest number of other cards in the computer’s hand.
-
Once you have defined your ComputerPlayer
class, modify the line of
code in the CardMatch
constructor that assigns a value to the second
element of the players
array (players[1]
). Instead of assigning a
Player
object, it should now assign a ComputerPlayer
object. You should not make any other changes to the CardMatch
class.
If you have implemented everything correctly, the computer’s hand should now be hidden when you run the program, and the computer should determine its own play, rather than asking you to enter it from the keyboard.
Once all of these tasks are completed, you should have a working CardMatch game!
Testing your code
To get repeatable hands for testing purposes, you can specify a seed
for the random-number generator used by the Deck
class when it
shuffles the deck. Here is one way to do so:
-
As needed, open the folder containing your code by using the File->Open Folder or File->Open menu option in VS Code.
-
If you don’t already have a Terminal pane at the bottom of the VS Code window, use the Terminal->New Terminal menu option to open one.
-
Enter the following command from the Terminal to compile your code:
javac CardMatch.java
If executing this command produces error messages describing bugs in your code, fix them, save the file(s) in VS Code, and try again. Repeat this process until your code compiles without any error messages.
-
Enter the following command from the Terminal to run your code with a random seed:
java CardMatch seed
where you replace
seed
with an integer.
Other testing notes
-
If you make any changes to your code, make sure to:
-
Save the changed file(s) in VS Code.
-
Recompile your code by executing
javac CardMatch.java
before you attempt to rerun the program.
-
-
To make sure that the
getPlay
method in yourComputerPlayer
class is working correctly, you may want to temporarily comment out thedisplayHand
method in that class. Doing so will cause all of the dealer’s cards to be displayed, which will allow you to see ifgetPlay
is selecting the correct card. Make sure to uncommentdisplayHand
before submitting the file.
Problem 5: Adding methods to the ArrayBag
class
30 points total; individual-only
Begin by downloading the following file:
ArrayBag.java
Make sure to put the file in your ps4
folder.
Open the file in VS Code, and you will see the ArrayBag
class
from lecture.
Add the methods described below to the ArrayBag
class, and then add
code to the main()
method to test these methods. You should not
add any new fields to the class.
-
public int roomLeft()
This method should return the number of additional items that the called
ArrayBag
has room to store. For example, the following test code:ArrayBag b1 = new ArrayBag(10); System.out.println("room before: " + b1.roomLeft()); b1.add("hello"); b1.add("world"); System.out.println("room after: " + b1.roomLeft());
should output:
room before: 10 room after: 8
Hint: This method should only need one or two lines of code.
-
public boolean isFull()
This method should return
true
if the calledArrayBag
is full, andfalse
otherwise. For example, the following test code:ArrayBag b1 = new ArrayBag(2); System.out.println(b1.isFull()); b1.add("hello"); System.out.println(b1.isFull()); b1.add("world"); System.out.println(b1.isFull());
should output:
false false true
-
public void increaseCapacity(int increment)
This method should increase the maximum capacity of the called
ArrayBag
by the specified amount. For example, ifb
has a maximum capacity of 10, thenb.increaseCapacity(5)
should giveb
a maximum capacity of 15. As part of your implementation, you will need to create a new array with room to support the new maximum capacity, copy any existing items into that array, and replace the original array with the new one by storing its reference in the called object.For example, the following test code:
ArrayBag b1 = new ArrayBag(10); b1.add("hello"); b1.add("world"); System.out.println(b1); System.out.println("room before: " + b1.roomLeft()); b1.increaseCapacity(5); System.out.println(b1); System.out.println("room after: " + b1.roomLeft());
should produce the following output:
{hello, world} room before: 8 {hello, world} room after: 13
Special cases:
- If
increment
is 0, the method should just return. - If
increment
is negative, the method should throw anIllegalArgumentException
.
- If
-
public boolean removeItems(ArrayBag other)
This method should attempt to remove from the called
ArrayBag
all occurrences of the items found in the parameterother
. If the called object contains multiple copies of an item fromother
, all of the copies should be removed. The method should returntrue
if one or more items are removed, andfalse
otherwise. For full credit, you should take full advantage of the existingArrayBag
methods.For example, consider this test code:
ArrayBag b1 = new ArrayBag(6); String[] words1 = {"hello", "you", "how", "are", "you", "today?"}; for (String w : words1) { b1.add(w); } System.out.println(b1); ArrayBag b2 = new ArrayBag(6); String[] words2 = {"not", "bad", "how", "are", "you", "doing"}; for (String w : words2) { b2.add(w); } System.out.println(b2); System.out.println(b1.removeItems(b2)); System.out.println(b1); System.out.println(b2);
Running it should display the following:
{hello, you, how, are, you, today?} {not, bad, how, are, you, doing} true {hello, today?} {not, bad, how, are, you, doing}
Special cases:
-
If the parameter is
null
, the method should throw anIllegalArgumentException
. -
If the parameter is an empty
ArrayBag
, the method should returnfalse
.
-
-
public ArrayBag intersectionWith(ArrayBag other)
This method should create and return an
ArrayBag
containing one occurrence of any item that is found in both the called object and the parameterother
. For full credit, the resulting bag should not include any duplicates. For example, ifb1
represents the bag {2, 2, 3, 5, 7, 7, 7, 8} andb2
represents the bag {2, 3, 4, 5, 5, 6, 7}, thenb1.intersectionWith(b2)
should return anArrayBag
representing the bag{2, 3, 5, 7}
. Give the newArrayBag
a maximum size that is equal to the number of items in the bag with the smaller number of items (but see below for an exception). The order of the items in the returnedArrayBag
does not matter.Special cases:
-
If there are no items that occur in both bags—including cases in which one or both of the bags are empty—the method should return an empty
ArrayBag
. -
If the parameter is
null
, the method should throw anIllegalArgumentException
. -
In general, the returned
ArrayBag
should have a maximum size that is equal to the number of items in the bag with the smaller number of items. However, because it’s not possible to construct anArrayBag
with a maximum size of 0, you should give the newArrayBag
a maximum size of 1 if one or both of the original bags are empty.
For full credit, you should take full advantage of the existing
ArrayBag
methods. They will make your job much easier!For example, running this test code:
ArrayBag b1 = new ArrayBag(10); String[] letters1 = {"a", "a", "b", "d", "f", "f", "f", "g"}; for (String ltr: letters1) { b1.add(ltr); } System.out.println(b1); ArrayBag b2 = new ArrayBag(8); String[] letters2 = {"a", "b", "c", "d", "d", "e", "f"}; for (String ltr: letters2) { b2.add(ltr); } System.out.println(b2); ArrayBag b3 = b1.intersectionWith(b2); System.out.println(b3); System.out.println(b3.numItems()); System.out.println(b3.roomLeft()); System.out.println(b1); // make sure original bags are unchanged System.out.println(b2);
should output:
{a, a, b, d, f, f, f, g} {a, b, c, d, d, e, f} {a, b, d, f} 4 3 {a, a, b, d, f, f, f, g} {a, b, c, d, d, e, f}
Note: The items in the intersection (
{a, b, d, f}
) can appear in any order. -
Submitting your work for Part II
Note: There are separate instructions at the end of Part I that you should use when submitting your work for that part of the assignment.
You should submit only the following files:
CardMatch.java
Player.java
ComputerPlayer.java
ArrayBag.java
You do not need to resubmit your Card.java
. We will use our
version of that class when testing your code.
Make sure that you do not try to submit a .class
file or a file
with a ~
character at the end of its name.
Here are the steps:
-
Login to Gradescope as needed by clicking the link in the left-hand navigation bar, and then click on the box for CS 112.
-
Click on the name of the assignment (
PS 4: Part II
) in the list of assignments. You should see a pop-up window with a box labeled DRAG & DROP. (If you don’t see it, click the Submit or Resubmit button at the bottom of the page.) -
Add your files to the box labeled DRAG & DROP. You can either drag and drop the files from their folder into the box, or you can click on the box itself and browse for the files.
-
Click the Upload button.
-
You should see a box saying that your submission was successful. Click the
(x)
button to close that box. -
The Autograder will perform some tests on your files. Once it is done, check the results to ensure that the tests were passed. If one or more of the tests did not pass, the name of that test will be in red, and there should be a message describing the failure. Based on those messages, make any necessary changes. Feel free to ask a staff member for help.
Note: You will not see a complete Autograder score when you submit. That is because additional tests for at least some of the problems will be run later, after the final deadline for the submission has passed. For such problems, it is important to realize that passing all of the initial tests does not necessarily mean that you will ultimately get full credit on the problem. You should always run your own tests to convince yourself that the logic of your solutions is correct.
-
If needed, use the Resubmit button at the bottom of the page to resubmit your work. Important: Every time that you make a submission, you should submit all of the files for that Gradescope assignment, even if some of them have not changed since your last submission.
-
Near the top of the page, click on the box labeled Code. Then click on the name of each file to view its contents. Check to make sure that the files contain the code that you want us to grade.
Important
-
It is your responsibility to ensure that the correct version of every file is on Gradescope before the final deadline. We will not accept any file after the submission window for a given assignment has closed, so please check your submissions carefully using the steps outlined above.
-
If you are unable to access Gradescope and there is enough time to do so, wait an hour or two and then try again. If you are unable to submit and it is close to the deadline, email your homework before the deadline to
cs112-staff@cs.bu.edu