CarryDropModel

// CarryDropModel
package demo;

import java.awt.Color;
import java.util.ArrayList;

import uchicago.src.sim.analysis.BinDataSource;
import uchicago.src.sim.analysis.DataSource;
import uchicago.src.sim.analysis.OpenHistogram;
import uchicago.src.sim.analysis.OpenSequenceGraph;
import uchicago.src.sim.analysis.Sequence;
import uchicago.src.sim.engine.BasicAction;
import uchicago.src.sim.engine.Schedule;
import uchicago.src.sim.engine.SimInit;
import uchicago.src.sim.engine.SimModelImpl;
import uchicago.src.sim.gui.DisplaySurface;
import uchicago.src.sim.gui.ColorMap;
import uchicago.src.sim.gui.Object2DDisplay;
import uchicago.src.sim.gui.Value2DDisplay;
import uchicago.src.sim.util.SimUtilities;

public class CarryDropModel extends SimModelImpl {
  // Default Values
  private static final int NUMAGENTS = 100;
  private static final int WORLDXSIZE = 40;
  private static final int WORLDYSIZE = 40;
  private static final int TOTALMONEY = 1000;
  private static final int AGENT_MIN_LIFESPAN = 30;
  private static final int AGENT_MAX_LIFESPAN = 50;

  private int numAgents = NUMAGENTS;
  private int worldXSize = WORLDXSIZE;
  private int worldYSize = WORLDYSIZE;
  private int money = TOTALMONEY;
  private int agentMinLifespan = AGENT_MIN_LIFESPAN;
  private int agentMaxLifespan = AGENT_MAX_LIFESPAN;

  private Schedule schedule;

  private CarryDropSpace cdSpace;

  private ArrayList agentList;

  private DisplaySurface displaySurf;

  private OpenSequenceGraph amountOfMoneyInSpace;
  private OpenHistogram agentWealthDistribution;

  class moneyInSpace implements DataSource, Sequence {

    public Object execute() {
      return new Double(getSValue());
    }

    public double getSValue() {
      return (double)cdSpace.getTotalMoney();
    }
  }

  class agentMoney implements BinDataSource{
    public double getBinValue(Object o) {
      CarryDropAgent cda = (CarryDropAgent)o;
      return (double)cda.getMoney();
    }
  }

  public String getName(){
    return "Carry And Drop";
  }

  public void setup(){
    System.out.println("Running setup");
    cdSpace = null;
    agentList = new ArrayList();
    schedule = new Schedule(1);

    // Tear down Displays
    if (displaySurf != null){
      displaySurf.dispose();
    }
    displaySurf = null;

    if (amountOfMoneyInSpace != null){
      amountOfMoneyInSpace.dispose();
    }
    amountOfMoneyInSpace = null;

    if (agentWealthDistribution != null){
      agentWealthDistribution.dispose();
    }
    agentWealthDistribution = null;


    // Create Displays
    displaySurf = new DisplaySurface(this, "Carry Drop Model Window 1");
    amountOfMoneyInSpace = new OpenSequenceGraph("Amount Of Money In Space",this);
    agentWealthDistribution = new OpenHistogram("Agent Wealth", 8, 0);

    // Register Displays
    registerDisplaySurface("Carry Drop Model Window 1", displaySurf);
    this.registerMediaProducer("Plot", amountOfMoneyInSpace);
  }

  public void begin(){
    buildModel();
    buildSchedule();
    buildDisplay();

    displaySurf.display();
    amountOfMoneyInSpace.display();
    agentWealthDistribution.display();
  }

  public void buildModel(){
    System.out.println("Running BuildModel");
    cdSpace = new CarryDropSpace(worldXSize, worldYSize);
    cdSpace.spreadMoney(money);

    for(int i = 0; i < numAgents; i++){
      addNewAgent();
    }
    for(int i = 0; i < agentList.size(); i++){
      CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
      cda.report();
    }
  }

  public void buildSchedule(){
    System.out.println("Running BuildSchedule");

    class CarryDropStep extends BasicAction {
      public void execute() {
        SimUtilities.shuffle(agentList);
        for(int i =0; i < agentList.size(); i++){
          CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
          cda.step();
        }

        int deadAgents = reapDeadAgents();
        for(int i =0; i < deadAgents; i++){
          addNewAgent();
        }

        displaySurf.updateDisplay();
      }
    }

    schedule.scheduleActionBeginning(0, new CarryDropStep());

    class CarryDropCountLiving extends BasicAction {
      public void execute(){
        countLivingAgents();
      }
    }

    schedule.scheduleActionAtInterval(10, new CarryDropCountLiving());

    class CarryDropUpdateMoneyInSpace extends BasicAction {
      public void execute(){
        amountOfMoneyInSpace.step();
      }
    }

    schedule.scheduleActionAtInterval(10, new CarryDropUpdateMoneyInSpace());

    class CarryDropUpdateAgentWealth extends BasicAction {
      public void execute(){
        agentWealthDistribution.step();
      }
    }

    schedule.scheduleActionAtInterval(10, new CarryDropUpdateAgentWealth());

  }

  public void buildDisplay(){
    System.out.println("Running BuildDisplay");

    ColorMap map = new ColorMap();

    for(int i = 1; i<16; i++){
      map.mapColor(i, new Color((int)(i * 8 + 127), 0, 0));
    }
    map.mapColor(0, Color.white);

    Value2DDisplay displayMoney =
        new Value2DDisplay(cdSpace.getCurrentMoneySpace(), map);

    Object2DDisplay displayAgents = new Object2DDisplay(cdSpace.getCurrentAgentSpace());
    displayAgents.setObjectList(agentList);

    displaySurf.addDisplayableProbeable(displayMoney, "Money");
    displaySurf.addDisplayableProbeable(displayAgents, "Agents");

    amountOfMoneyInSpace.addSequence("Money In Space", new moneyInSpace());
    agentWealthDistribution.createHistogramItem("Agent Wealth",agentList,new agentMoney());

  }

  private void addNewAgent(){
    CarryDropAgent a = new CarryDropAgent(agentMinLifespan, agentMaxLifespan);
    agentList.add(a);
    cdSpace.addAgent(a);
  }

  private int reapDeadAgents(){
    int count = 0;
    for(int i = (agentList.size() - 1); i >= 0 ; i--){
      CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
      if(cda.getStepsToLive() < 1){
        cdSpace.removeAgentAt(cda.getX(), cda.getY());
        cdSpace.spreadMoney(cda.getMoney());
        agentList.remove(i);
        count++;
      }
    }
    return count;
  }

  private int countLivingAgents(){
    int livingAgents = 0;
    for(int i = 0; i < agentList.size(); i++){
      CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
      if(cda.getStepsToLive() > 0) livingAgents++;
    }
    System.out.println("Number of living agents is: " + livingAgents);

    return livingAgents;
  }

  public Schedule getSchedule(){
    return schedule;
  }

  public String[] getInitParam(){
    String[] initParams = { "NumAgents", "WorldXSize", "WorldYSize", "Money", "AgentMinLifespan", "AgentMaxLifespan"};
    return initParams;
  }

  public int getNumAgents(){
    return numAgents;
  }

  public void setNumAgents(int na){
    numAgents = na;
  }

  public int getWorldXSize(){
    return worldXSize;
  }

  public void setWorldXSize(int wxs){
    worldXSize = wxs;
  }

  public int getWorldYSize(){
    return worldYSize;
  }

  public void setWorldYSize(int wys){
    worldYSize = wys;
  }

  public int getMoney() {
    return money;
  }

  public void setMoney(int i) {
    money = i;
  }

  public int getAgentMaxLifespan() {
    return agentMaxLifespan;
  }

  public int getAgentMinLifespan() {
    return agentMinLifespan;
  }

  public void setAgentMaxLifespan(int i) {
    agentMaxLifespan = i;
  }

  public void setAgentMinLifespan(int i) {
    agentMinLifespan = i;
  }

  public static void main(String[] args) {
    SimInit init = new SimInit();
    CarryDropModel model = new CarryDropModel();
    init.loadModel(model, "", false);
  }

}

CarryDropAgent

// CarryDropAgent
package demo;

import java.awt.Color;

import uchicago.src.sim.gui.Drawable;
import uchicago.src.sim.gui.SimGraphics;
import uchicago.src.sim.space.Object2DGrid;

public class CarryDropAgent implements Drawable{
  private int x;
  private int y;
  private int vX;
  private int vY;
  private int money;
  private int stepsToLive;
  private static int IDNumber = 0;
  private int ID;
  private CarryDropSpace cdSpace;

  public CarryDropAgent(int minLifespan, int maxLifespan){
    x = -1;
    y = -1;
    money = 0;
    setVxVy();
    stepsToLive =
        (int)((Math.random() * (maxLifespan - minLifespan)) + minLifespan);
    IDNumber++;
    ID = IDNumber;
  }

  private void setVxVy(){
    vX = 0;
    vY = 0;
    while((vX == 0) && ( vY == 0)){
      vX = (int)Math.floor(Math.random() * 3) - 1;
      vY = (int)Math.floor(Math.random() * 3) - 1;
    }
  }

  public void setXY(int newX, int newY){
    x = newX;
    y = newY;
  }

  public void setCarryDropSpace(CarryDropSpace cds){
    cdSpace = cds;
  }

  public String getID(){
    return "A-" + ID;
  }

  public int getMoney(){
    return money;
  }

  public int getStepsToLive(){
    return stepsToLive;
  }

  public void report(){
    System.out.println(getID() +
                       " at " +
                       x + ", " + y +
                       " has " +
                       getMoney() + " dollars" +
                       " and " +
                       getStepsToLive() + " steps to live.");
  }

  public int getX(){
    return x;
  }

  public int getY(){
    return y;
  }

  public void draw(SimGraphics G){
    if(stepsToLive > 10)
      G.drawFastRoundRect(Color.green);
    else
      G.drawFastRoundRect(Color.blue);
  }

  public void step(){
    int newX = x + vX;
    int newY = y + vY;

    Object2DGrid grid = cdSpace.getCurrentAgentSpace();
    newX = (newX + grid.getSizeX()) % grid.getSizeX();
    newY = (newY + grid.getSizeY()) % grid.getSizeY();

    if(tryMove(newX, newY)){
      money += cdSpace.takeMoneyAt(x, y);
    }
    else{
      CarryDropAgent cda = cdSpace.getAgentAt(newX, newY);
      if (cda!= null){
        if(money > 0){
          cda.receiveMoney(1);
          money--;
        }
      }       setVxVy();
    }
    stepsToLive--;
  }

  private boolean tryMove(int newX, int newY){
    return cdSpace.moveAgentAt(x, y, newX, newY);
  }

  public void receiveMoney(int amount){
    money += amount;
  }
}

CarryDropSpace

// CarryDropSpace
package demo;

import uchicago.src.sim.space.Object2DGrid;


public class CarryDropSpace {
private Object2DGrid moneySpace;
private Object2DGrid agentSpace;

  public CarryDropSpace(int xSize, int ySize){
    moneySpace = new Object2DGrid(xSize, ySize);
    agentSpace = new Object2DGrid(xSize, ySize);

    for(int i = 0; i < xSize; i++){
      for(int j = 0; j < ySize; j++){
        moneySpace.putObjectAt(i,j,new Integer(0));
      }
    }
  }

  public void spreadMoney(int money){
    // Randomly place money in moneySpace
    for(int i = 0; i < money; i++){

      // Choose coordinates
      int x = (int)(Math.random()*(moneySpace.getSizeX()));
      int y = (int)(Math.random()*(moneySpace.getSizeY()));

      // Get the value of the object at those coordinates
      int currentValue = getMoneyAt(x, y);
      // Replace the Integer object with another one with the new value
      moneySpace.putObjectAt(x,y,new Integer(currentValue + 1));
    }
  }

  public int getMoneyAt(int x, int y){
    int i;
    if(moneySpace.getObjectAt(x,y)!= null){
      i = ((Integer)moneySpace.getObjectAt(x,y)).intValue();
    }
    else{
      i = 0;
    }
    return i;
  }

  public CarryDropAgent getAgentAt(int x, int y){
    CarryDropAgent retVal = null;
    if(agentSpace.getObjectAt(x, y) != null){
      retVal = (CarryDropAgent)agentSpace.getObjectAt(x,y);
    }
    return retVal;
  }

  public Object2DGrid getCurrentMoneySpace(){
    return moneySpace;
  }

  public Object2DGrid getCurrentAgentSpace(){
    return agentSpace;
  }

  public boolean isCellOccupied(int x, int y){
    boolean retVal = false;
    if(agentSpace.getObjectAt(x, y)!=null) retVal = true;
    return retVal;
  }

  public boolean addAgent(CarryDropAgent agent){
    boolean retVal = false;
    int count = 0;
    int countLimit = 10 * agentSpace.getSizeX() * agentSpace.getSizeY();

    while((retVal==false) && (count < countLimit)){
      int x = (int)(Math.random()*(agentSpace.getSizeX()));
      int y = (int)(Math.random()*(agentSpace.getSizeY()));
      if(isCellOccupied(x,y) == false){
        agentSpace.putObjectAt(x,y,agent);
        agent.setXY(x,y);
        agent.setCarryDropSpace(this);
        retVal = true;
      }
      count++;
    }

    return retVal;
  }

  public void removeAgentAt(int x, int y){
    agentSpace.putObjectAt(x, y, null);
  }

  public int takeMoneyAt(int x, int y){
    int money = getMoneyAt(x, y);
    moneySpace.putObjectAt(x, y, new Integer(0));
    return money;
  }

  public boolean moveAgentAt(int x, int y, int newX, int newY){
    boolean retVal = false;
    if(!isCellOccupied(newX, newY)){
      CarryDropAgent cda = (CarryDropAgent)agentSpace.getObjectAt(x, y);
      removeAgentAt(x,y);
      cda.setXY(newX, newY);
      agentSpace.putObjectAt(newX, newY, cda);
      retVal = true;
    }
    return retVal;
  }

  public int getTotalMoney(){
    int totalMoney = 0;
    for(int i = 0; i < agentSpace.getSizeX(); i++){
      for(int j = 0; j < agentSpace.getSizeY(); j++){
        totalMoney += getMoneyAt(i,j);
      }
    }
    return totalMoney;
  }
}