GridWorld Case Study : GridWorld Case Study Barbara Ericson
March 24, 2007
Chapter 1: Intro to GridWorld : Chapter 1: Intro to GridWorld Open BugRunner.java
Run the main method
Click the step button
Click on an empty grid cell and create a rock in front of the bug
Click on the Step button
Click on a bug
Get a menu of methods
Click on a method to invoke it
Click on a flower and a rock too
Exercise Set 1 : Exercise Set 1 Does the bug always move to a new location?
In what direction does the bug move?
What does the bug do if it can’t move?
What does the bug leave behind when it moves?
What happens when the bug is at the edge of the grid?
And facing the edge?
And not facting the edge?
What happens when a bug is facing a rock and you click step?
Does a flower move?
What behavior does a flower have?
Does a rock move or have any other behavior?
Can more than one actor (bug, flower, rock) be in the same grid location at the same time?
Exercise Answers Set 1 : Exercise Answers Set 1 Does the bug always move to a new location?
No
In what direction does the bug move?
The direction it is facing
What does the bug do if it can’t move?
Turns right 45 degrees
What does the bug leave behind when it moves?
A flower
What happens when the bug is at the edge of the grid?
And facing the edge?
Turns 45
And not facing the edge?
Continues to move if it can
What happens when a bug is facing a rock and you click step?
It turns 45 degrees to the right.
Does a flower move?
No
What behavior does a flower have?
The color gets darker over time. It can act. It inherits other behavior from Actor (setColor, setDirection, etc)
Does a rock move or have any other behavior?
It doesn’t change over time. It can act. It inherits other behavior from Actor (setColor, setDirection, etc)
Can more than one actor (bug, flower, rock) be in the same grid location at the same time?
No
Exercises : Exercises Click on a bug, flower, or rock
Invoke the setDirection method
Fill in the following table for the setDirection method
Exercise Answers : Exercise Answers Click on a bug, flower, or rock
Invoke the setDirection method
Fill in the following table for the setDirection method
Can you set the direction to an angle that isn’t a multiple of 45?
What happens?
Exercise : Exercise Use the moveTo method to move a bug
Does it change direction?
How far can you move it?
What happens if you try to move it outside the grid?
What is the top left location?
What is the bottom right location?
Exercise Answers : Exercise Answers Use the moveTo method to move a bug
Does it change direction?
No
How far can you move it?
Anywhere in the grid
What happens if you try to move it outside the grid?
You get an IllegalArgumentException
What is the top left location?
0,0
What is the bottom right location?
9,9
Exercise : Exercise What method can you use to change the color of a bug, rock, or flower?
Move a rock to a location with a bug in it. Move the rock again to another location. What happened to the bug?
What methods are defined in bug
Not just inherited from Actor?
Exercise Answers : Exercise Answers What method can you use to change the color of a bug, rock, or flower?
setColor
Move a rock to a location with a bug in it. Move the rock again to another location. What happened to the bug?
It is removed from the world
What methods are defined in bug
Not just inherited from Actor
act, move, turn, canMove
Chapter 2: Bug Variations : Chapter 2: Bug Variations Create new kinds of bugs
Open classes in projects/boxBug
BoxBug
Moves in a square pattern
Instance variables of sideLength and steps
Overrides the act method
Exercise Set 2 : Exercise Set 2 What is the role of the instance variable sideLength?
What is the role of the instance variable steps?
Why is the turn method called twice when steps becomes equal to sideLength?
Why can the move method be called in BoxBug when there is no move method in the BoxBug class?
After a BoxBug is constructed will the size of the square pattern always be the same?
Can the path a BoxBug travels ever change?
When will the value of steps be zero?
Exercise Answers Set 2 : Exercise Answers Set 2 What is the role of the instance variable sideLength?
The number of grid cells in one side of the box – 1.
What is the role of the instance variable steps?
Keeps track of the current number of steps the bug has taken on the current side.
Why is the turn method called twice when steps becomes equal to sideLength?
To make a 90 degree turn (each turn is 45 degrees)
Why can the move method be called in BoxBug when there is no move method in the BoxBug class?
It is inherited from Bug since the BugBog class extends the Bug class
After a BoxBug is constructed will the size of the square pattern always be the same?
Yes, there is no mutator (modifier) method in BoxBug for sideLength
Can the path a BoxBug travels ever change?
Yes, if it can’t move it turns 90 degrees.
When will the value of steps be zero?
When it is constructed and after each 90 degree turn.
New Bug Classes : New Bug Classes CircleBug
Like BoxBug but only one turn
45 degree turn
SpiralBug
Like BoxBug but the sideLength gets longer after each turn
90 degree turn
New Bug Classes : New Bug Classes ZBug
Draws a Z and then stops moving
DancingBug
Takes an array of integers which are the number of turns it makes when asked to act
Then it acts like a Bug
Problem : Problem The GridWorld case study says to make CircleBug and SpiralBug like BoxBug
Hints at copy and paste
Should use inheritance
But sideLength and steps are private in BoxBug
Can add public accessors and modifier methods to BoxBug
And inherit from BoxBug
But is a CircleBug a kind of BoxBug?
Better to pull out sideLength and steps and put in a PatternBug abstract class
And have BoxBug inherit from PatternBug
Chapter 3: Classes and Interfaces : Chapter 3: Classes and Interfaces Main classes are:
Location – Class
Grid of Actors - Interface
BoundedGrid of Actors - Class
UnboundedGrid of Actors - Class
Actor – Class
Bug – Class
Flower – Class
Rock - Class
Location Class : Location Class Encapsulates a grid location
Row and Column number
Rows increase going down
Columns increase going right
Also has methods that determine relationships between locations and compas directions
Including constants for NORTH, NORTHEAST, LEFT, RIGHT, etc
Location Class : Location Class Accessor methods
getRow
getCol
Working with locations
Get a neighbor location in a direction
public Location getAdjacentLocation(int direction)
Get the closest compass direction toward target
public int getDirectionToward(Location target)
Two Location objects are equal if they have the same row and column
Location also implements the Comparable interface
Turning by an Amount : Turning by an Amount We have been using multiple calls to the turn method to turn an Actor
We can use setDirection and Location constants for this instead
setDirection(getDirection + Location.HALF_RIGHT); // turn 45 degrees
Exercise Set 3 : Exercise Set 3 Given
Location loc1 = new Location(4,3);
Locaiton loc2 = new Location(3,4);
How would you access the row value of loc1?
What is the value of b after the following statement is executed?
boolean b = loc1.equals(loc2);
What is the value of loc3 after the following?
Location loc3 = loc2.getAdjacentLocation(Location.SOUTH);
What is the value of dir after the following?
Int dir = loc1.getDirectionToward(new Location(6,5));
How does the getAdjacentLocation method know which location to return?
Exercise Answers Set 3 : Exercise Answers Set 3 Given
Location loc1 = new Location(4,3);
Location loc2 = new Location(3,4);
How would you access the row value of loc1?
loc1.getRow();
What is the value of b after the following statement is executed?
boolean b = loc1.equals(loc2); b is false
What is the value of loc3 after the following?
Location loc3 = loc2.getAdjacentLocation(Location.SOUTH);
Location(4,4);
What is the value of dir after the following?
int dir = loc1.getDirectionToward(new Location(6,5)); 135
How does the getAdjacentLocation method know which location to return?
It uses the passed direction
Grid Interface : Grid Interface Check if a location is valid (is in the grid)
boolean isValid(Location loc)
Put an object into the location in the grid and return the object that was at this location or null
E put(Location loc, E obj)
Remove the object at this location in the grid and return it or null
E remove(Location loc)
Return the object at this location in the grid or null
E get(Location loc)
Get an array list of locations that are occupied
ArrayList getOccupiedLocations()
Get the number of rows or columns (-1 for unbounded)
int getNumRows(), int getNumCols()
Getting Neighbors in a Grid : Getting Neighbors in a Grid Return all valid locations adjacent to a given location
ArrayList getValidAdjacentLocations(Location loc)
Return all valid empty locations adjacent to a given location
ArrayList getEmptyAdjacentLocations(Location loc)
Return all valid occupied locations adjacent to a given location
ArrayList getOccupiedAdjacentLocations(Location loc)
Returns all the objects in the occupied adjacent locations
ArrayList getNeighbors(Location loc)
Exercise Set 4 : Exercise Set 4 How can you get a count of the objects in the grid?
How can you get a count of the empty locations in the grid?
How can you check if location(10,10) is in the grid?
Grid contains method declarations but no code. Why?
Where can you find the code for the methods?
All methods that can return multiple objects return them in an ArrayList. Would it have been a better design to return them in an array? Explain your answer.
Exercise Answers Set 4 : Exercise Answers Set 4 How can you get a count of the objects in the grid?
getOccupiedLocations().size()
How can you get a count of the empty locations in the grid?
getNumRows() * getNumCols() – getOccupiedLocations.size()
How can you check if location(10,10) is in the grid?
isValid(new Location(10,10));
Grid contains method declarations but no code. Why?
It is an interface
Where can you find the code for the methods?
In the classes that implement the interface: BoundedGrid and UnboundedGrid
All methods that can return multiple objects return them in an ArrayList. Would it have been a better design to return them in an array? Explain your answer.
ArrayLists are arrays that can grow or shrink. They are better than arrays when you don’t know how many items you will have.
Actor Class : Actor Class public Color getColor()
public int getDirection()
public Grid getGrid()
public Location getLocation()
public void putSelfInGrid(Grid gr, Location loc)
Use this for adding an actor to the grid as it also set the Actor’s location
public void removeSelfFromGrid();
Use this for removing an Actor from the grid. It sets the grid and location instance variables to null.
Actor Class : Actor Class Moves this Actor to the given location and removes anything currently at this location
public void moveTo(Location loc)
Mutator (modifier) methods
public void setColor(Color newColor)
public void setDirection(int newDir)
Act method: by default reverses direction. Override this method in subclasses.
public void act()
Exercise Set 5 : Exercise Set 5 Name 3 properties that every Actor has.
When an actor is constructed what is its direction and color?
Why was the Actor class created as a class and not an interface?
Can an Actor put itself in the grid twice without removing itself?
Can an Actor remove itself from the grid twice?
Can an actor place itself in the grid and then remove itself and then add itself to the grid? Try it. What happens?
How can an actor turn 90 degrees to the right?
Exercise Answers Set 5 : Exercise Answers Set 5 Name 3 properties that every Actor has.
Color, direction, location
When an actor is constructed what is its direction and color?
Blue and North
Why was the Actor class created as a class and not an interface?
Use classes or abstract classes when we want to provide fields and methods. Interfaces can only define constants and abstract methods.
Can an Actor put itself in the grid twice without removing itself?
No, you will get an IllegalStateException
Can an Actor remove itself from the grid twice?
No, you will get an IllegalStateException
Can an actor place itself in the grid and then remove itself and then add itself to the grid? Try it. What happens?
Should work.
How can an actor turn 90 degrees to the right?
setDirection(getDirection() + Location.RIGHT);
Rock and Flower Classes : Rock and Flower Classes Subclasses of Actor
Override act()
Rocks don’t do anything in the act method
Empty body {}
Flowers change the color
reduces the red, green, and blue by the same amount (0.05)
Bug Class : Bug Class Extends Actor
In act() check if can move and if can move, move, and drop a flower in the old location, else turn (45 degrees)
public void act()
{
if (canMove())
move();
else
turn();
}
canMove Method : canMove Method A bug can move if
It is in a grid
And the location in front of it is a valid location
And there is either nothing in this location or there is a flower in this location
Uses neighbor instanceof Flower to check this
public boolean canMove()
{
Grid gr = getGrid();
if (gr == null)
return false;
Location loc = getLocation();
Location next = loc.getAdjacentLocation(getDirection());
if (!gr.isValid(next))
return false;
Actor neighbor = gr.get(next);
return (neighbor == null) || (neighbor instanceof Flower);
// ok to move into empty location or onto flower
// not ok to move onto any other actor
}
Exercise Set 6 : Exercise Set 6 Which statement in the canMove method ensures that a bug doesn’t move out of the grid?
Which statement in the canMove method keeps a bug from walking into a rock?
Which methods from the Grid interface are invoked in the canMove method and why?
Which method in the Location class is invoked in the canMove method and why?
Which methods inherited from the Actor class are invoked in the canMove method and why?
What happens in the move method when the location in front of the bug is out of the grid?
Is the variable loc needed in the move method or could it be avoided by calling getLocation() multiple times?
Why do you think that the flowers that are dropped by the bug have the same color as the bug?
When a bug removes itself from the grid will it, will it place a flower in its previous location?
Which statement in the move method places a flower in the grid at the previous location?
If a bug needs to turn 180 degrees how many times should it call the turn method?
Exercise Answers Set 6 : Exercise Answers Set 6 Which statement in the canMove method ensures that a bug doesn’t move out of the grid?
if (!gr.isValid(next))
Which statement in the canMove method keeps a bug from walking into a rock?
return (neighbor == null) || (neighbor instanceof Flower);
Which methods from the Grid interface are invoked in the canMove method and why?
isValid is used to check if the location in front of the bug is value and get is used to get the object in the grid in front of the bug
Which method in the Location class is invoked in the canMove method and why?
getAdjacentLocation to get the location in front of the bug
Which methods inherited from the Actor class are invoked in the canMove method and why?
getGrid is used to check that the bug is in a grid, and getLocation is used to get the current location
Exercise Answers Set 6 : Exercise Answers Set 6 What happens in the move method when the location in front of the bug is out of the grid?
The bug removes itself from the grid
Is the variable loc needed in the move method or could it be avoided by calling getLocation() multiple times?
It is needed to store the previous location so that a flower can be put there
Why do you think that the flowers that are dropped by the bug have the same color as the bug?
To make it clear which bug they come from
When a bug removes itself from the grid will it, will it place a flower in its previous location?
Yes
Which statement in the move method places a flower in the grid at the previous location?
flower.putSelfInGrid(gr, loc);
If a bug needs to turn 180 degrees how many times should it call the turn method?
180 / 45 = 4
Jumper Activity : Jumper Activity In groups of 3-5 students
Create a Jumper class.
Objects of this class can move forward 2 cells and can jump over rocks or flowers. They don’t leave anything behind
Discuss the following:
What happens if the next location is empty but the one two in front contains a rock or flower?
What should happen if the location two in front is out of the grid?
What should a Jumper do if it is facing the edge of the grid?
What should a Jumper do if the location two in front has another Actor in it (not a Flower or Rock)
What will a Jumper do if it encounters another Jumper?
Are there any other tests a Jumper needs to make?
Jumper Activity Cont. : Jumper Activity Cont. Consider the following design issues:
Which class should Jumper extend?
Is there an existing class that is similar to Jumper?
Should you create a constructor? What parameters should it have?
Which methods should be overriden?
What new methods should be added?
How will you test the class?
Code the Jumper and JumperRunner classes
Test the Jumper class
Or give it to another group to test
The Graphical User Interface : The Graphical User Interface The World class connects the described classes and the GUI
The GUI asks the World for the grid, gets the objects in the grid, and draws them at their locations
ActorWorld is a subclass of World
That has a step method that calls act() on each object in the Grid
Has methods for adding objects
public void add(Location loc, Actor theActor)
public void add(Actor theActor)
Adds the actor to a random location
Has a method for removing objects
Public Actor remove(Location loc)
Class Diagram : Class Diagram
Part 4: Interacting Objects : Part 4: Interacting Objects Critters are actors that have a common pattern for behavior
Use the same act() method
When a critter acts it:
gets a list of actors to process
ArrayList getActors()
processes the actors
void processActors(ArrayList actors);
generates a list of locations it can move to
ArrayList getMoveLocations()
selects a location
Location selectMoveLocation(ArrayList locList)
moves to the selected location
void makeMove(Location loc)
Exercise Set 7 : Exercise Set 7 What methods are implemented in Critter? What does each do?
What are the 5 basic actions common to all Critters when they act?
Should subclasses of Critter override the getActors() method?
Describe 3 ways a Critter could process actors?
What 3 methods must be invoked to make a Critter move? Explain each method.
Why is there no Critter constructor?
Exercise Answers Set 7 : Exercise Answers Set 7 What methods are implemented in Critter? What does each do?
act, getActors, processActors, getMoveLocations, selectMoveLocation, makeMove
Act checks that the Critter is in a grid and if so calls the other methods
getActors gets the neighboring Actors
processActors eats (removes) actors that are not Rocks or Critters
getMoveLocations returns valid empty neighboring locations (1 cell away)
selectMoveLocation returns current location if no empty neighbors or a random empty neighbor
makeMove if the location is null remove self from grid otherwise move to the location
What are the 5 basic actions common to all Critters when they act?
Get actors to process, process the actors, get a list of locations, select a location, move
Should subclasses of Critter override the getActors() method?
Yes, if they want to control the type of actors to interact with or to get more than just the neighboring Actors (one cell away)
Describe 3 ways a Critter could process actors?
Change their color, Change their direction, remove them from the grid, etc
What 3 methods must be invoked to make a Critter move?
getMoveLocations, selectMoveLocation, makeMove.
Why is there no Critter constructor?
Because it inherits from Actor and Actor has a no-arg constructor so by not providing any constructors the compiler will add a no-arg constructor that calls super()
Extending the Critter Class : Extending the Critter Class ChameleonCritter
Overrides processActors to pick a random actor and change its current color to the actor’s color
Overrides makeMove to also turn toward the new location
CrabCritter
Overrides getActors to get actors straight ahead, diagonal left, and diagonal right (from front)
Overrides getMoveLocations to only move to the left or right
Overrides makeMove so that if it doesn’t move it randomly turns left or right
Exercise Set 8 : Exercise Set 8 Why does act cause a ChameleonCritter to act differently than a Critter even though act is not overriden?
Why does the makeMove method of ChameleonCritter call super.makeMove?
How would you make a ChameleonCritter drop a flower in the old location when it moves?
Why doesn’t ChameleonCritter override the getActors method?
Which class contains the getLocation method?
How can a Critter access its own grid?
Exercise Answers Set 8 : Exercise Answers Set 8 Why does act cause a ChameleonCritter to act differently than a Critter even though act is not overriden?
Because some of the methods act calls are overriden
Why does the makeMove method of ChameleonCritter call super.makeMove?
Because it wants to do the same actions as the parent class
How would you make a ChameleonCritter drop a flower in the old location when it moves?
Save the current location before you move and then create a flower and add it to this saved location just like in Bug
Why doesn’t ChameleonCritter override the getActors method?
It wants the same behavior
Which class contains the getLocation method?
Actor
How can a Critter access its own grid?
The inherited getGrid method (from Actor)
Exercise Set 9 : Exercise Set 9 Why doesn’t CrabCritter override the processActors method?
Describe the process CrabCritter uses to find and eat actors.
Does it always eat all neighboring actors?
Explain.
Why is the getLocationsInDirections method used in CrabCritter?
If a CrabCritter has location (3,4) and faces south what are the possible locations for actors returned by getActors?
What are the similarities and differences between the movements of a CrabCritter and a Critter?
How does a CrabCritter determine when it turns instead of moving?
Why don’t the CrabCitters objects eat each other?
Exercise Answers Set 9 : Exercise Answers Set 9 Why doesn’t CrabCritter override the processActors method?
Because it wants to eat the actors which is what the method in Critter does
Describe the process CrabCritter uses to find and eat actors.
Does it always eat all neighboring actors?
No only the ones in front, or diagonally left or right
Explain.
It overrides getActor to get only these and then calls processActors to eat them
Why is the getLocationsInDirections method used in CrabCritter?
To get the locations in front, diagonally left and right to get Actors in these locations
If a CrabCritter has location (3,4) and faces south what are the possible locations for actors returned by getActors?
(4,4), (4, 3), (4,5)
Exercise Answers Set 9 : Exercise Answers Set 9 What are the similarities and differences between the movements of a CrabCritter and a Critter?
If a CrabCritter can’t move it randomly turns left or right, if it can move it moves like a Critter
How does a CrabCritter determine when it turns instead of moving?
It turns only if it can’t move
Why don’t the CrabCitters objects eat each other?
Because processActors in Critter won’t eat other Critters and a CrabCritter is a type of Critter
Chapter 5: Grid Data Structures : Chapter 5: Grid Data Structures AbstractGrid defines methods that are common to BoundedGrid and UnboundedGrid
public ArrayList getNeighbors(Location loc)
public ArrayList getValidAdjacentLocations(Location loc)
public ArrayList getEmptyAdjacentLocations(Location loc)
public ArrayList getOccupiedAdjacentLocations(Location loc)
public String toString()
This class must be abstract as it implements Grid but doesn’t define all the methods specified in the Grid interface
These are defined in BoundedGrid and UnboundedGrid
Grid Class Diagram : Grid Class Diagram
Exercise Set 10 : Exercise Set 10 Where is the isValid method specified?
Which classes implement this method?
Which AbstractGrid methods call the isValid method? Why don’t other methods call it?
Which methods of the Grid interface are called by the getNeighbors method?
Which classes implement these methods?
Why must the get method which returns objects of type E be used in the getEmptyAdjacentLocations method when this method returns Location objects?
What would be the affect of replacing the constant Location.HALF_RIGHT with Location.RIGHT where it appears in getValidAdjacentLocatins?
Exercise Answers Set 10 : Exercise Answers Set 10 Where is the isValid method specified?
In concrete subclasses of AbstractGrid
Which classes implement this method?
BoundedGrid and UnboundedGrid
Which AbstractGrid methods call the isValid method? Why don’t other methods call it?
getValidAdjacentLocations others don’t because they call this method
Which methods of the Grid interface are called by the getNeighbors method?
getOccupiedAdjacentLocations
Which classes implement these methods?
AbstractGrid
Why must the get method which returns objects of type E be used in the getEmptyAdjacentLocations method when this method returns Location objects?
Because that is how it checks that the location is empty
What would be the affect of replacing the constant Location.HALF_RIGHT with Location.RIGHT where it appears in getValidAdjacentLocatins?
It wouldn’t get diagonal neighbors
BoundedGrid Class : BoundedGrid Class Fixed number of rows and columns
Throws runtime exception if you try to access a location outside the grid
Stores objects in a two-dimensional array
private Object[][] occupantArray;
Can’t declare an array of a generic type in Java
Exercise Set 11 : Exercise Set 11 What ensures that a grid has at least one valid location?
How is the number of columns in the grid determined? What assumption makes this possible?
What are the requirements for a Location to be valid in a BoundedGrid?
What type is returned by the getOccupiedLocations method? What is the time complexity (Big-Oh) for this method?
What type is returned by the get method? What is the time complexity (Big-Oh) for this method?
What conditions cause an exception to be thrown by the put method? What is the Big-Oh?
What type is returned by the remove method? What happens if you try to remove from an empty location? What is the Big-Oh?
Based on your answers to 4-7 is this an efficient implementation?
Exercise Answers Set 11 : Exercise Answers Set 11 What ensures that a grid has at least one valid location?
The constructor checks that the number of rows and columns is at least 1
How is the number of columns in the grid determined? What assumption makes this possible?
return occupantArray[0].length; That there is at least one row and that this is an array of arrays with the inner array being the columns.
What are the requirements for a Location to be valid in a BoundedGrid?
The row index is >= 0 and < num rows, the col index is >= 0 and less than the number of columns
What type is returned by the getOccupiedLocations method? What is the time complexity (Big-Oh) for this method?
ArrayList O(r * c) where r is the number of rows and c is the number of cols
What type is returned by the get method? What is the time complexity (Big-Oh) for this method?
E O(1)
What conditions cause an exception to be thrown by the put method? What is the Big-Oh?
If the location isn’t valid or the object is null O(1)
What type is returned by the remove method? What happens if you try to remove from an empty location? What is the Big-Oh?
E, nothing it just returns null, O(1)
Based on your answers to 4-7 is this an efficient implementation?
It is pretty efficient for arrays that aren’t too big. If the array is really big and doesn’t include many objects then there are better ways to do the getOccupiedLocations
UnboundedGrid : UnboundedGrid All locations are valid even if the row and col are negative
Stores objects in a Map
getNumRows() and getNumCols()
return -1
Exercise Set 12 : Exercise Set 12 Which method must the Location class implement so that Location can be used as the key to the map? What would be required if the Map was a TreeMap? Does Location satisfy these requirements?
Why are the checks for null included in the get, put, and remove methods? Why don’t the methods in BoundedGrid do this?
What is the average time complexity (Big-Oh) for get, put, and remove? What would it be if TreeMap where used instead of HashMap?
How would the behavior of the class differ, aside from time complexity if TreeMap where used instead of HashMap?
Could you use a Map for a BoundedGrid? Is there an advantage to using a 2-D array for a BoundedGrid?
Exercise Answers Set 12 : Exercise Answers Set 12 Which method must the Location class implement so that Location can be used as the key to the map? What would be required if the Map was a TreeMap? Does Location satisfy these requirements?
hashCode, implement Comparable consistent with equals, Yes
Why are the checks for null included in the get, put, and remove methods? Why don’t the methods in BoundedGrid do this?
You can only have one null key in a HashMap
What is the average time complexity (Big-Oh) for get, put, and remove? O(1) What would it be if TreeMap where used instead of HashMap?
How would the behavior of the class differ, aside from time complexity if TreeMap where used instead of HashMap?
The keys would be kept in sorted order in a TreeMap.
Could you use a Map for a BoundedGrid? Is there an advantage to using a 2-D array for a BoundedGrid?
Yes, but it would take more space for a small bounded grid and be less efficient when the grid was fairly full.