CS 231: Project #4

Title image Spring 2018

Agent-Based Simulations

The main purpose of this project is to give you an opportunity to use your linked list within the context of an agent-based simulation.

In this week's simulation, we will have Agents that are on a 2D landscape. They will have positions in a continuous (floating point) 2D space, rather than the grid from the Game of Life. Like in the Game of Life, the agents are active and will implement an updateState method.

For this simulation, we won't have the concept of a scale factor, or you can think of the scale factor as being 1 so that coordinates map to pixels. If your Landscape's size is 500 by 500, then the Agents' positions should be between 0 and 500.

The Agent-based simulations were inspired by Growing Artificial Societies by Epstein and Axtell, two of the first researchers to make use computational modeling to examine social science questions about self-organizing societies.

Here is a GIF example of a working simulation in action:



Create an Agent class (it is up to you whether or not you want to make it abstract, but the instructions are written as if it is not). We will be making two forms of agents (agents with different updateState() methods). This means we will be using inheritance and need to begin with a base class - the Agent class. It needs fields to store the x and y positions (the type is double) and should implement the following methods:

Also, remember to import java.awt.Graphics so the compiler knows about the Graphics type.

Write a simple main method to test your class and the methods except for updateState and draw. You will need to comment out updateState until you have written the Landscape class


Create a SocialAgent class. The first agent we will implement will ultimately move towards other agents, creating groups of agents. SocialAgent will extend the Agent class.

public class SocialAgent extends Agent

The new class does not need any additional fields, but will need to override the constructor, updateState, and draw methods. We will save updateState for a later task. For now, implement these methods:

Copy your test method for the Agent class to the SocialAgent class, update it to create SocialAgent objects and test the new class.


Create a class called Landscape. It serves the same purpose as the Landscape in the Game of Life simulation, but is different enough that you probably don't want to copy the old one and edit it. Start with a new file. The Landscape will need fields to store its width and height (as ints) and a LinkedList of Agents. You need to use your implementation of a linked list). The Landscape needs the following methods:

Write a main test method, compile, run, and debug. Test everything but the draw method. At this point, you can also uncomment the updateState methods of your Agent and SocialAgent.


Make it possible to visualize your Landscape. Download the LandscapeDisplay.java file. It is almost identical to last week.

Test your visualization by running LandscapeDisplay as your main program. The main program adds 200 agents to the Landscape and then displays them.

updateState( )

Add a method to your SocialAgent class, public void updateState(Landscape scape). It should implement the following rules.

If the cell has more than 3 neighbors (Agents besides itself) within a radius of 15
    with a 1% chance, the cell should move randomly within the range [-5,5] 
    the cell should move randomly within the range [-5, 5]

Note that the Cell's motion should be a continuous value between +5 and -5 in both X and Y. You can use the Random class's nextFloat or nextDouble method to get a random floating point value between 0 and 1.0.

You can test your update state by creating a Landscape with four agents on it at locations (5, 5), (10, 10), (15, 15), and (20, 20). Call updateState on the agent at (5, 5) and have it print out the number of neighbors within a radius of 10 (there should be 1 besides itself). Reset the Cell positions and then repeat at radius 15 (there should be 2 besides itself), then reset and try a radius of 25 (there should be three).

It is your own design choice to decide whether to include an Agent in the neighbors list if the agent is at exactly at the location passed in as x0, y0.

updateAgents( )

Add a method to your Landscape class, public void updateAgents(), which updates the state of each agent, in a random order. Use your shuffled array method to get an ArrayList of Agents in randomized order, then use a foreach loop to call each agent's updateState method.


Create a SocialAgentSimulation class. It should be modeled after the LifeSimulation class. It would be best to control the Landscape size and the number of agents from the command line, but it is acceptable to hard-code them. Generate and randomly place N agents (and N of 200 is reasonable) on the Landscape. Then loop over the time steps, calling updateAgents, repaint, and Thread.sleep as in LifeSimulation. Use a good size radius, such as 15-25, to start your simulation. Do your agents clump together?


Create a CategorizedSocialAgent class that extends the SocialAgent class. This is our second agent (since CategorizedSocialAgent is a SocialAgent and SocialAgent is an Agent, CategorizedSocialAgent is also an Agent).

public class CategorizedSocialAgent extends SocialAgent

The new class should have an integer field category and implement or override the following methods.


Create a CategorizedSocialAgentSimulation class. Model this class after SocialAgentSimulation, using CategorizedSocialAgents instead of SocialAgents. Demonstrate it using 2 categories.

Compare your SocialAgentSimulation using two significantly different radii, including one that is very large. What happens?


  1. Instead of making separate main classes for each type of simulation, write just one Simulation class and make it possible for the user to control the type of SocialAgents from the command line.
  2. See if you can mix and match different agent types and write about what happens.
  3. Try out additional SocialAgent subclasses with different update rules.
  4. Experiment with the effects of modifying some of the update rules. These should be compare and contrast. Try to avoid comparing simulations where more than one thing has been changed.
  5. For any assignment, a good extension will be to implement a Java class that you haven't implemented in the past projects and demonstrate that it has the same functionality as the Java class. In this project, ArrayList would be a good class to try.
  6. Re-implement the Queue using an array-based method instead of a Node-based method and show the functionality is identical.


Your report should have a simple format.


Make your report for the project a wiki page in your personal space. If you have questions about making a wiki page, stop by my office or ask in lab.

Once you have written up your assignment, give the page the label:


You can give any wiki page a label using the label field at the bottom of the page. The label is different from the title.

Do not put code on your report page or anywhere it can be publicly accessed. To hand in code, put it in your folder on the Courses fileserver. Create a directory for each project inside the private folder inside your username folder.