Transition from sss-2.2 to sss-2.3. Paul Johnson 2004/07/29 This is the output from the "diff" program, which compares the text in two sets of files. It was used to compare sss-2.2 and sss-2.3. This is a "context" diff, which shows the "before and after" snips in the vicinity of the changes. The + sign indicates that a line has been added in the revision. An ! indicates that a line has been changed. Note that the Predator class appears as all new material, although much of it is simply cut and pasted from SugarAgent. 12-001 12-002 12-003 README 12-004 12-005 diff -rc --new-file sss-2.2/README sss-2.3/README 12-006 *** sss-2.2/README 2003-04-20 07:41:33.000000000 -0400 12-007 --- sss-2.3/README 2004-07-29 04:51:45.000000000 -0400 12-008 *************** 12-009 *** 1,4 **** 12-010 --- 1,20 ---- 12-011 Paul Johnson 12-012 + 2004-07-26 12-013 + 12-014 + sss-2.3 12-015 + 12-016 + For demonstration purposes only, this package shows how a new 12-017 + class, "Predator", can be introduced. 12-018 + 12-019 + Begin with my package sss-2.2-Swarm-2.1.141.tar.gz. One must edit the 12-020 + Makefile, copy SugarAgent.[hm] to get a starting point for 12-021 + Predator.[hm], fiddle the SugarSpace so it has a grid for Predators 12-022 + and can move predators around, and the ModelSwarm has to create a list 12-023 + of predators and schedule it. ObserverSwarm adds predators to the raster 12-024 + and also a new graph of Predator kills is included. 12-025 + 12-026 + ________________________________________________ 12-027 + Paul Johnson 12-028 2003-04-18 12-029 12-030 Swarm SugarScape was done by Nelson Minar and now it has undergone 12-031 Binary files sss-2.2/sss.hdf and sss-2.3/sss.hdf differ 12-032 12-033 12-034 Predator.h 12-035 12-036 12-037 diff -rc --new-file sss-2.2/Predator.h sss-2.3/Predator.h 12-038 *** sss-2.2/Predator.h 1969-12-31 19:00:00.000000000 -0500 12-039 --- sss-2.3/Predator.h 2004-07-29 03:30:43.000000000 -0400 12-040 *************** 12-041 *** 0 **** 12-042 --- 1,56 ---- 12-043 + // Sugarscape in Swarm. Copyright © 1997 Nelson Minar 12-044 + // This program is distributed without any warranty; without even the 12-045 + // implied warranty of merchantability or fitness for a particular purpose. 12-046 + // See file LICENSE for details and terms of copying. 12-047 + 12-048 + 12-049 + #import 12-050 + #import // we use Space features 12-051 + #import 12-052 + #import "SugarSpace.h" 12-053 + 12-054 + // The definition of a SugarAgent object. We inherit code from the generic 12-055 + // SwarmObject, which provides memory allocation and other niceties. It 12-056 + // does not provide any sort of agent behaviour, though, that's up to us. 12-057 + // First, there are a lot of state variables 12-058 + 12-059 + @interface Predator: SwarmObject 12-060 + { 12-061 + SugarValue currentSugar; // how much sugar I hold 12-062 + SugarValue metabolism; // how much sugar I need 12-063 + int vision; // how far I can see 12-064 + int age; // how old I am 12-065 + int deathAge; // how old I can get 12-066 + int numKilled; 12-067 + 12-068 + id modelSwarm; // my swarm 12-069 + SugarSpace *sugarSpace; // the sugarspace I live in 12-070 + id myPixmap; 12-071 + 12-072 + @public 12-073 + int x, y; // my position 12-074 + // I won't change this myself 12-075 + } 12-076 + 12-077 + // The main behaviour of an object - do one 'time step', one action. 12-078 + - step; 12-079 + 12-080 + // The agent movement rule M. 12-081 + - move; 12-082 + 12-083 + // data accessor functions. 12-084 + - (SugarValue)getMetabolism; 12-085 + - (int)getVision; 12-086 + - (int)getAge; 12-087 + - (int)getNumKilled; 12-088 + - (SugarValue)getCurrentSugar; 12-089 + - setModelSwarm: s; 12-090 + - setCurrentSugar: (SugarValue)cs; 12-091 + - setMetabolism: (SugarValue)m; 12-092 + - setVision: (int)v; 12-093 + - setDeathAge: (int)a; 12-094 + 12-095 + // display code so you can see the agents moving. 12-096 + - drawSelfOn: (id )r; 12-097 + 12-098 + @end 12-099 12-100 12-101 Predator.m: 12-102 12-103 diff -rc --new-file sss-2.2/Predator.m sss-2.3/Predator.m 12-104 *** sss-2.2/Predator.m 1969-12-31 19:00:00.000000000 -0500 12-105 --- sss-2.3/Predator.m 2004-07-29 03:30:57.000000000 -0400 12-106 *************** 12-107 *** 0 **** 12-108 --- 1,269 ---- 12-109 + // Sugarscape in Swarm. Copyright © 1997 Nelson Minar 12-110 + // Class Predator based on SugarAgent Copyright @ 2004 Paul Johnson 12-111 + // This program is distributed without any warranty; without even the 12-112 + // implied warranty of merchantability or fitness for a particular purpose. 12-113 + // See file LICENSE for details and terms of copying. 12-114 + 12-115 + #import "Predator.h" 12-116 + #import 12-117 + #import "ModelSwarm.h" 12-118 + #import 12-119 + 12-120 + @implementation Predator 12-121 + 12-122 + 12-123 + - createEnd 12-124 + { 12-125 + numKilled = 0; 12-126 + return [super createEnd]; 12-127 + } 12-128 + 12-129 + 12-130 + // One "step" for an agent. Depending on the rules in effect, this step 12-131 + // could have a lot of different meanings. 12-132 + - step 12-133 + { 12-134 + 12-135 + age++; 12-136 + 12-137 + SugarAgent * targetAgent = [self move]; 12-138 + 12-139 + currentSugar += [targetAgent getCurrentSugar]; 12-140 + 12-141 + currentSugar -= metabolism; 12-142 + 12-143 + if (targetAgent) 12-144 + { 12-145 + #ifdef PREDEBUG 12-146 + fprintf(stderr,"I'm at %d,%d, Killing one at %d %d sugar= %d\n",x,y,targetAgent->x,targetAgent->y,[targetAgent getCurrentSugar]); 12-147 + #endif 12-148 + [sugarSpace removeAgent: targetAgent]; 12-149 + [modelSwarm agentDeath: targetAgent]; 12-150 + numKilled++; 12-151 + } 12-152 + // Check if I'm dying 12-153 + // if (currentSugar <= 0 || age >= deathAge) 12-154 + // { 12-155 + // [sugarSpace removeAgent: self]; 12-156 + // [modelSwarm agentDeath: self]; 12-157 + // } 12-158 + 12-159 + return self; 12-160 + } 12-161 + 12-162 + 12-163 + // A dumb macro to get the absolute value of an integer 12-164 + #define intabs(a) ((a) < 0 ? -(a) : (a)) 12-165 + 12-166 + - move 12-167 + { 12-168 + int xLook, yLook; 12-169 + SugarValue bestSugar; 12-170 + int bestDistance; 12-171 + int goodSpots; 12-172 + int goodX[16], goodY[16]; // 4 should be adequate 12-173 + int chosenSpot, newX, newY; 12-174 + SugarAgent * targetAgent = nil; 12-175 + int targetSugar; 12-176 + 12-177 + // prime the algorithm with out of range values 12-178 + bestSugar = -1; 12-179 + goodSpots = 0; 12-180 + bestDistance = 999999; // big number 12-181 + 12-182 + // First, look in the X direction for good spots. 12-183 + yLook = y; 12-184 + for (xLook = x - vision; xLook <= x + vision; xLook++) 12-185 + { 12-186 + // Is the spot currently empty? 12-187 + if ((targetAgent = [sugarSpace getAgentAtX: xLook Y: yLook]) != nil) 12-188 + { 12-189 + // is the spot we're looking at the best we've ever seen? 12-190 + if ((targetSugar = [targetAgent getCurrentSugar]) > bestSugar) 12-191 + { 12-192 + // yes, best spot ever. Forget everything else, record this 12-193 + // as the only good spot 12-194 + bestSugar = targetSugar; 12-195 + bestDistance = intabs(x - xLook); 12-196 + goodSpots = 0; 12-197 + goodX[0] = xLook; 12-198 + goodY[0] = yLook; 12-199 + goodSpots++; 12-200 + } 12-201 + else if (targetSugar == bestSugar) 12-202 + { 12-203 + // No, it's only as good as anything else we've seen. Is it closer 12-204 + // than any other spot we've seen with this sugar? 12-205 + if (intabs(x - xLook) < bestDistance) { 12-206 + // Yes, forget all the rest - this is the only good spot 12-207 + bestDistance = intabs(x - xLook); 12-208 + goodSpots = 0; 12-209 + goodX[0] = xLook; 12-210 + goodY[0] = yLook; 12-211 + goodSpots++; 12-212 + } 12-213 + else if (intabs (x - xLook) == bestDistance) 12-214 + { 12-215 + // No, this spot is as good as some other one. Just add this 12-216 + // one on as a good spot. 12-217 + goodX[goodSpots] = xLook; 12-218 + goodY[goodSpots] = yLook; 12-219 + goodSpots++; 12-220 + } 12-221 + } 12-222 + } 12-223 + } 12-224 + 12-225 + // Now repeat the same choice in the Y axis, ignoring current y position. 12-226 + xLook = x; 12-227 + for (yLook = y - vision; yLook <= y + vision; yLook++) 12-228 + { 12-229 + if ((yLook != y) && ((targetAgent = [sugarSpace getAgentAtX: xLook Y: yLook]) != nil)) 12-230 + { 12-231 + if ((targetSugar = [targetAgent getCurrentSugar]) > bestSugar) 12-232 + { 12-233 + bestSugar = targetSugar; 12-234 + bestDistance = intabs(y - yLook); 12-235 + goodSpots = 0; 12-236 + goodX[0] = xLook; 12-237 + goodY[0] = yLook; 12-238 + goodSpots++; 12-239 + } 12-240 + else if (targetSugar == bestSugar) 12-241 + { 12-242 + if (intabs(y - yLook) < bestDistance) 12-243 + { 12-244 + bestDistance = intabs(y - yLook); 12-245 + goodSpots = 0; 12-246 + goodX[0] = xLook; 12-247 + goodY[0] = yLook; 12-248 + goodSpots++; 12-249 + } 12-250 + else if (intabs(y - yLook) == bestDistance) 12-251 + { 12-252 + goodX[goodSpots] = xLook; 12-253 + goodY[goodSpots] = yLook; 12-254 + goodSpots++; 12-255 + } 12-256 + } 12-257 + } 12-258 + } 12-259 + 12-260 + // A bit of debug printing to make sure the agents are behaving sensibly. 12-261 + // (turned off normally) 12-262 + #ifdef PREDEBUG 12-263 + { 12-264 + int i; 12-265 + fprintf(stderr,"Predator at %d,%d Found %d good spots:\n", x,y, goodSpots); 12-266 + for (i = 0; i < goodSpots; i++) 12-267 + fprintf(stderr," (%d,%d) = %d\n", goodX[i], goodY[i], 12-268 + [ [sugarSpace getAgentAtX: goodX[i] Y: goodY[i]] getCurrentSugar] ); 12-269 + } 12-270 + #endif 12-271 + 12-272 + // Alright, goodX[] and goodY[] record the best spots we've found. 12-273 + // Let's figure out where to move. 12-274 + 12-275 + if (goodSpots == 0) // No spots are good 12-276 + ; // don't even move 12-277 + else 12-278 + { 12-279 + if (goodSpots == 1) // only one good spot 12-280 + chosenSpot = 0; 12-281 + else // pick a random spot 12-282 + chosenSpot = [uniformIntRand getIntegerWithMin: 0 withMax: goodSpots-1]; 12-283 + newX = goodX[chosenSpot]; // get the coordinate 12-284 + newY = goodY[chosenSpot]; // and move there! 12-285 + 12-286 + 12-287 + [sugarSpace movePredator: self toX: newX Y: newY]; 12-288 + #ifdef PREDEBUG 12-289 + 12-290 + fprintf(stderr,"Predator moved to %d,%d:\n", x,y); 12-291 + #endif 12-292 + } 12-293 + return targetAgent = [sugarSpace getAgentAtX: x Y: y]; 12-294 + } 12-295 + 12-296 + //// The code below here is not very interesting - it has to do with 12-297 + //// the technical details of managing the data in the model, not the 12-298 + //// modelling itself. You can safely ignore it until you want to know 12-299 + //// the details of how the program works. 12-300 + 12-301 + // set methods for various values 12-302 + - setModelSwarm: s 12-303 + { 12-304 + modelSwarm = s; 12-305 + sugarSpace = [s getSugarSpace]; 12-306 + return self; 12-307 + } 12-308 + 12-309 + - (SugarValue)getCurrentSugar 12-310 + { 12-311 + return currentSugar; 12-312 + } 12-313 + 12-314 + - setCurrentSugar: (SugarValue)cs 12-315 + { 12-316 + currentSugar = cs; 12-317 + return self; 12-318 + } 12-319 + 12-320 + - (int)getMetabolism 12-321 + { 12-322 + return metabolism; 12-323 + } 12-324 + 12-325 + - setMetabolism: (int)m 12-326 + { 12-327 + metabolism = m; 12-328 + return self; 12-329 + } 12-330 + 12-331 + - (int)getVision 12-332 + { 12-333 + return vision; 12-334 + } 12-335 + 12-336 + - setVision: (int)v 12-337 + { 12-338 + vision = v; 12-339 + return self; 12-340 + } 12-341 + 12-342 + - (int)getAge 12-343 + { 12-344 + return age; 12-345 + } 12-346 + 12-347 + - (int)getNumKilled 12-348 + { 12-349 + return numKilled; 12-350 + } 12-351 + 12-352 + - setDeathAge: (int)s 12-353 + { 12-354 + deathAge = s; 12-355 + return self; 12-356 + } 12-357 + 12-358 + // Graphics code - how to draw oneself (hardcoded colour value here. If 12-359 + // agents have different properties, these colour should be different.) 12-360 + - drawSelfOn: (id )r 12-361 + { 12-362 + // [r drawPointX: x Y: y Color: 100]; 12-363 + if (myPixmap == nil) 12-364 + { 12-365 + myPixmap = [Pixmap createBegin: [self getZone]]; 12-366 + [myPixmap setFile: "pacman.png"]; 12-367 + myPixmap = [myPixmap createEnd]; 12-368 + } 12-369 + 12-370 + [myPixmap setRaster: r]; 12-371 + 12-372 + [r draw: myPixmap X: (int) x Y: y]; 12-373 + 12-374 + return self; 12-375 + } 12-376 + 12-377 + @end 12-378 12-379 12-380 12-381 Makefile 12-382 12-383 diff -rc --new-file sss-2.2/Makefile sss-2.3/Makefile 12-384 *** sss-2.2/Makefile 2004-07-27 05:08:13.000000000 -0400 12-385 --- sss-2.3/Makefile 2004-07-26 10:50:10.000000000 -0400 12-386 *************** 12-387 *** 4,10 **** 12-388 APPLICATION=sss 12-389 APPVERSION=2.2 12-390 BUGADDRESS=bug-swarm@swarm.org 12-391 ! OBJECTS=main.o SugarAgent.o SugarSpace.o ModelSwarm.o ObserverSwarm.o 12-392 12-393 #DATAFILES = $(foreach f,1 2 3,$(foreach type,obs model,parameters/II-$(f).$(type))) sugarspace.pgm 12-394 12-395 --- 4,10 ---- 12-396 APPLICATION=sss 12-397 APPVERSION=2.2 12-398 BUGADDRESS=bug-swarm@swarm.org 12-399 ! OBJECTS=main.o SugarAgent.o SugarSpace.o ModelSwarm.o ObserverSwarm.o Predator.o 12-400 12-401 12-402 12-403 *************** 12-404 *** 12,21 **** 12-405 12-406 include $(SWARMHOME)/etc/swarm/Makefile.appl 12-407 12-408 - 12-409 main.o: main.m ObserverSwarm.h 12-410 ObserverSwarm.o: ObserverSwarm.h ObserverSwarm.m ModelSwarm.h SugarAgent.h 12-411 ! ModelSwarm.o: ModelSwarm.h ModelSwarm.m SugarAgent.h 12-412 SugarSpace.o: SugarSpace.h SugarSpace.m 12-413 SugarAgent.o: SugarAgent.h SugarAgent.m SugarSpace.h 12-414 12-415 --- 12,21 ---- 12-416 12-417 include $(SWARMHOME)/etc/swarm/Makefile.appl 12-418 12-419 main.o: main.m ObserverSwarm.h 12-420 ObserverSwarm.o: ObserverSwarm.h ObserverSwarm.m ModelSwarm.h SugarAgent.h 12-421 ! ModelSwarm.o: ModelSwarm.h ModelSwarm.m SugarAgent.h Predator.h 12-422 SugarSpace.o: SugarSpace.h SugarSpace.m 12-423 SugarAgent.o: SugarAgent.h SugarAgent.m SugarSpace.h 12-424 + Predator.o: Predator.h Predator.m SugarSpace.h 12-425 12-426 12-427 12-428 ModelSwarm.h 12-429 12-430 diff -rc --new-file sss-2.2/ModelSwarm.h sss-2.3/ModelSwarm.h 12-431 *** sss-2.2/ModelSwarm.h 2003-04-18 20:32:05.000000000 -0400 12-432 --- sss-2.3/ModelSwarm.h 2004-07-27 04:15:25.000000000 -0400 12-433 *************** 12-434 *** 16,22 **** 12-435 @interface ModelSwarm: Swarm 12-436 { 12-437 // Parameters for the model 12-438 ! int numAgents; 12-439 int alpha; // growth rate for sugar 12-440 int replacement; // use replacement rule? 12-441 int maxVision, maxMetabolism; 12-442 --- 16,22 ---- 12-443 @interface ModelSwarm: Swarm 12-444 { 12-445 // Parameters for the model 12-446 ! int numAgents, numPredators; 12-447 int alpha; // growth rate for sugar 12-448 int replacement; // use replacement rule? 12-449 int maxVision, maxMetabolism; 12-450 *************** 12-451 *** 26,32 **** 12-452 char *datafile; 12-453 12-454 // Objects in the list 12-455 ! id agentList; 12-456 id shuffler; 12-457 SugarSpace *sugarSpace; 12-458 id reaperQueue; 12-459 --- 26,33 ---- 12-460 char *datafile; 12-461 12-462 // Objects in the list 12-463 ! id agentList; 12-464 ! id predatorList; 12-465 id shuffler; 12-466 SugarSpace *sugarSpace; 12-467 id reaperQueue; 12-468 *************** 12-469 *** 38,49 **** 12-470 --- 39,53 ---- 12-471 12-472 // Methods to handle the agents in the world 12-473 - addNewRandomAgent; 12-474 + - addPredator; 12-475 - agentBirth: (SugarAgent *)agent; 12-476 - agentDeath: (SugarAgent *)agent; 12-477 12-478 // Accessor functions 12-479 - (SugarSpace *)getSugarSpace; 12-480 - getAgentList; 12-481 + - getPredatorList; 12-482 + 12-483 12-484 // Scheduling methods 12-485 - buildObjects; 12-486 12-487 12-488 12-489 ModelSwarm.m 12-490 12-491 diff -rc --new-file sss-2.2/ModelSwarm.m sss-2.3/ModelSwarm.m 12-492 *** sss-2.2/ModelSwarm.m 2004-07-26 11:17:53.000000000 -0400 12-493 --- sss-2.3/ModelSwarm.m 2004-07-27 03:03:12.000000000 -0400 12-494 *************** 12-495 *** 6,11 **** 12-496 --- 6,12 ---- 12-497 #import "ModelSwarm.h" 12-498 //#import 12-499 #import //uniformUnsRand uniformIntRand 12-500 + #import "Predator.h" 12-501 12-502 #include // strdup 12-503 @implementation ModelSwarm 12-504 *************** 12-505 *** 22,27 **** 12-506 --- 23,29 ---- 12-507 12-508 // Parameters for the simulation 12-509 obj->numAgents = 400; 12-510 + obj->numPredators = 0; 12-511 obj->alpha = 1; 12-512 obj->replacement = 0; 12-513 obj->maxVision = 6; 12-514 *************** 12-515 *** 43,48 **** 12-516 --- 45,52 ---- 12-517 12-518 [probeMap addProbe: [probeLibrary getProbeForVariable: "numAgents" 12-519 inClass: [self class]]]; 12-520 + [probeMap addProbe: [probeLibrary getProbeForVariable: "numPredators" 12-521 + inClass: [self class]]]; 12-522 [probeMap addProbe: [probeLibrary getProbeForVariable: "alpha" 12-523 inClass: [self class]]]; 12-524 [probeMap addProbe: [probeLibrary getProbeForVariable: "replacement" 12-525 *************** 12-526 *** 87,96 **** 12-527 --- 91,109 ---- 12-528 // create a list to store all the agents 12-529 agentList = [List create: self]; 12-530 12-531 + 12-532 + predatorList = [List create: self]; 12-533 + 12-534 // And create a bunch of agents to live in the world. 12-535 for (i = 0; i < numAgents; i++) 12-536 [self addNewRandomAgent]; 12-537 12-538 + for (i = 0; i < numPredators; i++) 12-539 + { 12-540 + Predator * aPredator = [self addPredator]; 12-541 + [predatorList addLast: aPredator]; 12-542 + } 12-543 + 12-544 // Create a "reaper queue" to manage agent deaths 12-545 reaperQueue = [List create: self]; 12-546 12-547 *************** 12-548 *** 118,123 **** 12-549 --- 131,138 ---- 12-550 [modelActions createActionTo: sugarSpace message: M(updateSugar)]; 12-551 [modelActions createActionTo: shuffler message: M(shuffleWholeList:) : agentList]; 12-552 [modelActions createActionForEach: agentList message: M(step)]; 12-553 + [modelActions createActionForEach: predatorList message: M(step)]; 12-554 + 12-555 [modelActions createActionTo: self message: M(reapAgents)]; 12-556 12-557 // The schedule is just running our actions over and over again 12-558 *************** 12-559 *** 144,150 **** 12-560 agent = [agent createEnd]; 12-561 12-562 // Give the agent a random initial position and parameters. 12-563 - //pj 20040725: should be -1 to "keep in bounds" 12-564 x = [uniformIntRand getIntegerWithMin: 0 withMax: [sugarSpace getSizeX]-1]; 12-565 y = [uniformIntRand getIntegerWithMin: 0 withMax: [sugarSpace getSizeY]-1]; 12-566 [sugarSpace addAgent: agent atX: x Y: y]; 12-567 --- 159,164 ---- 12-568 *************** 12-569 *** 166,171 **** 12-570 --- 180,223 ---- 12-571 return self; 12-572 } 12-573 12-574 + // Create a new Predator. 12-575 + - addPredator 12-576 + { 12-577 + int x, y; 12-578 + Predator *agent; 12-579 + 12-580 + // turn off these warnings. 12-581 + [[sugarSpace getAgentGrid] setOverwriteWarnings: 0]; 12-582 + 12-583 + // Create the agent object 12-584 + agent = [Predator createBegin: self]; 12-585 + [agent setModelSwarm: self]; 12-586 + agent = [agent createEnd]; 12-587 + 12-588 + // Give the agent a random initial position and parameters. 12-589 + x = [uniformIntRand getIntegerWithMin: 0 withMax: ([sugarSpace getSizeX]-1)]; 12-590 + y = [uniformIntRand getIntegerWithMin: 0 withMax: ([sugarSpace getSizeY]-1)]; 12-591 + [sugarSpace addPredator: agent atX: x Y: y]; 12-592 + agent->x = x; 12-593 + agent->y = y; 12-594 + 12-595 + [agent setCurrentSugar: 12-596 + [uniformIntRand getIntegerWithMin: minInitialSugar 12-597 + withMax: maxInitialSugar]]; 12-598 + [agent setMetabolism: 12-599 + [uniformIntRand getIntegerWithMin: 1 withMax: maxMetabolism]]; 12-600 + [agent setVision: 12-601 + [uniformIntRand getIntegerWithMin: 1 withMax: maxVision]]; 12-602 + [agent setDeathAge: 12-603 + [uniformIntRand getIntegerWithMin: deathAgeMin 12-604 + withMax: deathAgeMax]]; 12-605 + 12-606 + // turn the warnings back on 12-607 + [[sugarSpace getAgentGrid] setOverwriteWarnings: 1]; 12-608 + return agent; 12-609 + } 12-610 + 12-611 + 12-612 // Methods to handle the birth and death of agents 12-613 - agentBirth: (SugarAgent *)agent 12-614 { 12-615 *************** 12-616 *** 217,220 **** 12-617 --- 269,280 ---- 12-618 return agentList; 12-619 } 12-620 12-621 + 12-622 + - getPredatorList 12-623 + { 12-624 + return predatorList; 12-625 + } 12-626 + 12-627 + 12-628 + 12-629 @end 12-630 12-631 12-632 ObserverSwarm.h 12-633 12-634 diff -rc --new-file sss-2.2/ObserverSwarm.h sss-2.3/ObserverSwarm.h 12-635 *** sss-2.2/ObserverSwarm.h 2003-04-18 20:44:27.000000000 -0400 12-636 --- sss-2.3/ObserverSwarm.h 2004-07-29 03:38:30.000000000 -0400 12-637 *************** 12-638 *** 23,30 **** 12-639 --- 23,33 ---- 12-640 id worldRaster; // window on world 12-641 id sugarDisplay; // sugar displayer 12-642 id agentDisplay; // agent displayer 12-643 + id predatorDisplay; 12-644 id populationGraph; // population graph 12-645 id attributeGraph; // agent attributes graph 12-646 + id killGraph; //New for Predators 12-647 + 12-648 id wealthHistogram; // histogram of wealth 12-649 12-650 id displayActions; // schedule objects 12-651 12-652 12-653 12-654 ObserverSwarm.m 12-655 12-656 diff -rc --new-file sss-2.2/ObserverSwarm.m sss-2.3/ObserverSwarm.m 12-657 *** sss-2.2/ObserverSwarm.m 2003-04-20 06:47:46.000000000 -0400 12-658 --- sss-2.3/ObserverSwarm.m 2004-07-29 03:42:36.000000000 -0400 12-659 *************** 12-660 *** 155,165 **** 12-661 --- 155,184 ---- 12-662 [agentDisplay setDisplayMessage: M(drawSelfOn:)]; // draw method 12-663 agentDisplay = [agentDisplay createEnd]; 12-664 12-665 + 12-666 + predatorDisplay = [Object2dDisplay createBegin: self]; 12-667 + [predatorDisplay setDisplayWidget: worldRaster]; 12-668 + [predatorDisplay setDiscrete2dToDisplay: [sugarSpace getPredatorGrid]]; 12-669 + [predatorDisplay setObjectCollection: [modelSwarm getPredatorList]]; 12-670 + [predatorDisplay setDisplayMessage: M(drawSelfOn:)]; // draw method 12-671 + predatorDisplay = [predatorDisplay createEnd]; 12-672 + 12-673 + 12-674 + 12-675 + 12-676 // Enable probes on the world. 12-677 [worldRaster setButton: ButtonRight 12-678 Client: agentDisplay 12-679 Message: M(makeProbeAtX:Y:)]; 12-680 12-681 + [worldRaster setButton: ButtonLeft 12-682 + Client: predatorDisplay 12-683 + Message: M(makeProbeAtX:Y:)]; 12-684 + 12-685 + 12-686 + 12-687 + 12-688 + 12-689 if (drawPopulationGraph) 12-690 { 12-691 // And create a graph of population in the world 12-692 *************** 12-693 *** 208,213 **** 12-694 --- 227,259 ---- 12-695 notificationMethod: @selector(_wealthHistogramDeath_:)]; 12-696 } 12-697 12-698 + 12-699 + 12-700 + 12-701 + // New Graph for Predators! 12-702 + killGraph = [EZGraph createBegin: self]; 12-703 + SET_WINDOW_GEOMETRY_RECORD_NAME (killGraph); 12-704 + [killGraph setTitle: "Predator Kills"]; 12-705 + [killGraph setAxisLabelsX: "time" Y: "kills"]; 12-706 + killGraph = [killGraph createEnd]; 12-707 + 12-708 + //Little routine to add line for each predator 12-709 + { 12-710 + id predatorList = [modelSwarm getPredatorList]; 12-711 + id index = [predatorList begin: self]; 12-712 + id aPredator; 12-713 + int i = 1; 12-714 + for (aPredator=[index next];[index getLoc]==Member;aPredator=[index next]) 12-715 + { 12-716 + char name[20]; 12-717 + snprintf(name,20,"Predator %d",i); 12-718 + [killGraph createSequence: name 12-719 + withFeedFrom: aPredator 12-720 + andSelector: M(getNumKilled)]; 12-721 + i++; 12-722 + } 12-723 + } 12-724 + 12-725 return self; 12-726 } 12-727 12-728 *************** 12-729 *** 228,233 **** 12-730 --- 274,280 ---- 12-731 { 12-732 [sugarDisplay display]; 12-733 [agentDisplay display]; 12-734 + [predatorDisplay display]; 12-735 [worldRaster drawSelf]; 12-736 } 12-737 return self; 12-738 *************** 12-739 *** 274,279 **** 12-740 --- 321,327 ---- 12-741 [displayActions createActionTo: self message: M(_updateDisplay_)]; 12-742 12-743 [displayActions createActionTo: attributeGraph message: M(step)]; 12-744 + [displayActions createActionTo: killGraph message: M(step)]; 12-745 if (drawPopulationGraph) 12-746 [displayActions createActionTo: populationGraph message: M(step)]; 12-747 if (drawWealthHistogram) 12-748 Binary files sss-2.2/pacman.png and sss-2.3/pacman.png differ 12-749 12-750 12-751 12-752 12-753 SugarAgent.h 12-754 12-755 diff -rc --new-file sss-2.2/SugarAgent.h sss-2.3/SugarAgent.h 12-756 *** sss-2.2/SugarAgent.h 1999-08-26 20:45:10.000000000 -0400 12-757 --- sss-2.3/SugarAgent.h 2004-07-26 11:49:21.000000000 -0400 12-758 *************** 12-759 *** 3,8 **** 12-760 --- 3,9 ---- 12-761 // implied warranty of merchantability or fitness for a particular purpose. 12-762 // See file LICENSE for details and terms of copying. 12-763 12-764 + #import 12-765 #import // we use Space features 12-766 #import 12-767 #import "SugarSpace.h" 12-768 12-769 12-770 SugarAgent.m 12-771 12-772 diff -rc --new-file sss-2.2/SugarAgent.m sss-2.3/SugarAgent.m 12-773 *** sss-2.2/SugarAgent.m 1999-08-26 20:45:10.000000000 -0400 12-774 --- sss-2.3/SugarAgent.m 2004-07-27 02:09:02.000000000 -0400 12-775 *************** 12-776 *** 165,170 **** 12-777 --- 165,171 ---- 12-778 newX = goodX[chosenSpot]; // get the coordinate 12-779 newY = goodY[chosenSpot]; // and move there! 12-780 [sugarSpace moveAgent: self toX: newX Y: newY]; 12-781 + //note sugarSpace inserts new position into this agent. 12-782 } 12-783 return self; 12-784 } 12-785 12-786 12-787 12-788 diff -rc --new-file sss-2.2/SugarSpace.h sss-2.3/SugarSpace.h 12-789 *** sss-2.2/SugarSpace.h 2003-04-20 06:47:46.000000000 -0400 12-790 --- sss-2.3/SugarSpace.h 2004-07-27 03:07:22.000000000 -0400 12-791 *************** 12-792 *** 11,16 **** 12-793 --- 11,18 ---- 12-794 #import 12-795 #import 12-796 12-797 + //These are here to remedy "circularity" of header inclusions 12-798 + @class Predator; 12-799 @class SugarAgent; 12-800 12-801 // A SugarValue is a measurement of how much sugar is at the world. 12-802 *************** 12-803 *** 31,36 **** 12-804 --- 33,39 ---- 12-805 SugarValue globalMaxSugar; // absolute maximum for space 12-806 12-807 id agentGrid; // agent positions 12-808 + id predatorGrid; 12-809 } 12-810 12-811 // Use this method at object creation - set the size of the world. 12-812 *************** 12-813 *** 62,70 **** 12-814 - removeAgent: (SugarAgent *)agent; 12-815 - moveAgent: (SugarAgent *)agent toX: (int)x Y: (int)y; 12-816 12-817 // Get the array of all the agents in the space. 12-818 - (id )getAgentGrid; 12-819 ! 12-820 // coordinate normalization. This handles coordinates out of range by 12-821 // wrapping them around. 12-822 - (int)xnorm: (int)x; 12-823 --- 65,79 ---- 12-824 - removeAgent: (SugarAgent *)agent; 12-825 - moveAgent: (SugarAgent *)agent toX: (int)x Y: (int)y; 12-826 12-827 + - (Predator *)getPredatorAtX: (int)x Y: (int)y; 12-828 + - addPredator: (Predator *)agent atX: (int)x Y: (int)y; 12-829 + - removePredator: (Predator *)agent; 12-830 + - movePredator: (Predator *)agent toX: (int)x Y: (int)y; 12-831 + 12-832 + 12-833 // Get the array of all the agents in the space. 12-834 - (id )getAgentGrid; 12-835 ! - (id )getPredatorGrid; 12-836 // coordinate normalization. This handles coordinates out of range by 12-837 // wrapping them around. 12-838 - (int)xnorm: (int)x; 12-839 12-840 12-841 SugarSpace.m 12-842 12-843 diff -rc --new-file sss-2.2/SugarSpace.m sss-2.3/SugarSpace.m 12-844 *** sss-2.2/SugarSpace.m 2003-04-20 06:52:03.000000000 -0400 12-845 --- sss-2.3/SugarSpace.m 2004-07-27 03:05:44.000000000 -0400 12-846 *************** 12-847 *** 6,11 **** 12-848 --- 6,12 ---- 12-849 // Here we implement the class SugarSpace. 12-850 #import "SugarSpace.h" 12-851 #import "SugarAgent.h" 12-852 + #import "Predator.h" 12-853 12-854 #import // InFile 12-855 #import // strdup 12-856 *************** 12-857 *** 82,87 **** 12-858 --- 83,94 ---- 12-859 agentGrid = [Grid2d createBegin: [self getZone]]; 12-860 [agentGrid setSizeX: xsize Y: ysize]; 12-861 agentGrid = [agentGrid createEnd]; 12-862 + 12-863 + 12-864 + predatorGrid = [Grid2d createBegin: [self getZone]]; 12-865 + [predatorGrid setSizeX: xsize Y: ysize]; 12-866 + predatorGrid = [predatorGrid createEnd]; 12-867 + 12-868 12-869 return self; 12-870 } 12-871 *************** 12-872 *** 182,187 **** 12-873 --- 189,238 ---- 12-874 return self; 12-875 } 12-876 12-877 + 12-878 + 12-879 + //// Code to manage Predator positions is copied directly from 12-880 + // methods for sugar agent movement. 12-881 + 12-882 + - (Predator *)getPredatorAtX: (int)x Y: (int)y 12-883 + { 12-884 + return [predatorGrid getObjectAtX: [self xnorm: x] Y: [self ynorm: y]]; 12-885 + } 12-886 + 12-887 + 12-888 + - addPredator: (Predator *)agent atX: (int)x Y: (int)y 12-889 + { 12-890 + x = [self xnorm: x]; 12-891 + y = [self ynorm: y]; 12-892 + agent->x = x; 12-893 + agent->y = y; 12-894 + [predatorGrid putObject: agent atX: x Y: y]; 12-895 + 12-896 + return self; 12-897 + } 12-898 + 12-899 + 12-900 + - removePredator: (Predator *)agent 12-901 + { 12-902 + int x, y; 12-903 + 12-904 + x = [self xnorm: agent->x]; 12-905 + y = [self ynorm: agent->y]; 12-906 + if ([self getPredatorAtX: x Y: y] == agent) 12-907 + [predatorGrid putObject: nil atX: x Y: y]; 12-908 + 12-909 + return self; 12-910 + } 12-911 + 12-912 + - movePredator: (Predator *)agent toX: (int)x Y: (int)y 12-913 + { 12-914 + [self removePredator: agent]; 12-915 + [self addPredator: agent atX: x Y: y]; 12-916 + 12-917 + return self; 12-918 + } 12-919 + 12-920 + 12-921 //// The code below here is not very interesting - it has to do with 12-922 //// the technical details of managing the data in the model, not the 12-923 //// modelling itself. You can safely ignore it until you want to know 12-924 *************** 12-925 *** 216,221 **** 12-926 --- 267,279 ---- 12-927 return agentGrid; 12-928 } 12-929 12-930 + - (id )getPredatorGrid 12-931 + { 12-932 + return predatorGrid; 12-933 + } 12-934 + 12-935 + 12-936 +