Source code: org/mrd/models/cagn/Landscape.java
1 /*
2 * Copyright (C) 2002-2003, Mark Diggory
3 *
4 * This file is part of the CAGN model project.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. License
19 * information is also available at http://www.gnu.org.
20 *
21 */
22 package org.mrd.models.cagn;
23
24 import java.io.File;
25 import java.util.ArrayList;
26 import java.util.Vector;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.commons.pool.ObjectPool;
31
32 import uchicago.src.sim.space.Object2DGrid;
33 import uchicago.src.sim.space.Object2DTorus;
34
35 /** Landscape Encapsulates much of the Internal Datastructure management of a
36 * spatial simulation. It takes care of traking agents that are dead and need to be
37 * added or removed from the simulation landscape. It is composed of Three primary
38 * data structures:
39 * 1.) Agent Grid - used to track nieghorhood relationships
40 * 2.) Resource Grid - represents available resources in an area
41 * 3.) Agent List - A randomizable or sortable list that is iterated over to
42 * update the agents.
43 *
44 * There is one secondary datastructure, a birth queue, this
45 * store new agents that need to be added to the model at the end of
46 * a iteration.
47 *
48 * @author Mark Diggory <mdiggory@latte.harvard.edu>;
49 */
50
51 public class Landscape{
52
53 protected Log log;
54
55 /** Grid that holds the Agents.
56 */
57 protected Object2DGrid agentGrid;
58
59 /** Grid that holds the Habitat Resources
60 */
61 protected Object2DGrid habitatGrid;
62
63 /**
64 * A list of all the agents. Convenient for any method that
65 * iterates through a list of agents. A least one list like this is common
66 * to most simulations. See below for examples of its use.
67 **/
68 protected ArrayList agents = new ArrayList();
69
70 /** This queue holds dispersed agents that need to be added to the simulation at the end
71 * of the iteration.
72 */
73 protected Vector birthQueue = new Vector();
74
75 /** This queue holds agensts that failed to disperse that need to be removed from the simulation.
76 */
77 protected Vector reaperQueue = new Vector();
78
79 /** Holds value of property model. */
80 protected ObjectPool pool;
81
82 /** Creates a new Landscape
83 * @param model The model this landscape exists within.
84 * @param title Title that will be shown on the Landscape Display
85 * @param habitatFile The Habitat File that will initialize the resources in this landscape.
86 */
87 public Landscape(ObjectPool pool, String habitatFile) {
88
89 log = LogFactory.getLog(this.getClass().getName());
90
91 /* hand over references */
92 this.pool = pool;
93
94 /* Initialize the Grids */
95 try{
96 habitatFile = new File(habitatFile).getCanonicalPath();
97 log.debug("HabitatFile: "+habitatFile);
98 }catch(Exception e){
99 log.error("failed to locate habitatGrid file.");
100 }
101 habitatGrid = new Object2DTorus(habitatFile, Object2DGrid.PGM_ASCII);
102 agentGrid = new Object2DTorus(this.getSizeX(), this.getSizeY());
103 }
104
105 /** This will update the landscape by adding the new agents to the Grid and the agent
106 * list.
107 */
108 public void birthAgents() {
109 agents.addAll(birthQueue);
110 birthQueue.clear();
111 }
112
113 /** This will update the landscape by removing the dead agents from the Grid and the agent
114 * list.
115 */
116 public void reapAgents() {
117
118 try{
119 for (java.util.Iterator iter = reaperQueue.iterator(); iter.hasNext();) {
120 pool.returnObject(iter.next());
121 }
122 reaperQueue.clear();
123
124 for (java.util.Iterator iter = agents.iterator(); iter.hasNext();) {
125 Agent agent = (Agent)iter.next();
126 if(agent.getStage() == Agent.DEAD){
127 pool.returnObject(agent);
128 iter.remove();
129 agentGrid.putObjectAt(agent.getX(), agent.getY(),null);
130
131 }
132 }
133 }catch(Exception e){
134 log.error(e.getMessage(),e);
135 }
136 }
137
138 /** This gets the Resource Object available at a (x, y) coordinate
139 * @param x coordinate
140 * @param y coordinate
141 * @return Object The resource object at the coordinate of the Agent
142 */
143 public Object getResourceAt(int x, int y){
144 try{
145 return habitatGrid.getObjectAt(x, y);
146 }catch(java.lang.ArrayIndexOutOfBoundsException aobe){
147 System.err.println("Landscape.getResourceAt(): Bad coordinate( x=" +x+" y=" +y+")");
148 aobe.printStackTrace();
149 }
150 return null;
151 }
152
153 /** This gets the Resource double value available at a (x, y) coordinate
154 * @param x coordinate
155 * @param y coordinate
156 * @return double The value of the resource object at that coordinate.
157 */
158 public double getResourceValueAt(int x, int y){
159
160 double value = Double.NaN;
161 try{
162 value = habitatGrid.getValueAt(x, y);
163 }catch(java.lang.ArrayIndexOutOfBoundsException aobe){
164 System.err.println("Landscape.getResourceValueAt(): Bad coordinate( x=" +x+" y=" +y+")");
165 aobe.printStackTrace();
166 }
167
168 return value;
169 }
170
171 /**
172 * @param x
173 * @param y
174 * @return */
175 public Agent getAgentAt(int x, int y){
176 return (Agent)agentGrid.getObjectAt(x,y);
177 }
178
179 /**
180 * @param x
181 * @param y
182 * @param agent */
183 public void moveAgentTo(Agent agent, int x, int y) {
184
185 /* get agent in old location, make sure new location is empty */
186 Agent exists = (Agent)agentGrid.getObjectAt(agent.getX(),agent.getY());
187 Object empty = agentGrid.getObjectAt(x,y);
188
189 if(exists != null && empty == null){
190 agentGrid.putObjectAt(exists.getX(),exists.getY(),null);
191 agentGrid.putObjectAt(x,y,exists);
192 exists.setX(x);
193 exists.setY(y);
194 }else{
195 /* aggghhhh */
196 }
197
198 }
199
200 /**
201 * @param x
202 * @param y
203 * @param agent */
204 public void moveAgentTo(int old_x, int old_y, int x, int y) {
205
206 /* get agent in old location, make sure new location is empty */
207 Agent exists = (Agent)agentGrid.getObjectAt(old_x,old_y);
208 Object empty = agentGrid.getObjectAt(x,y);
209
210 if(exists != null && empty == null){
211 agentGrid.putObjectAt(exists.getX(),exists.getY(),null);
212 agentGrid.putObjectAt(x,y,exists);
213 exists.setX(x);
214 exists.setY(y);
215
216 }else{
217 /* aggghhhh */
218 }
219
220 }
221
222 /**
223 * @param x
224 * @param y
225 * @param agent */
226 public void putAgentAt(int x, int y, Agent agent) {
227
228 /* make sure new location is empty */
229 if(agentGrid.getObjectAt(x,y) == null){
230
231 /* set Agents characteristic determined by Landscape */
232 agent.setX(x);
233 agent.setY(y);
234
235 agent.setLandscape(this);
236
237 /* put the agent in the landscape */
238 birthQueue.add(agent);
239 agentGrid.putObjectAt(x,y,agent);
240 }else{
241 /* aagghhhhh */
242 }
243 }
244
245 /** Getter for property sizeX.
246 * @return Value of property sizeX.
247 */
248 public int getSizeX() {
249 return habitatGrid.getSizeX();
250 }
251
252 /** Getter for property sizeY.
253 * @return Value of property sizeY.
254 */
255 public int getSizeY() {
256 return habitatGrid.getSizeY();
257 }
258
259 /** Getter for property agents.
260 * @return Value of property agents.
261 */
262 public ArrayList getAgents() {
263 return this.agents;
264 }
265
266 /** Getter for property habitatGrid.
267 * @return Value of property habitatGrid.
268 */
269 public Object2DGrid getHabitatGrid() {
270 return this.habitatGrid;
271 }
272
273 /** Getter for property agentGrid.
274 * @return Value of property agentGrid.
275 */
276 public Object2DGrid getAgentGrid() {
277 return this.agentGrid;
278 }
279
280 /** Getter for property birthQueue.
281 * @return Value of property birthQueue.
282 */
283 public Vector getBirthQueue() {
284 return this.birthQueue;
285 }
286
287 /** Getter for property reaperQueue.
288 * @return Value of property reaperQueue.
289 */
290 public Vector getReaperQueue() {
291 return this.reaperQueue;
292 }
293
294 }