import java.util.ArrayList;
public abstract class ListEnv extends SquareEnvironment
{
private ArrayList objectList;
public ListEnv()
{
objectList = new ArrayList();
}
public abstract int numRows();
public abstract int numCols();
public abstract boolean isValid(Location loc);
// The rest of the methods copied from UnboundedEnv
/** Returns the number of objects in this environment.
* @return the number of objects
**/
public int numObjects()
{
return objectList.size();
}
/** Returns all the objects in this environment.
* @return an array of all the environment objects
**/
public Locatable[] allObjects()
{
Locatable[] objectArray = new Locatable[objectList.size()];
// Put all the environment objects in the list.
for ( int index = 0; index < objectList.size(); index++ )
{
objectArray[index] = (Locatable) objectList.get(index);
}
return objectArray;
}
/** Determines whether a specific location in this environment is
* empty.
* @param loc the location to test
* @return true
if loc
is a
* valid location in the context of this environment
* and is empty; false
otherwise
**/
public boolean isEmpty(Location loc)
{
return (objectAt(loc) == null);
}
/** Returns the object at a specific location in this environment.
* @param loc the location in which to look
* @return the object at location loc
;
* null
if loc
is empty
**/
public Locatable objectAt(Location loc)
{
int index = indexOf(loc);
if ( index == -1 )
return null;
return (Locatable) objectList.get(index);
}
/** Creates a single string representing all the objects in this
* environment (not necessarily in any particular order).
* @return a string indicating all the objects in this environment
**/
public String toString()
{
Locatable[] theObjects = allObjects();
String s = "Environment contains " + numObjects() + " objects: ";
for ( int index = 0; index < theObjects.length; index++ )
s += theObjects[index].toString() + " ";
return s;
}
// modifier methods
/** Adds a new object to this environment at the location it specifies.
* (Precondition: obj.location()
is a valid empty location.)
* @param obj the new object to be added
* @throws IllegalArgumentException if the precondition is not met
**/
public void add(Locatable obj)
{
// Check precondition. Location should be empty.
Location loc = obj.location();
if ( ! isEmpty(loc) )
throw new IllegalArgumentException("Location " + loc +
" is not a valid empty location");
// Add object to the environment.
objectList.add(obj);
}
/** Removes the object from this environment.
* (Precondition: obj
is in this environment.)
* @param obj the object to be removed
* @throws IllegalArgumentException if the precondition is not met
**/
public void remove(Locatable obj)
{
// Find the index of the object to remove.
int index = indexOf(obj.location());
if ( index == -1 )
throw new IllegalArgumentException("Cannot remove " +
obj + "; not there");
// Remove the object.
objectList.remove(index);
}
/** Updates this environment to reflect the fact that an object moved.
* (Precondition: obj.location()
is a valid location
* and there is no other object there.
* Postcondition: obj
is at the appropriate location
* (obj.location()
), and either oldLoc
is
* equal to obj.location()
(there was no movement) or
* oldLoc
is empty.)
* @param obj the object that moved
* @param oldLoc the previous location of obj
* @throws IllegalArgumentException if the precondition is not met
**/
public void recordMove(Locatable obj, Location oldLoc)
{
int objectsAtOldLoc = 0;
int objectsAtNewLoc = 0;
// Look through the list to find how many objects are at old
// and new locations.
Location newLoc = obj.location();
for ( int index = 0; index < objectList.size(); index++ )
{
Locatable thisObj = (Locatable) objectList.get(index);
if ( thisObj.location().equals(oldLoc) )
objectsAtOldLoc++;
if ( thisObj.location().equals(newLoc) )
objectsAtNewLoc++;
}
// There should be one object at newLoc. If oldLoc equals
// newLoc, there should be one at oldLoc; otherwise, there
// should be none.
if ( ! ( objectsAtNewLoc == 1 &&
( oldLoc.equals(newLoc) || objectsAtOldLoc == 0 ) ) )
{
throw new IllegalArgumentException("Precondition violation moving "
+ obj + " from " + oldLoc);
}
}
// internal helper method
/** Get the index of the object at the specified location.
* @param loc the location in which to look
* @return the index of the object at location loc
* if there is one; -1 otherwise
**/
protected int indexOf(Location loc)
{
// Look through the list to find the object at the given location.
for ( int index = 0; index < objectList.size(); index++ )
{
Locatable obj = (Locatable) objectList.get(index);
if ( obj.location().equals(loc) )
{
// Found the object -- return its index.
return index;
}
}
// No such object found.
return -1;
}
}