Tips on Using the CS 540 Agent World Simulator
Introduction(Note that a CS540 FAQ on the Agent World Simulator will be created as questions arise from students during the semester.)
The Agent World is a test-bed for artificial intelligence techniques in a simplified universe. The universe consists of four types of entities: animals (also know as, 'agents' or 'players'), minerals, vegetables, and walls. One or more agents will be in a universe at a time. For each action an agent takes, it receives a reward. Negative rewards include running into walls (-1), pushing minerals (-2), bumping into other agents (-3), and running into sliding minerals (-25). Positive rewards include eating vegetables (+5), and pushing minerals into other agents (+25). Note that although an agent receives a slight negative reward for pushing a mineral, it receives a large positive reward if a mineral it has pushed slides into another agent. If an agent does not run into any other object, it receives a reward of zero.
We provide the code for the simulator, as well as the code to manipulate the agents and determine what objects are currently in their line of sight. Your job is to write the code that controls an agent in a (hopefully) intelligent way. Below is a list of suggestions to expedite this process.
Location and Naming of Files and Classes
The code you write for manipulating an agent will be placed in a class that is named after your username on the CS Dept computers (and not your DoIT account). This is done to ensure that all members of the class have a unique class name for the code that controls their agent; in this way, it will be possible to run all of the agents in the same environment. We will provide a skeleton for this class; your job is to fill in the code that makes the agent intelligent. Because agents are implemented as Java threads, the code that actually manipulates the agent must be placed in the run() function of your username class. Of course, we expect you to use good design techniques and to divide your code into appropriate functions; however, all of the code you write must be called from within the run() function (the run() function for threads is analogous to the main() function for normal programs).
To include your agent in the simulator, read the comments in your copy of the RunAgentWorld.java file. Be sure to properly name the file and class containing your agent.
Some Useful Functions
Some of the functions you will need in order to control your agent are described below.
Moves the agent in the specified direction. Because this function requires that the radians be positive, it is usually called this way: setMoveVector(Utils.convertToPositiveRadians(directionInRadians));
A negatively valued radians is interpreted as meaning 'stand still' (ie, don't move).
Returns an object of type Sensor, containing the type of object in each direction that the agent can see and how far away is the object in a particular direction. (This is part of the Player class and, hence, will be inherited.)
To examine a particular sensor, use sensors.getObjectType(dir), where dir = 0 ... Sensors.NUMBER_OF_SENSORS, to see what is sensed (the sensors have limited range, so often nothing is seen in a particular direction). To determine how far away an object in a given direction is, use sensors.getDistance(dir); this returns a double.
Here are the possible sensor types (they are constant integers):
Returns the reward the agent received for its last move. (This is part of the Player class and, hence, will be inherited.)
Returns the maximum distance agents can see in given direction.
The radius of ALL the objects (all are really circles internally).
Prints the name of the thread from which the function was called and a message.
The best way to become familiar with the Agent World is to write a simple program that always moves the agent in a constant direction. This will allow you to determine if you are controlling the agent properly.
When training an agent, it is often difficult to determine whether it is performing properly. The best way to make this determination is to break the agent's task into pieces. First, write the code for it to not bump into walls; then, add code for it to seek food; next, add the code for it to avoid rocks; etc. Alternatively, you can test your code on simplified universes with, for example, no objects except walls, or just walls and food, etc. This can be done by editing the main() function in the RunAgentWorld class and not calling or reducing the value of the arguments of aw.addMinerals() or aw.addVegetables().