import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; public class zombies extends BApplet { // Zombie Infection Simulation // Kevan Davis, 16/8/03 // 030904 vMFF-1.9 Modified by Markleford Friedman (www.markleford.com) boolean flagFreeze = true; boolean flagFirst = true; int num = 1000; int speed = 2; int cntHumans = 0; int cntZombies = 0; // Constants static int MAX_POPULATION = 4000; static int MAP_WIDTH = 250; static int MAP_HEIGHT = 250; static int TEXT_HEIGHT = 0; static int TYPE_NONE = 0; static int TYPE_WALL = 1; static int TYPE_ZOMBIE = 2; static int TYPE_HUMAN = 3; static int TYPE_PANIC = 4; static int TYPE_HUNTER = 5; static int DIR_NORTH = 0; static int DIR_EAST = 1; static int DIR_SOUTH = 2; static int DIR_WEST = 3; // Color constants will be specified programmatically int COLOR_HUMAN; int COLOR_PANIC; int COLOR_ZOMBIE; int COLOR_HUNTER; int COLOR_WALL; int COLOR_BACK; int COLOR_DEAD; // Preset variables Being[] beings = new Being[MAX_POPULATION]; void drawMap() { int i; // Paint the background fill(COLOR_BACK); rect(0, 0, MAP_WIDTH, MAP_HEIGHT); // Paint the buildings fill(COLOR_WALL); stroke(COLOR_BACK); for (i = 0; i < 100; i++) { rect((int)random(MAP_WIDTH+10)-5, (int)random(MAP_HEIGHT+10)-5, (int)random(60)+10, (int)random(60)+10); } // Create open areas fill(COLOR_BACK); for (i = 0; i < 30; i++) { rect((int)random(MAP_WIDTH), (int)random(MAP_HEIGHT), (int)random(20)+20,(int)random(20)+20); } fill(COLOR_WALL); stroke(COLOR_WALL); //rect(0, MAP_HEIGHT, MAP_WIDTH, TEXT_HEIGHT); } void resetSim() { int i; // Paintin' time! drawMap(); // Place all beings for(i = 0; i < num; i++) { beings[i].reset(); } // Create one zombie beings[0].infect(); // Init the counts cntHumans = num - 1; cntZombies = 1; // Unfreeze the sim (enable loop() processing) flagFreeze = false; } void setup() { // Set dimensions size(MAP_WIDTH, MAP_HEIGHT + TEXT_HEIGHT); // Disable screen refresh noBackground(); // Set up the colors COLOR_HUMAN = color(200,130,200); COLOR_PANIC = color(255,200,220); COLOR_ZOMBIE = color(54,215,90); COLOR_HUNTER = color(255,255,255); COLOR_WALL = color(80,80,80); COLOR_BACK = color(0,0,0); COLOR_DEAD = color(0,96,192); for(int i = 0; i < MAX_POPULATION; i++) { beings[i] = new Being(); } } void loop() { if (!flagFreeze) { for(int i=0; i= MAP_WIDTH) || (x < 0) || (y >= MAP_HEIGHT) || (y < 1)) { return TYPE_WALL; } else if (getPixel(x,y) == COLOR_WALL) { return TYPE_WALL; } else if (getPixel(x,y) == COLOR_PANIC) { return TYPE_PANIC; } else if (getPixel(x,y) == COLOR_HUMAN) { return TYPE_HUMAN; } else if (getPixel(x,y) == COLOR_HUNTER) { return TYPE_HUNTER; } else if (getPixel(x,y) == COLOR_ZOMBIE) { return TYPE_ZOMBIE; } } return TYPE_NONE; } void keyPressed() { if(key == ' ') { for(int i=0; i 250) { flagFreeze=true; num -= 250; resetSim(); } } if(key == 's' || key == 'S') { speed--; if (speed == 0) { speed = 3; } } } class Being { // Member variables int xpos, ypos, dir; int type, active; boolean alive; Being() { //reset(); } void reset() { xpos = 0; ypos = 0; dir = (int)random(4); type = TYPE_HUMAN; position(); active = 0; alive = true; } void position() { //for(int i = 0; i < 1000; i++) while (true) { // Get a random point xpos = (int)random(MAP_WIDTH); ypos = (int)random(MAP_HEIGHT); // Test if it is unoccupied if (getPixel(xpos,ypos) == COLOR_BACK) { break; } } } int getTarget(int x, int y) { for(int i=0; i 50) { infect(); } else { panic(); } } } } void panic() { active = 10; } void kill() { this.alive = false; setPixel(xpos, ypos, COLOR_DEAD); cntZombies--; } void infect() { type = TYPE_ZOMBIE; setPixel(xpos, ypos, COLOR_ZOMBIE); cntZombies++; cntHumans--; } void imbue() { type = TYPE_HUNTER; setPixel(xpos, ypos, COLOR_HUNTER); } void uninfect() { type = TYPE_HUMAN; alive = true; } void move() { if(!this.alive) { if(getPixel(xpos, ypos) == COLOR_BACK) { setPixel(xpos, ypos, COLOR_DEAD); } return; } // Check our line of sight... if (type == TYPE_HUMAN) { int target = look(xpos,ypos,dir,10); // Holy shit! ZOMBIE! if (target == TYPE_ZOMBIE) { active = 10; } // Hey, what's that guy scared of? if(target == TYPE_PANIC) { active = (int)random(5); } // If a Zombie is in our path (or we're just bored) change course if ((target == TYPE_ZOMBIE) || ((int)random(8) == 0)) { dir = (dir + 1 + (int)random(3)) % 4; } } if (type == TYPE_ZOMBIE) { int target = look(xpos,ypos,dir,7); // Braaaiiinnns!!! if (target == TYPE_HUMAN || target == TYPE_PANIC || target == TYPE_HUNTER) { active = 10; } // Is someone in front of us? int victim = look(xpos,ypos,dir,1); if (victim == TYPE_HUMAN || victim == TYPE_PANIC || victim == TYPE_HUNTER) { int ix = xpos; int iy = ypos; if (dir == DIR_NORTH) { iy--; } if (dir == DIR_EAST) { ix++; } if (dir == DIR_SOUTH) { iy++; } if (dir == DIR_WEST) { ix--; } int i = -1; if((i = getTarget(ix,iy)) >= 0) { beings[i].attack(); } } else { // Darn, no brains... if (active == 0 && ((int)random(8) == 0)) { dir = (dir + 1 + (int)random(3)) % 4; active = 5; } /* if (((int)random(active+1) == 0) || (victim == TYPE_ZOMBIE && (int)random(5) == 0)) { dir = (dir + 1 + (int)random(3)) % 4; active = 5; } */ } } if (type == TYPE_HUNTER) { int target = look(xpos,ypos,dir,15); // Kill that sumbitch! if (target==TYPE_ZOMBIE) { active = 10; } // Are we next to him now? int victim = look(xpos,ypos,dir,1); if (victim == TYPE_ZOMBIE) { int ix = xpos; int iy = ypos; if (dir == DIR_NORTH) { iy--; } if (dir == DIR_EAST) { ix++; } if (dir == DIR_SOUTH) { iy++; } if (dir == DIR_WEST) { ix--; } int i = -1; if((i = getTarget(ix,iy)) >= 0) { beings[i].kill(); active = 2; } } // Bored now: wander some if (active == 0 && ((int)random(8) == 0)) { dir = (dir + 1 + (int)random(3)) % 4; } } // Move in a straight line... // Unset our pixel setPixel(xpos, ypos, COLOR_BACK); // If nothing in front of us, take a step forward if (type == TYPE_ZOMBIE && ((int)random(active/2) == 0)) { // No move } else { if (look(xpos,ypos,dir,1) == TYPE_NONE) { if (dir == DIR_NORTH) { ypos--; } if (dir == DIR_EAST) { xpos++; } if (dir == DIR_SOUTH) { ypos++; } if (dir == DIR_WEST) { xpos--; } } else { // We hit an obstacle: choose a new direction dir = (dir + 1 + (int)random(3)) % 4; } } if (type == TYPE_ZOMBIE) { setPixel(xpos, ypos, COLOR_ZOMBIE); } else if (type == TYPE_HUNTER) { if (active > 0) { // Panicked humans get an extra move if (look(xpos,ypos,dir,1) == TYPE_NONE) { if (dir == DIR_NORTH) { ypos--; } if (dir == DIR_EAST) { xpos++; } if (dir == DIR_SOUTH) { ypos++; } if (dir == DIR_WEST) { xpos--; } } else { // We hit an obstacle: choose a new direction dir = (dir + 1 + (int)random(3)) % 4; } } setPixel(xpos, ypos, COLOR_HUNTER); } else if (active > 0) { // Panicked humans get an extra move if (look(xpos,ypos,dir,1) == TYPE_NONE) { if (dir == DIR_NORTH) { ypos--; } if (dir == DIR_EAST) { xpos++; } if (dir == DIR_SOUTH) { ypos++; } if (dir == DIR_WEST) { xpos--; } } else { // We hit an obstacle: choose a new direction dir = (dir + 1 + (int)random(3)) % 4; } setPixel(xpos, ypos, COLOR_PANIC); } else { setPixel(xpos, ypos, COLOR_HUMAN); } if (active>0) { active--; } } } }