Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Java Space Simulation Write a set of classes that define the behavior of differe

ID: 3766859 • Letter: J

Question

Java

Space Simulation

Write a set of classes that define the behavior of different objects in our space simulation. You are given starter code that, when complete, runs a simulation of a space with many objects moving around in it. Different kinds of objects will behave in different ways and you are defining those differences. In this world, some beings propagate their species by infecting others, which transforms the other object into the original object's species.

Objectives

Inheritance

Background

As with previous assignments, there is starter code for you to download here. These files must be in the same folder as the files you create.

The class SpaceItem is the super class for the other objects in our simulation. It has one method that must be overridden (the getMove() method). There are public methods as well as protected methods that your subclasses will inherit and you'll be able to use (protected means that they are available to the subclass implementation, but not to clients).

There are also useful enum definitions in SpaceItem.

On each round of the simulation, each object is asked what action it wants to perform. There are four possible responses, each with a constant associated with it.

Constant

Description

Action.MOVE

    Move forward one square in its current direction

Action.LEFT

    Turn left (rotate 90 degrees counter-clockwise)

Action.RIGHT

    Turn right (rotate 90 degrees clockwise)

Action.INFECT

    Infect the object in front of you

The getMove() method is passed an object of type SpaceItemInfo. This is an object that provides information about the current status of the object. It includes four methods for asking about surrounding neighbors, plus a method to find out the current direction this object is facing as well as a method to find out how many other objects this object has successfully infected. Below are the methods of the SpaceItemInfo class:

Method

Description

    public Neighbor getFront()

    returns neighbor in front of you

    public Neighbor getBack()

    returns neighbor in back of you

    public Neighbor getLeft()

    returns neighbor to your left

    public Neighbor getRight()

    returns neighbor to your right

    public Direction getDirection()

    returns direction you are facing

    public int getInfectCount()

    returns # of objects you have infected

The return type for the first four methods is Neighbor. There are four different constants for the different kind of neighbors you might encounter:

Constant

Description

Neighbor.WALL

    The neighbor in that direction is a wall

Neighbor.EMPTY

    The neighbor in that direction an empty square

Neighbor.SAME

    The neighbor in that direction is the same type

Neighbor.OTHER

    The neighbor in that direction is some other type

Notice that you are only told whether a neighbor is of your type or some other type. You can’t find out exactly what type it is.

The getDirection() method of the SpaceItemInfo class indicates what direction the object is facing. There are four direction constants:

Constant

Description

    Direction.NORTH

    facing north

    Direction.SOUTH

    facing south

    Direction.EAST

    facing east

    Direction.WEST

    facing west

Specification

You are to implement 4 subclasses of SpaceItem. The behavior of each specialized class is described below.

Class

getMove():Action

A

A Cruiser moves in a zig zag (MOVE, turn RIGHT, MOVE, turn LEFT). If it runs into a wall or anything else, turn AROUND, and start the sequence over.

^^

The unicode string for the infinity symbol is "u221e"

Aliens are predators. If there's another object in front, INFECT. Otherwise, an Alien travels around its neighborhood: five MOVES in one direction, then turn RIGHT, five MOVES in this new direction, then turn RIGHT, repeatedly. If it runs into a wall or another Alien, turn RIGHT and start over again.

Your choice

The constructors for these specialized classes must be have no parameters. The client code won't be able to compile otherwise.

You can add any private members (instance variables or methods) to these classes that are necessary for your design.That is your implementation choice. Be wise though about choices; not all variables should be instance variables.

You do not need to define any additional public methods for these classes.

Be smart when it comes to inheritance. Don't rewrite code that you don't have to.

You define the last class. Have fun with this: deciding what space object to model, and determining its state and its behavior. Part of your score will reflect how interesting and unique you make the behavior. It's also critical that your documentation is accurate.

For the random moves, you may use either a Random object or the Math.random() method to obtain pseudorandom values, although if you use a Random object, you are required to make it a field of your object so that you don’t have to construct a new one every time you use it.

The only mutator method is getMove(). Other methods are just answering a state.

Each of your SpaceItem classes has a pattern to it and at first all of your objects will be in synch with each other. But as they become infected, or run into other objects, they will get out of synch.

When an object is infected, it is replaced by a brand new SpaceItem of the other species, but that new object retains the properties of the old one. So it will be at the same location, facing in the same direction, and with the same infect count as the one it is replacing.

The simulator provides great visual feedback about where objects are, so you can watch them move around the world. But it doesn’t give great feedback about what direction they are facing. The simulator has a “debug” button that makes this easier to see. When you request debug mode, your objects will be displayed as arrow characters that indicate the direction they are facing.

The simulator also indicates the “step” number as the simulation proceeds (initially displaying a 0).

Documentation

Though the documentation in the classes other than SpaceItem and SpaceItemInfo is sparse, make sure to write proper documentation for your classes, both JavaDoc and internal.

It's important that your documentation for the last class is accurate and specific.

Constant

Description

Action.MOVE

    Move forward one square in its current direction

Action.LEFT

    Turn left (rotate 90 degrees counter-clockwise)

Action.RIGHT

    Turn right (rotate 90 degrees clockwise)

Action.INFECT

    Infect the object in front of you

Explanation / Answer


Introduction to ABM


Introduction ABM with Mason

Spring 2015

Psychology 120

Agent-Based Modeling with Mason

So far, we have learned a little bit about the Java programming language. To build an agent-based model in Java requires a LOT of programming and verification that the code written works as intended. A basic principle that we will be following is to use already developed and tested tools for modeling wherever possible. This is why we will be using a programming environment that already provides us with many of the tools we need to build ABMs. There are many simulation environment available and the list is growing. We will be using MASON. There are several reasons for this choice:

(1) The environment is Open Source.

(2) Because MASON is open source, we have access to the source code and the full power of Java, which allows us maximum flexibility to create ABMs that fit our specifications.

(3) MASON is extremely fast and has been optimized to run very fast, which is important for computationally intensive simulations.

There are drawbacks as well. To use MASON efficiently, one has to learn how to program in Java, which does take time and practice.

Building an ABM with MASON

To build an ABM in Mason requires us to learn new ideas in the Java programming language: interface and inheritance. Let’s go over these two ideas and how we use them in MASON to build ABMs.

Interfaces

In ABM, one of the fundamental things we do is to define classes of agents that can do things. We have already done this with our Talker agent. To create powerful and useful agents, we need a simulation environment that can run agents repeatedly without knowing the details of how the agent actually works. There is a problem, however, How is the simulation environment suppose to know what methods to call from the agents we define? That is, suppose we define a class of agent called “Particle” and we also define a method called “move,” how is the Mason simulation environment going to know what methods we have defined? Suppose we define several movement methods: “move1”, “move2”, and “move3”. How could it possibly know what methods we intend to use and their names?

This problem is solved by defining a basic interface for an agent with a method that the simulation environment already knows about. For MASON, this method is “step” and the interface is called “Steppable”. Let’s look at it.

/*

Copyright 2006 by Sean Luke and George Mason University

Licensed under the Academic Free License version 3.0

See the file "LICENSE" for more information

*/

package sim.engine;

/** Something that can be stepped */

public interface Steppable extends java.io.Serializable

    {

    public void step(SimState state);

    }

This interface class is found in MASON under sim.engine. Notice that there is no code to do anything, but the MASON simulation environment knows that any class that uses the interface “Steppable” has a method called “step” and that it has an parameter called “state” of the class “SimsState”, which we will talk about next.

Every agent that we define from now on will use the interface “Steppable”.

Inheritance

Recall from the first lecture on object-oriented programming and Java that one of the virtues of object-oriented programming is the reuse of code. Reusing code is good for at least two reasons. First, we don’t have to solve the problem again and write the code. Second, and perhaps most importantly, we can reuse code that has been tested and verified, so that we know that it works as intended.

We do this by the mechanism of inheritance. This amounts to defining a subclass based on an already defined class. In Java, every class we define is actually a subclass of the class Object, The class structure of Java is illustrated in the figure below.

Figure 1 All Classes in the Java Platform are Descendants of Object

In MASON, located in sim.engine is a class called SimState. The class SimState has lots of nice code in it already defined for defining a simulation environment. For example, it has a random object in it that is better than what we have been using and it has a Schedule object for running multiple agents on each step. When we define an Environment class for our agent-based models, we want it to be a subclass of SimState.

Particle Agents

Our first ABM will be quite simple. It will have particle agents that move around in a 2D environment. We will begin by defining a Particle class and defining their SimulationEnvironment as a subclass of SimState. Later, we will define a graphical user interface (GUI), but that can wait.

To make particle agents, we first have to define a class. Let’s call this class Particle. Let’s go ahead and make a new java project and package for our Particle and SimulationEnvrionment classes. Let’s make it so that it has the following structure:

particle_agents

     particles

          Particle

          SimulationEnvrionment

Let’s make both of these classes. When we are done, we have two classes that look like this:

package particles;

public class Particle{

}

and

package particles;

public class SimulationEnvironment{

}

We need to use MASON to make further progress, so let’s select the file “menu” and set “properties” so that our project knows where MASON is.

Now, we are going to put the ideas of interface and inheritance to work. First, we will use MASON to run all of the agents we define no matter what they do. The MASON simulation environment knows that all agents have a “step” method so we will make our particle class implement MASON’s Steppable interface. Once we do this, our Particle class will look like this:

package particles;

import sim.engine.*;

public class Particle implements Steppable{

        public void step(SimState state) {

               // TODO Auto-generated method stub

        }

}

To take advantage of MASON’s simulation environment, we will use inheritance to define a subclass that uses SimState plus what we add to it. to do that, we will use the keyword extends to make our Environment a subclass of MASON’s SimState. The result will look like this:

package particles;

import sim.engine.*;

public class Environment extends SimState {

        public Environment(long seed) {

               super(seed); //super uses the constructor method from the parent

                             //parent class.

               // TODO Auto-generated constructor stub

        }

}

The hard part starts now; we have to fill in the details.

SimulationEnvironment Class Agents

Let’s start by introducing a 2D space that our particles can move in. The space could be continuous or discrete. We will define a discrete space in which agents move to discrete cells. Our space could be represented by a lattice of cells as illustrated below.

As it turns out, MASON has classes for different kinds of spaces, so let’s use one of MASON’s classes for our space in the simulation environment. To add a space variable called particleSpace of the class SparseGrid2D, we can write the code as illustrated below:

package particles;

import sim.engine.*;

import sim.field.grid.SparseGrid2D;

public class Environment extends SimState {

        public SparseGrid2D particleSpace; //This is a 2D space in which bags

                                           //are created for each cell once an

        //agent or a particle first moves into a cell. This allows multiple

        //agents or particles to occupy the same cell.

        public Environment(long seed) {

               super(seed);

               // TODO Auto-generated constructor stub

        }

}

Before we can create a 2D space for our particles, we must specify the dimensions of the space. Lets call these variables gridWidth and gridHeight.

package particles;

import sim.engine.*;

import sim.field.grid.SparseGrid2D;

public class Environment extends SimState {

        public SparseGrid2D particleSpace; //This is a 2D space in which bags

                                           //are created for each cell once an

        //agent or a particle first moves into a cell. This allows multiple

        //agents or particles to occupy the same cell.

          public int gridWidth = 50; //the width of the grid

          public int gridHeight = 50; //the height of the grid

        public Environment(long seed) {

               super(seed);

               // TODO Auto-generated constructor stub

        }

}

To make the space that we will place particles in, we have to use the start method.

public void start() {

      super.start(); //use the previously defined code, then we add our own.

}

Notice a new keyword super, which is used to call up the previously defined code when we override what was previously written in the parent class. We will then add our own code after super.start(). Our SimulationEnvironment class now should look something like this:

package particles;

import sim.engine.*;

import sim.field.grid.SparseGrid2D;

public class Environment extends SimState {

        public SparseGrid2D particleSpace; //This is a 2D space in which bags

                                           //are created for each cell once an

        //agent or a particle first moves into a cell. This allows multiple

        //agents or particles to occupy the same cell.

        public int gridWidth = 50; //the width of the grid

         public int gridHeight = 50; //the height of the grid

        public Environment(long seed) {

               super(seed);

               // TODO Auto-generated constructor stub

        }

        public void start(){

               super.start();

               particleSpace = new SparseGrid2D(gridWidth, gridHeight); //create a 2D

               //space for our agents.

        }

}

Particles in Space

We have just defined how to create a space, now we need to make our particles and place them somewhere in our newly created space. First, we must specify how many particles we wish to make. Let’s make 100 particles (we could choose any positive integer within reason). We could specify this by writing:

public int n = 100; //The number of particles

Now, all we need to do is create 100 particles and put them into our 2D particleSpace. Where do we put them? We could put them in random locations like this:

package particles;

import sim.engine.*;

import sim.field.grid.SparseGrid2D;

public class Environment extends SimState {

        public SparseGrid2D particleSpace; //This is a 2D space in which bags

                                           //are created for each cell once an

        //agent or a particle first moves into a cell. This allows multiple

        //agents or particles to occupy the same cell.

        public int gridWidth = 50; //the width of the grid

         public int gridHeight = 50; //the height of the grid

         public int n = 100; //The number of particles

        public Environment(long seed) {

               super(seed);

               // TODO Auto-generated constructor stub

        }

        public void start(){

               super.start();

               particleSpace = new SparseGrid2D(gridWidth, gridHeight); //create a 2D

               //space for our agents.

               /*

               * Now, let's make n particles and put them into random

                 *locations in particleSpace

                 * To do this, we will use the random method built into SimState.

                 * It has lot's of

                * methods, which make generating random locations easier.

                */

               for(int i=0;i < n;i++){

                    Particle p = new Particle(this);

                    particleSpace.setObjectLocation(p, p.x, p.y);

               }

         }

}

Graphical User Interface (GUI)

We have placed the particles randomly into a 2D space, but we can’t see them. To see them, we need to create a graphical user interface (GUI). To do this, we are going to use classes defined in MASON. The trouble is that there are a lot of classes and you have to know the theory behind MASON’s GUI classes to write this class from scratch, so I’m going to just give you a basic GUI class, tell you what each component means, and then move on to try it out. As we continue to develop our skills at ABM, we will tweak this basic file so that we can change our GUIs as we see fit. Here is the basic GUI class we will use:

package particles;

import sim.engine.*;

import sim.display.*;

import sim.portrayal.grid.*;

import java.awt.*;

import javax.swing.*;

import sim.portrayal.simple.OvalPortrayal2D;

public class ParticlesWithUI extends GUIState {

        public Display2D display;

        public JFrame displayFrame;

        SparseGridPortrayal2D particlesPortrayal = new SparseGridPortrayal2D();

        public static void main(String[] args) {

               ParticlesWithUI ex = new ParticlesWithUI();

               Console c = new Console(ex);

               c.setVisible(true);

               System.out.println("Start Simulation");

        }

        public ParticlesWithUI() {

               super(new Environment(System.currentTimeMillis()));

        }

        public void quit() {

               super.quit();

               if (displayFrame!=null) displayFrame.dispose();

               displayFrame = null;

               display = null;

        }

        public void start() {

               super.start();

               setupPortrayals();

        }

        public void load(SimState state) {

               super.load(state);

               setupPortrayals();

        }

        public void setupPortrayals() {

                Environment se = (Environment)state;

               particlesPortrayal.setField(se.particleSpace);

                OvalPortrayal2D o = new OvalPortrayal2D(Color.red);

               particlesPortrayal.setPortrayalForAll(o);

               display.reset();

               display.repaint();

        }

        public void init(Controller c){

               super.init(c);

               display = new Display2D(400,400,this);

               displayFrame = display.createFrame();

               c.registerFrame(displayFrame);

               displayFrame.setVisible(true);

               display.setBackdrop(Color.black);

               display.attach(particlesPortrayal,"Particles");

        }

        public Object getSimulationInspectedObject() {

               return state;

        }

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote