We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › No idea what could be the problem!!
Page Index Toggle Pages: 1
No idea what could be the problem!! (Read 827 times)
No idea what could be the problem!!
Sep 15th, 2008, 4:40am
 
I am fairly new at processing and I have run into a error that I cannot figure out.  I have done some java before, and I don't think that this error would have happened in pure java.

By the way the code is a zombie/human simulation mod that is basically copied off: http://zombies.insertdisc.com/zombies.java by Kevan Davis.  I am just recoding it as an exercise and since I have run into this error my code has been getting closer to Davis's because I am trying to ween out the bug.  Here is my code:

//Containers
Being [] beings;

//Controlling Vars
int numZombies = 1;
int numHumans = 6000;
int totalBeings;

color zombie = color(0,255,0);
color human = color(255,0,0);
color panicHuman = color(255,0,255);
color wall = color(0,0,0);
color nothing = color(1,1,1);

void setup() {
 size(200,200);
 background(0);
 frameRate(30);
 
 totalBeings = numZombies + numHumans;
 
 beings = new Being[totalBeings];

 //Create Zombies
 for(int i = 0; i<numZombies; i++) {
   beings[i] = new Being(true); //True = isZombie
 }
 
 //Create Humans
 for(int i = numZombies; i<totalBeings; i++) {
   beings[i] = new Being(false);
 }
}

void draw() {
 background(0);
 //println(frameRate);
 for(int i = 0;i<totalBeings;i++) {
   beings[i].exist();
 }
}

color look(int x, int y, int dir, int d) {
   int xpos = x;
   int ypos = y;
   for(int i = 0; i < d; i++) {
     if(dir==1) ypos--;
     if(dir==2) xpos++;
     if(dir==3) ypos++;
     if(dir==4) xpos--;

     if(xpos>width-1 || xpos<1 || ypos>height-1 || ypos<1) return wall;
     else if(get(xpos,ypos) == human) return human;
     else if(get(xpos,ypos) == panicHuman) return panicHuman;
     else if(get(xpos,ypos) == zombie) return zombie;
   }
   return nothing;
 }

class Being {

 //State
 boolean isZombie;
 int x,y;
 int dir; //1 = up, 2 = right, 3 = down, 4 = left
 int panic = 0;

 //Controlling vars
 color zombie = color(0,255,0);
 color human = color(255,0,0);
 color panicHuman = color(255,0,255);
 color wall = color(0,0,0);
 color nothing = color(1,1,1);

 int panicTurns = 5;
 int mass = 5;
 int distance = 10;


 Being(boolean isZombie) {
   this.isZombie = isZombie;

   x = (int)random(width)+1;
   y = (int)random(height)+1;
   dir = (int)random(4) + 1;
 }

 //The main loop for the zombie/human.
 void exist() {
   checkState();
   updatePosition();
   apply();
 }

 //This function updates the being's state vars depending on if the being is a zombie or a human
 void checkState() {
   if(isZombie) {
     fill(zombie);
     stroke(zombie);
   }
   else if(panic > 0) {
     fill(panicHuman);
     stroke(panicHuman);
   }
   else {
     fill(human);
     stroke(human);
   }
 }

 void updatePosition() {

   int r = (int)random(10);
   if((!isZombie && panic>0) || r < 3) {
     //update position
     if(look(x,y,dir,1)==nothing) {
       if(dir==1) y--;
       else if(dir==2) x++;
       else if(dir==3) y++;
       else if(dir==4) x--;
     }
     else {
       dir = (int)random(4)+1;
     }

     if(panic>0) panic--;
   }

   int target = look(x,y,dir,distance);

   if(isZombie) {
     //Look around!
     if(target == zombie || target == wall || (target == nothing && (int)random(5) == 1)) {
       dir = (int)random(4)+1;
     }

     int ix = x, iy = y;
     if(dir==1) iy--;
     if(dir==2) ix++;
     if(dir==3) iy++;
     if(dir==4) ix--;
     
     if(target == panicHuman || target == human) println("i see human!");
     
     //Infect something?!
     if(look(x,y,dir,1) == human) { //This line triggers the error
       for(int i=0; i<totalBeings; i++) {
         beings[i].infect(ix,iy);
       }
     }

   } else { //Is I human?!

     //Oh Noes!  Look for zombies!
     if(target == zombie) panic = panicTurns;
     else if(target == wall || target == human) dir = (int)random(4)+1;
     else if(target == nothing && (int)random(8) == 1) dir = (int)random(4)+1;

     //Run away!
     if(target == zombie) {
       dir += 2;
       if(dir>4) dir -= 4;
     }
   }
 }

 void infect(int ix, int iy) {
   if(x == ix && y == iy) isZombie = true;
 }

 void apply() {
   //ellipse(x,y,5,5);
   point(x,y);
 }
}


The error isn't a syntax error or a error processing tells me...  Its just that whenever the if statement that has the error comment (in the updatePosition() function) is uncommented (as it is now), the zombies dont even see humans...  However when it is commented they see humans and infect them.  I am completely lost as to why, because it seems to me that this is just a simple if statement.

Thanks in advance for help!!
Re: No idea what could be the problem!!
Reply #1 - Sep 15th, 2008, 11:32am
 
I got it.
I played a bit with your code, trying some improvements, but with the same issue as you. I found the idea of using the image as data storage... I don't know, I would say not very appropriate: it doesn't scale to bigger graphics, and it might be slow (the three get() in the look() function is overkill! Wink).
Finally, I found out why the initial zombie seemed to be short-sighted (never seeing humans).
On each draw() call, background(0) clears the sketch, then you loop on the beings, checking their status and displaying them one by one.
But the zombie is at the beginning of the loop, drawn first, in a surface full of nothing, the humans waiting behind to be updated and drawn... So it will never see anything but nothingness and walls.
By removing the test, the zombie can infect humans it doesn't see (by touch! Smiley). Moreover, the new zombies being randomly in the middle of the loop, they can see humans drawn before.
Without looking at the original code, I guess it used double buffering, looking in the old buffer and updating in the new one.

Solution?
If you want to keep your method, just create the zombie(s) after the humans. But still a number of beings won't see the others.
Otherwise, keep an array of states equals to the size of the sketch (or corresponding to grid, thus smaller). Or perhaps a double array (previous and current state), to avoid changing states before all beings are checked.

For what it is worth, here is the current state of my changes to your code (implementing lazily the first suggestion only!).
Code being long, I just put it in PasteBin: http://pastebin.com/f5afc6fb4
Re: No idea what could be the problem!!
Reply #2 - Sep 15th, 2008, 12:22pm
 
On second thought, I see some advantages of using the display memory as state storage: it is updated automatically (when drawing), it doesn't use extra storage, and in our case, it allows partial seeing if being is bigger than one pixel.
And I remembered a simple way to have a copy of this storage, with extra advantage: looking up the copy is faster than using get(). The loadPixels() function will copy the screen display to an array of pixels[]. We can do that just before clearing the background, and we are done.

Update at http://pastebin.com/f385545e
Re: No idea what could be the problem!!
Reply #3 - Sep 15th, 2008, 12:37pm
 
Just tried an amusing variant when zombies finally decay and stay dead.
http://pastebin.com/f714c6232

[EDIT] http://pastebin.com/f632a160e - Added some stats
Amusing simulation indeed. It shows that lot of humans (dense population) are more vulnerable: they have difficulties to run away (other humans being on the way), thus zombies can reach them.
With my decay variant, in some cases, we can see some surviving humans lost among a see of cadavers... Brr...
Re: No idea what could be the problem!!
Reply #4 - Sep 15th, 2008, 1:37pm
 
Ah the zombie simulation. That's what initially got me into processing many many years ago.

I made a few variations on it myself:

http://www.hardcorepawn.com/zombie/

http://www.hardcorepawn.com/zombie2/

http://www.hardcorepawn.com/zombie3/ etc..

Re: No idea what could be the problem!!
Reply #5 - Sep 15th, 2008, 3:07pm
 
Amusing and interesting variations, JohnG.
The last two (Zombies4 and Winter Zombies) doesn't work, even as I know I have a very recent Java version. Opening the Java console shows the culprit: you try to manage sound, and I get exceptions, because I am trying your applets on a computer without sound card (or at least, without sound driver on WinXP).
That's not the first Java program I see to fail because of this.
Of course, I suppose it is a very rare setting (no sound on a modern computer), so I don't know if it is worth fixing this issue.
Re: No idea what could be the problem!!
Reply #6 - Sep 15th, 2008, 11:13pm
 
Ha ha.

I must show the boss Winter Zombies. He will be very upset that someone has already made the zombie city game.
Re: No idea what could be the problem!!
Reply #7 - Sep 15th, 2008, 11:49pm
 
Wow thanks so much PhiLho for pointing out my obvious background error...  I totally forgot about that since I keep my classes in tabs and thus don't often go back to classes that I think work...  Yay for silly coding errors...

I figured out another way to fix the problem, although your final fix (using the pixels[] array) is both faster and better...

Essentially the other way would be that before movement the being would turn its own pixel black, then move and then paint itself back in.  That way you don't even have to redraw the background...

Anyways, I am on my way to modifying the zombie simulation so that they are ellipses and they get bigger as they eat more brains.  ARRRR BRAINS...

Thanks for all the help!  I am going to post my new simulation here once its done.  Cheesy

Oh and I love the variants JohnG!  Cheesy
Re: No idea what could be the problem!!
Reply #8 - Sep 16th, 2008, 4:20am
 
Ok so I hacked this around for a bit and here is what I have come up with.

Zombies increase in size when they kill
Zombies become cannibals (eat other zombies) if they can't find humans and they are about to die
Zombies are much more dangerous

Panic humans make other humans panic

Just play with the variables in the first part of the program and have some fun.  Its really interesting doing extremes like 1 zombie/1000 humans or 0 humans/1000 zombies.  Also experiment with the size of the window as it has a big effect on the zombies winning (killing all humans)...

http://2dsquid.pastebin.com/f52b9750e

Cheesy  Hack it and see what you can come up with!
Page Index Toggle Pages: 1