import java.util.LinkedList; import java.util.Iterator: public class SMBoundedEnv extends SquareEnvironment { private LinkedList[] rows; private int numberOfCols; public SMBoundedEnv(int nRows, int nCols) { super(); numberOfCols = nCols; rows = new LinkedList[nRows]; for ( int index = 0; index < rows.length; index++ ) rows[index] = new LinkedList(); } public int numRows() { return rows.length; } public int numCols() { return numberOfCols; } public int numObjects() { int objectCount = 0; for ( int index = 0; index < rows.length; index++ ) objectCount += rows[index].size(); return objectCount; } public Locatable[] allObjects() { Locatable[] theObjects = new Locatable[numObjects()]; int tempObjectCount = 0; // Step through all the rows. for ( int index = 0; index < rows.length; index++ ) { // Step through all the objects in this row. Iterator itr = rows[index].iterator(); while ( itr.hasNext() ) { // Put the next object in the array. theObjects[tempObjectCount] = (Locatable)itr.next(); tempObjectCount++; } } return theObjects; } public boolean isValid(Location loc) { if ( loc == null ) return false; return (0 <= loc.row() && loc.row() < numRows()) && (0 <= loc.col() && loc.col() < numCols()); } public boolean isEmpty(Location loc) { return isValid(loc) && objectAt(loc) == null; } public Locatable objectAt(Location loc) { if ( ! isValid(loc) ) return null; // Step through all the objects in the row for location loc Iterator itr = rows[loc.row()].iterator(); while ( itr.hasNext() ) { // Is this object at the location we're looking for? Locatable obj = (Locatable) itr.next(); if ( obj.location().equals(loc) ) { // Found the object -- return it. return obj; } } return null; } // modifier methods public void add(Locatable obj) { Location loc = obj.location(); if ( ! isEmpty(loc) ) throw new IllegalArgumentException("Location " + loc + " is not a valid empty location"); // Add object to the environment. rows[loc.row()].add(obj); } public void remove(Locatable obj) { // Make sure that the object is there to remove. Location loc = obj.location(); if ( objectAt(loc) != obj ) throw new IllegalArgumentException("Cannot remove " + obj + "; not there"); // Remove the object from the environment. rows[loc.row()].remove(obj); } public void recordMove(Locatable obj, Location oldLoc) { // Simplest case: There was no movement. Location newLoc = obj.location(); if ( newLoc.equals(oldLoc) ) return; // Verify that there wasn't already an object at new location. Iterator itr = rows[newLoc.row()].iterator(); while ( itr.hasNext() ) { Locatable current = (Locatable) itr.next(); if ( current.location().equals(newLoc) && current != obj ) { throw new IllegalArgumentException("There's already " + "an object (" + current + ") at location " + newLoc); } } // If object stayed within same row, no change made; // otherwise remove object and add it to new row. if ( newLoc.row() != oldLoc.row() ) { // Remove object from old row and add it to new row. rows[oldLoc.row()].remove(obj); add(obj); } } }