56
© A+ Computer Science - www.apluscompsci.com

© A+ Computer Science - . Row = 0 Column = 0

Embed Size (px)

Citation preview

Page 1: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 2: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Row = 0

Column = 0

Page 3: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

A grid is a structure that has rows and columns.

rows

cols

Page 4: © A+ Computer Science - . Row = 0 Column = 0

Chapter 3: GridWorld Classes

and Interfaces

Page 5: © A+ Computer Science - . Row = 0 Column = 0

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

<<interface>>Grid<Actor>

AbstractGrid<Actor>

BoundedGrid<Actor> UnboundedGrid<Actor>

Actor

implements

uses

extends

Bug

extends

Flower Rock

uses

uses

Page 6: © A+ Computer Science - . Row = 0 Column = 0

Location Class Encapsulates the coordinates for an

actor’s position in a grid Row and Column number

Rows increase going down Columns increase going right

Also has methods that determine relationships between locations and compass directions

Every actor has a direction 0 for north, 45 is northeast, …

Location class also has eight constants that specify the constant direction

NORTH, NORTHEAST, …

Page 7: © A+ Computer Science - . Row = 0 Column = 0

Location Class

public Location(int r, int c)constructs a location with row r and column c

public int getRow()returns the row of this location

public int getCol()returns the column of this location

public Location getAdjacentLocation(int direction)returns the adjacent location in the compass direction that is closest to direction

public int getDirectionToward(Location target)returns the closest compass direction from this location toward target

Testable API

Page 8: © A+ Computer Science - . Row = 0 Column = 0

Location Classpublic boolean equals(Object other)

returns true if other is a Location object with the same row and column values as this location, and false otherwise

public int hashCode()returns a hash code (unique key) for this location

public int compareTo(Object otherObject)returns a negative integer if this location is less than other (if the row is less than other.row or if the rows are equal and column is less than other.column), zero if the two locations are equal, or a positive integer if this location is greater than other. Locations are ordered in row-major order

public String toString()returns a string with the row and the column of this location, in the format (row, col)

Testable API

Page 9: © A+ Computer Science - . Row = 0 Column = 0

Location Class

Compass directions:public static final int NORTH = 0;public static final int EAST = 90;public static final int SOUTH = 180;public static final int WEST = 270;public static final int NORTHEAST = 45;public static final int SOUTHEAST = 135;public static final int SOUTHWEST = 225;public static final int NORTHWEST = 315;

Page 10: © A+ Computer Science - . Row = 0 Column = 0

Location Class

Turn angles:public static final int LEFT = -90;

public static final int RIGHT = 90;

public static final int HALF_LEFT = -45;

public static final int HALF_RIGHT= 45;

public static final int FULL_CIRCLE = 360;

public static final int HALF_CIRCLE = 180 ;

public static final int AHEAD = 0;

Page 11: © A+ Computer Science - . Row = 0 Column = 0

Examples

Location loc1 = new Location(5,7);Location locOrig = new Location(0,0);

Location loc2 = loc1.getAdjacentLocation(Location.WEST);// (5,6)Location loc3 = loc1.getAdjacentLocaton(Location.NORTHEAST);// (4,8)Location loc4 = locOrig.getAdjacentLocaton(Location.WEST);// (0,-1)int dir = loc1.getDirectionToward(new Location(6,8));// 135

Page 12: © A+ Computer Science - . Row = 0 Column = 0

Turning by an Amount

You may 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

Page 13: © A+ Computer Science - . Row = 0 Column = 0

Exercise Set 3Location loc1 = new Location(4, 3);Location loc2 = new Location(3, 4);

1. How would you access the row value of loc1? loc1.getRow()

2. What is the value of b after the following statement is executed?boolean b = loc1.equals(loc2);false

3. What is the value of loc3 after the following?Location loc3 = loc2.getAdjacentLocation(Location.SOUTH);(4, 4)

4. What is the value of dir after the following?int dir = loc1.getDirectionToward(new Location(6,1));225

5. How does the getAdjacentLocation method know which location to return? It first takes the direction passed to it and converts it to the closest 45

degree direction. Then it looks in that direction to return the adjacent location

Page 14: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 15: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Grid is an interface that details thebehaviors expected of a grid. All its methods are abstract methods (no code).

Grid was designed as an interface because many different structures could be used to store the grid values.

An interface works perfectly in this case due to the large number of unknowns.

Page 16: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

A grid can store any type of Object.

Grid<Integer> intGrid;intGrid = new BoundedGrid<Integer>(5,5);

Grid<String> stringGrid;stringGrid = new UnboundedGrid<String>();

Page 17: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Gridabstract methods

Name Useget(loc) returns the object reference at location loc

getEmptyAdjacentLocations(loc) returns an ArrayList of the valid empty locations in 8 directions

getNeighbors(loc) returns an ArrayList of the objects around location loc

getNumCols() returns the number of columns in this grid

getNumRows() returns the number of rows in this grid

getOccupiedAdjacentLocations(loc)

returns an ArrayList of the valid locations in 8 directions that contain objects

getOccupiedLocations() returns an ArrayList of locations in the entire grid that contain objects

import info.gridworld.grid.Grid;

Note: loc is a reference to a Location object.

Page 18: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Gridabstract methods (continued)Name Use

getValidAdjacentLocations(loc) returns an ArrayList of the valid locations in 8 directions

isValid(loc) checks to see if location is valid (returns true/false)

put(loc, obj) puts the obj in grid at location loc. Returns the object that was previously in the location. Note: If you want to add Actors to a world, then don’t use grid.put() since it will not update the location of the Actor. Use world.add() instead.

remove(loc) takes the object at location loc out of the grid. Returns the object that was removed. Note: Use world.remove() instead of grid.remove() when removing Actors.

import info.gridworld.grid.Grid;

Note: loc is a reference to a Location object. obj is a reference to an Object.

Page 19: © A+ Computer Science - . Row = 0 Column = 0

Grid Interfaceint getNumRows()

returns the number of rows, or -1 if this grid is unbounded

int getNumCols()returns the number of columns, or -1 if this grid is unbounded

Boolean isValid(Location loc)returns true if loc is valid in this grid, false otherwiseprecondition: loc is not null

E put(Location loc, E obj)puts obj at location loc in this grid and returns the object previously at that location (or null if the location was previously empty)precondition: loc is valid in this grid and obj is not null

Testable API

E stands for Object

Page 20: © A+ Computer Science - . Row = 0 Column = 0

Grid InterfaceE remove(Location loc)

removes the object at location loc and returns it (or null if the location is unoccupied)precondition: loc is valid in this grid

E get(Location loc)returns the object at location loc (or null if the location is unoccupied)precondition: loc is valid in this grid

ArrayList<Location> getOccupiedLocations()returns all occupied locations in this grid

ArrayList<Location> getValidAdjacentLocations(Location loc)returns all valid locations adjacent to loc in this grid. The Array list is populated by going clockwise beginning at the adjacent north location

precondition: loc is valid in this grid

Testable API

Page 21: © A+ Computer Science - . Row = 0 Column = 0

Grid InterfaceArrayList<Location> getEmptyAdjacentLocations(Location

loc)returns all valid empty locations adjacent to loc in this gridprecondition: loc is valid and in this grid

ArrayList<Location> getOccupiedAdjacentLocations(Location loc)returns all valid occupied locations adjacent to loc in this grid

precondition: loc is valid in this grid

ArrayList<E> getNeighbors(Location loc)returns all objects in the occupied locations adjacent to loc in this gridprecondition: loc is valid in this grid

Note: All the Grid methods that look at adjacent locations and return an array list will populate the array list by first looking at the adjacent north location and then going clockwise to retrieve all applicable locations

Testable API

Page 22: © A+ Computer Science - . Row = 0 Column = 0

Exercise Answers Set 4Assume we have a BoundedGrid reference named grid.

1. How can you get a count of the objects in the grid? grid.getOccupiedLocations().size()

2. How can you get a count of the empty locations in the grid? grid.getNumRows() * grid.getNumCols() – grid.getOccupiedLocations.size()

3. How can you check if location (10,10) is in the grid? if (grid.isValid(new Location(10,10)))

4. Grid contains method declarations but no code. Why? It is an interface

5. Where can you find the code for the methods? In the classes that implement the interface: BoundedGrid and UnboundedGrid

6. 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.

Page 23: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

BoundedGrid<Integer> grid;grid = new BoundedGrid<Integer>(5,5);grid.put(new Location(2,2),4);grid.put(new Location(1,1),11);System.out.println(grid);System.out.println(grid.isValid(new Location(-2,3)));System.out.println(grid.isValid(new Location(2,3))); OUTPUT{(1, 1)=11, (2, 2)=4}falsetrue

11

4

Page 24: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

BoundedGrid<Integer> grid;grid = new BoundedGrid<Integer>(5,5);grid.put(new Location(2,2),4);grid.put(new Location(1,1),11);grid.put(new Location(0,2),3);grid.put(new Location(0,1),6); System.out.println(grid);grid.remove(new Location(1,1));System.out.println(grid);grid.remove(new Location(1,1));System.out.println(grid); World world = new World(grid);world.show();

OUTPUT{(0, 1)=6, (0, 2)=3, (1, 1)=11, (2, 2)=4}{(0, 1)=6, (0, 2)=3, (2, 2)=4}{(0, 1)=6, (0, 2)=3, (2, 2)=4}

Page 25: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 26: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

UnboundedGrid<Integer> grid;grid = new UnboundedGrid<Integer>();System.out.println(grid.getNumRows());System.out.println(grid.getNumCols());System.out.println(grid);World world = new World(grid);world.show();

OUTPUT-1-1{}

Page 27: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 28: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

UnboundedGrid<Integer> grid;grid = new UnboundedGrid<Integer>();grid.put(new Location(2,2),4);grid.put(new Location(1,1),11);System.out.println(grid);System.out.println(grid.isValid(new Location(-2,3)));System.out.println(grid.isValid(new Location(2,3))); World world = new World(grid);world.show();

OUTPUT{(1, 1)=11, (2, 2)=4}truetrue

11

4

Page 29: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

UnboundedGrid<Integer> grid;grid = new UnboundedGrid<Integer>();grid.put(new Location(2,2),4);grid.put(new Location(1,1),11);grid.put(new Location(0,2),3);grid.put(new Location(0,1),6); grid.put(new Location(-2,-2),-2); System.out.println(grid);grid.remove(new Location(1,1));System.out.println(grid);grid.remove(new Location(1,1));System.out.println(grid); World world = new World(grid);world.show();

OUTPUT{(0, 1)=6, (0, 2)=3, (-2, -2)=-2, (2, 2)=4, (1, 1)=11}{(0, 1)=6, (0, 2)=3, (-2, -2)=-2, (2, 2)=4}{(0, 1)=6, (0, 2)=3, (-2, -2)=-2, (2, 2)=4}

Page 30: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 31: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 32: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Worldfrequently used methods

Name Use

World() creates a new world using 10X10 grid

World(grid) creates a new world using grid

add(loc, obj) add obj to world at location loc

show() makes the world visible

import info.gridworld.world.World;

Page 33: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

World<Monster> world = new World<Monster>();world.add(new Location(0,0), new Monster());world.add(new Location(9,0), new Monster()); world.show(); orGrid<Monster> grid = new BoundedGrid<Monster>(10,10); World world = new World(grid);grid.put(new Location(0,0), new Monster());grid.put(new Location(9,0), new Monster()); world.show();

Page 34: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 35: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Worldfrequently used methods

Name UsegetGrid() returns a reference to the world’s

grid

remove(loc) removes the object at location loc

locationClicked(loc)

activated by a mouse click in the grid.Returns boolean (true). You can control what happens when clicking a cell.

import info.gridworld.world.World;

Page 36: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

BoundedGrid<Integer> grid;grid = new BoundedGrid<Integer>(5,5);grid.put(new Location(2,2),4);grid.put(new Location(1,1),9);grid.put(new Location(0,4),11);grid.put(new Location(4,3),5);grid.put(new Location(2,0),1);

World<Integer> world;world = new World<Integer>(grid);world.show();

Page 37: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

World<Monster> world;world = new World<Monster>(new BoundedGrid(6,6));world.show(); Grid<Monster> grid = world.getGrid();for(int r=0; r<grid.getNumRows(); r++){ for(int c=0; c<grid.getNumCols(); c++) { grid.put(new Location(r,c), new Monster(r,c,2)); }}

Page 38: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

import info.gridworld.world.World;import info.gridworld.grid.Location;

public class RowColMultiplyWorld extends World{

public boolean locationClicked(Location loc){

add(loc, new RowColMultiplyBug(loc.getCol()*loc.getRow()));System.out.println("Location "+loc+" clicked");return true;

}}

Page 39: © A+ Computer Science - . Row = 0 Column = 0

© A+ Computer Science - www.apluscompsci.com

Page 40: © A+ Computer Science - . Row = 0 Column = 0

Actor Classpublic Actor()

constructs a blue actor that is facing north

public Color getColor()returns the color of this actor

public void setColor(Color newColor)sets the color of this actor to newColor

public int getDirection()returns the direction of this actor, an angle between 0 and 359 degrees

public void setDirection(int newDirection)sets the direction of this actor to the angle between 0 a nd 359 degrees that is equivalent to newDirection

Testable API

Page 41: © A+ Computer Science - . Row = 0 Column = 0

Actor Classpublic Grid <Actor> getGrid()

returns the grid of this actor, or null if this actor is not contained in the grid

public Location getLocation()returns the location of this actorprecondition: this actor is contained in this grid

public void putSelfInGrid(Grid<Actor> gr, Location loc)puts this actor into the location loc of the grid gr. If there is another actor at loc, it is removed.precondition: this actor is not contained in a grid and loc is valid in gr

public void removeSelfFromGrid()removes this actor from its gridprecondition: this actor is contained in a grid

Testable API

Page 42: © A+ Computer Science - . Row = 0 Column = 0

Actor Classpublic void moveTo(Location newLocation)

moves this actor to newLocation. If there is another actor at newLocation, it is removed.

precondition: this actor is contained in a grid and newLocation is valid in the grid of this actor

public void act()

reverses the direction of this actor. Override this method in subclasses of Actor to define types of actors with different behavior

public String toString()

returns a string with the location, direction, and color of this actor

Testable API

Page 43: © A+ Computer Science - . Row = 0 Column = 0

Rock and Flower Classes

Subclasses of ActorOverride act()

Rocks don’t do anything in the act methodEmpty body {}

Flowers change the color Reduces the red, green, and blue by the

same amount (0.05)Gets darker

Testable API

Page 44: © A+ Computer Science - . Row = 0 Column = 0

Exercise Set 51. Name 3 properties that every Actor has.

Color, direction, location2. When an actor is constructed what is its direction and color?

Blue and North3. 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.

4. Can an Actor put itself in the grid twice without removing itself? No, you will get an IllegalStateException

5. Can an Actor remove itself from the grid twice? No, you will get an IllegalStateException

6. 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.

7. How can an actor turn 90 degrees to the right? setDirection(getDirection() + Location.RIGHT);

Page 45: © A+ Computer Science - . Row = 0 Column = 0

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)

Implementation Testable

Page 46: © A+ Computer Science - . Row = 0 Column = 0

Bug Class

public class Bug extends Actor{ public Bug() { setColor(Color.RED); }

/** * Constructs a bug of a given color. * @param bugColor the color for this bug */ public Bug(Color bugColor) { setColor(bugColor); }

Implementation

Page 47: © A+ Computer Science - . Row = 0 Column = 0

Bug Classpublic void act(){ if (canMove()) move(); else turn();}/* Turns the bug 45 degrees to the right without changing its location.*/public void turn(){ setDirection(getDirection() + Location.HALF_RIGHT);}

Implementation

Page 48: © A+ Computer Science - . Row = 0 Column = 0

Bug Class/** * Moves the bug forward, putting a flower into the location it

previously occupied. */ public void move() { Grid<Actor> gr = getGrid(); if (gr == null) return; Location loc = getLocation(); Location next = loc.getAdjacentLocation(getDirection()); if (gr.isValid(next)) moveTo(next); else removeSelfFromGrid(); Flower flower = new Flower(getColor()); flower.putSelfInGrid(gr, loc); }

Implementation

Page 49: © A+ Computer Science - . Row = 0 Column = 0

Bug Class/** * Tests whether this bug can move forward into a location that is empty or * contains a flower. * @return true if this bug can move. */

public boolean canMove() { Grid<Actor> 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 }

Implementation

Page 50: © A+ Computer Science - . Row = 0 Column = 0

Exercise Set 6

1. Which statement in the canMove() method ensures that a bug doesn’t move out of the grid?

• if (!gr.isValid(next))2. Which statement in the canMove() method keeps a bug from walking into a

rock?• return (neighbor == null) || (neighbor instanceof Flower);

3. 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 valid• get() is used to get the object in the grid in front of the bug

4. Which method in the Location class is invoked in the canMove() method and why?

• getAdjacentLocation() is used to get the location in front of the bug5. 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• getLocation() is used to get the current location of the bug • getDirection() is used to find the adjacent location in front of the bug

Page 51: © A+ Computer Science - . Row = 0 Column = 0

Exercise Set 6

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 grid7. 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

8. 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 from9. When a bug removes itself from the grid, will it place a flower in its previous

location?• Yes

10. Which statement in the move() method places a flower in the grid at the previous location?

• flower.putSelfInGrid(gr, loc);11. If a bug needs to turn 180 degrees how many times should it call the turn()

method?• 180 / 45 = 4

Page 52: © A+ Computer Science - . Row = 0 Column = 0

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 This happens when the World’s show() method is executed.

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)

optional

Page 53: © A+ Computer Science - . Row = 0 Column = 0

step() method in ActorWorld class

public void step() { Grid<Actor> gr = getGrid(); ArrayList<Actor> actors = new ArrayList<Actor>(); for (Location loc : gr.getOccupiedLocations()) actors.add(gr.get(loc));

for (Actor a : actors) { // only act if another actor hasn't removed a if (a.getGrid() == gr) a.act(); } }

Page 54: © A+ Computer Science - . Row = 0 Column = 0

Class Diagram

Page 55: © A+ Computer Science - . Row = 0 Column = 0

Jumper Activity In groups of 3 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 and put the answers to these questions in comments at the beginning of the program: What happens if the next location is empty but the location

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?

Page 56: © A+ Computer Science - . Row = 0 Column = 0

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 overridden? 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