;; SUMMARY ;;;; Zombies ruin everything. ;; COPYRIGHT & LICENSE ;;;; Copyright (C) 2005 James P. Steiner ;;;; Some Rights Reserved. ;;;; Creative Commons Attribution-NonCommercial-ShareAlike License v. 2.0. ;;;; Visit http://creativecommons.org/licenses/by-nc-sa/2.0/ for more information. ;; APPLET DIMENSIONS (width x height) ;;;; 1000 x 600 ;; globals [ wall-color space-color crumb-color human-color panic-color zombie-color chase-color dead-color clock tick last-tick ] breeds [ clocks humans corpses zombies ] humans-own [ mood-change? will-panic? panic? panic-countdown infected? threats ] corpses-own [ gestation-countdown ] zombies-own [ frenzy? mood-change? frenzy-countdown decomposition resting-countdown targets ] patches-own [ wall ] to-report special-effect place-clock report timer end to-report sign [ value ] ifelse value < 0 [ report -1 ][ ifelse value > 0 [ report 1 ][ ifelse value = 0 [ report 0 ][ ]]] end to setup ca set space-color black set wall-color violet - 2 set human-color gray set panic-color white set dead-color red set zombie-color green set chase-color yellow ifelse graphics? [ set-default-shape turtles "person" set-default-shape humans "person" set-default-shape zombies "zombie" set-default-shape corpses "corpse" ] [ foreach (list turtles humans zombies corpses) [ set-default-shape ? "square" ] ] run layout ask patches with [ is-wall? self ] [ set wall wall-strength ] make-clock make-people display end to reset ask turtles with [ breed != clocks ] [ die ] setup-people end to setup-people make-people end to make-people let spaces patches with [ pcolor = space-color ] let pop min (list population (count spaces) ) ask random-n-of pop spaces [ sprout 1 [ setup-person ] ] ask random-one-of humans [ die-and-gestate ] ;; blink the corpse for a while ask corpses [ repeat 3 [ let sz 10 repeat 9 [ set size sz wait .05 set sz sz - 1 ] ] set size 1] end to setup-person set breed humans set heading 90 * random 4 set panic? false set infected? false set panic-countdown 0 set color human-color end to make-clock create-custom-clocks 1 [ set shape "clock" set heading 0 set clock self set size 0 setxy screen-edge-x screen-edge-y ] end to place-clock if not is-turtle? clock [ make-clock ] let clock-size clock-scale * .01 * screen-edge-x * .5 if size-of clock != clock-size [ set size-of clock clock-size set xcor-of clock ((screen-edge-x - clock-size * .5) * sign xcor-of clock ) set ycor-of clock ((screen-edge-y - clock-size * .5) * sign ycor-of clock ) display ] end to monitor-mouse-move-clock if mouse-down? [ ask clock [ if abs (mouse-xcor - xcor) < (size * 2) and abs (mouse-ycor - ycor) < (size * 2 ) [ setxy (ycor) (- xcor) ] ] ] place-clock end to die-and-gestate set breed corpses set gestation-countdown incubation-period set color dead-color end to go no-display set tick tick + 1 ask clock [ rt 6 ] if not any? humans or not (any? zombies or any? corpses) [ if not any? humans [ cct-zombies 1 [ set size screen-size-x set color green set label "Z O M B I E !" ] ] display stop ] ifelse watch? [ if subject = nobody [ ifelse any? zombies [ watch random-one-of zombies ] [ ifelse any? corpses [ watch random-one-of corpses ] [ watch random-one-of humans ]]] ][ if is-turtle? subject [ reset-perspective ] ] ask humans [ human-change-mood ] ask zombies [ zombie-change-mood ] ask humans [ human-do-things ] ask zombies [ zombie-do-things ] ask corpses [ corpse-do-things ] if count humans >= 2 and random-float 1.0 < human-repro-rate * (count humans) [ ask random-one-of (patches with [ pcolor = space-color ]) [ sprout 1 [ setup-person ] ] ] set-current-plot-pen "people" plot count humans set-current-plot-pen "zombies" plot count zombies monitor-mouse-move-clock display end to human-panic-now! set mood-change? "panic!" end to human-relax... set mood-change? "relax" end to human-change-mood ifelse mood-change? = "panic!" [ set panic-countdown int ( panic-time * .25 + random (panic-time * .75) ) set color panic-color set panic? true let threat random-one-of threats ifelse is-turtle? threat and threat != nobody [ ifelse breed-of threat = humans [ set heading heading-of threat ] [ if value-from threat [ patch-here ] != patch-here [ set heading 180 + towards-nowrap threat ]] ] [ set heading random 8 * 90 ] if is-space? patch-ahead .5 [ jump .5 ] ] [ if mood-change? = "relax" [ set panic-countdown 0 set color human-color set panic? false ] ] set mood-change? "" end to human-vision-old locals [ index ] set index 1 while [ index < human-vision-range and is-space? patch-ahead index and not panic? ] [ ifelse any? value-from (patch-ahead index) [ turtles-here with [ breed != humans ] ] [ human-panic-now! ] [ set index index + 1 ] ] end to human-do-things locals [ index ] ifelse panic? [ ifelse is-wall? patch-ahead .5 or panic-countdown < 1 [ human-relax... rt 90 * (((random 2) * 2) - 1) ] [ jump .5 ;; setxy (pxcor) pycor set panic-countdown panic-countdown - 1 ] ] [ if tick mod 2 = 0 [ set index 1 set threats turtles in-radius-nowrap human-vision-range with [ breed = zombies or breed = corpses or (breed = humans and panic?) ] ifelse any? threats [ human-panic-now! ] [ let paths neighbors4 with [ is-space? self and not any? turtles-here] if any? paths [ set heading towards random-one-of paths jump .5 ;; setxy (pxcor) pycor ] ] ] ] if infected? [ die-and-gestate ] end to zombie-vision-old locals [ index ] set index 1 let pir patches at-points ( n-values zombie-vision-range [ (list (dx * (? + 1)) (dy * (? + 1)) ) ]) set pir pir end to zombie-change-mood ifelse mood-change? = "frenzy!" [ set frenzy? true if is-agentset? targets [ let target random-one-of targets carefully [ set heading towards target ] [ set heading random 8 * 45 ] set frenzy-countdown int ( frenzy-time * .25 + random (frenzy-time * .75) ) set color chase-color ; + ifelse-value ( decomposition > 50) [ 20 ] [ 0 ] ] ] [ if mood-change? = "relax..." [ set frenzy? false set frenzy-countdown 0 set color zombie-color ; + ifelse-value ( decomposition > 50) [ 20 ] [ 0 ] if zombie-smash!? [ without-interruption [ let next-patch patch-ahead .5 if is-wall? next-patch [ ask next-patch [ set wall wall - 1 set pcolor scale-color wall-color (wall-strength - wall) (- wall-strength) (wall-strength * 2) if wall <= 0 [ set wall 0 set pcolor space-color ] ] zombie-eww!-decompose ] ] ] ] ] set mood-change? "" end to zombie-do-things locals [ index ] zombie-eww!-decompose ifelse resting-countdown > 0 [ set resting-countdown resting-countdown - 1 ] [ without-interruption [ if any? humans-here [ zombie-attack! ] ] ifelse frenzy? [ ifelse is-wall? patch-ahead .5 [ set mood-change? "relax..." ] [ jump .5 ;; setxy (pxcor) pycor set frenzy-countdown frenzy-countdown - 1 if frenzy-countdown <= 0 [ zombie-relax... ] ] ] [ if tick mod 2 = 0 [ let paths neighbors4 with [ is-space? self ] if any? paths [ set heading towards random-one-of paths jump .5 ;; setxy (pxcor) pycor ] set targets humans in-radius-nowrap zombie-vision-range with [ patch-here != value-from myself [patch-here ]] if any? targets [ zombie-frenzy! ] ] ] ] set pcolor space-color + .2 end to corpse-do-things set gestation-countdown gestation-countdown - 1 if gestation-countdown <= 0 [ hatch-zombie ] end to hatch-zombie set breed zombies set heading 90 * random 4 set decomposition 0 zombie-relax... end to zombie-attack! ask random-one-of humans-here [ set infected? true ] set resting-countdown after-kill-rest ifelse blood-lust? [ zombie-frenzy! ] [ zombie-relax... ] end to zombie-relax... set frenzy? false set frenzy-countdown 0 set color zombie-color end to zombie-frenzy! set mood-change? "frenzy!" end to zombie-eww!-decompose set decomposition decomposition + decompose-rate if decomposition >= 100 [ die ] end to corridors locals [ h w x1 y1 x2 y2 region flipper index ] ask patches [ set pcolor wall-color ] set index int sqrt (screen-size-x * screen-size-y) let invex 0 repeat (index / 2) [ ifelse random 2 = 0 [ set h 3 + int (index * random-float 1 ) * 2 set w 3 + int (invex * random-float 1 ) * 2 ] [ set h 3 + int (invex * random-float 1 ) * 2 set w 3 + int (index * random-float 1 ) * 2 ] set x1 (- screen-edge-x) + random ( screen-size-x - w) set y1 ( screen-edge-y) - random ( screen-size-y - h) set x2 x1 + w set y2 y1 - h set region patches with [ between pxcor x1 x2 and between pycor y1 y2 ] ask region [ set pcolor space-color ] if index mod 4 != 0 ;; random 10 < 8 [ ask region with [ pxcor > x1 and pxcor < x2 and pycor < y1 and pycor > y2 ] [ set pcolor wall-color ] ] set index index - 2 set invex invex + 2 ] ask patches with [ abs pxcor + 1 = screen-edge-x or abs pycor + 1 = screen-edge-y ] [ set pcolor space-color ] ask patches with [ abs pxcor = screen-edge-x or abs pycor = screen-edge-y ] [ set pcolor wall-color ] end to mazes clear-patches clear-turtles set space-color black set wall-color violet - 2 set crumb-color yellow ;; fill in as all walls ask patches [ set pcolor wall-color ] ;; make open-space border around edges (keep maze from wrapping) ask patches with [ abs pxcor > screen-edge-x - 2 or abs pycor > screen-edge-y - 2 ] [ set pcolor space-color ] ;; create a turtle, and do the maze thing cct 1 [ setxy 0 0 set pcolor crumb-color do-maze timer + 1 set pcolor space-color die ] ask patches with [ abs pxcor > screen-edge-x - 2 or abs pycor > screen-edge-y - 2] [ set pcolor wall-color ] end to mazes&plazas mazes let rad int (1 + screen-edge-x * plaza-size * .01) let freq rad * 3 ask patches with [ pxcor mod freq = 0 and pycor mod freq = 0 ] [ ask patches in-radius rad [ set pcolor space-color ] ] ask patches with [ abs pxcor > screen-edge-x - 2 or abs pycor > screen-edge-y - 2] [ set pcolor wall-color ] end to do-maze [ timeout ] if timer > timeout [ stop ] let more?? false let opens patches at-points [[0 2][0 -2][2 0][-2 0]] with [ pcolor = wall-color ] while [ any? opens ] [ let choice random-one-of opens set heading towards choice repeat 2 [ jump 1 set pcolor crumb-color ] set opens patches at-points [[0 2][0 -2][2 0][-2 0]] with [ pcolor = wall-color ] set more?? true ] let crumbs patches at-points [[0 1][0 -1][1 0][-1 0]] with [ pcolor = crumb-color ] if any? crumbs [ let choice random-one-of crumbs set heading towards choice repeat 2 [ set pcolor space-color jump 1 ] set more?? true ] if more?? [ do-maze timeout ] end to-report between [ value limit1 limit2 ] ifelse limit1 <= limit2 [ report (value >= limit1 and value <= limit2 ) ] [ report (value >= limit2 and value <= limit1 ) ] end to-report is-wall? [ agent ] report (shade-of? pcolor-of agent wall-color ) end to-report is-space? [ agent ] report (shade-of? pcolor-of agent space-color) end to goto-patch [ agent ] setxy pxcor-of agent pycor-of agent end to goto-turtle [ agent ] setxy xcor-of agent ycor-of agent end @#$#@#$#@ GRAPHICS-WINDOW 404 10 888 515 39 39 6.0 1 10 1 1 1 0 0 0 1 CC-WINDOW 5 586 897 681 Command Center 0 BUTTON 11 60 66 93 NIL setup NIL 1 T OBSERVER T NIL SLIDER 202 154 374 187 incubation-period incubation-period 0 100 5 1 1 NIL SLIDER 12 120 184 153 human-vision-range human-vision-range 1 100 4 1 1 NIL SLIDER 202 120 374 153 zombie-vision-range zombie-vision-range 0 100 4 1 1 NIL BUTTON 77 60 132 93 NIL go T 1 T OBSERVER T NIL SLIDER 124 10 296 43 population population 100 5000 1000 100 1 NIL BUTTON 141 60 196 93 NIL reset NIL 1 T OBSERVER T NIL PLOT 13 368 378 572 People NIL NIL 0.0 1000.0 0.0 500.0 true true PENS "people" 1.0 0 -16777216 true "zombies" 1.0 0 -2674135 true SLIDER 202 188 374 221 decompose-rate decompose-rate 0 1 0.5 0.01 1 NIL BUTTON 14 306 69 339 NIL clear-plot NIL 1 T OBSERVER T NIL SLIDER 12 154 184 187 panic-time panic-time 0 10 1 1 1 NIL SLIDER 202 222 374 255 frenzy-time frenzy-time 0 10 1 1 1 NIL SLIDER 202 256 374 289 after-kill-rest after-kill-rest 0 100 0 10 1 NIL CHOOSER 10 10 122 55 layout layout "corridors" "mazes" "mazes&plazas" 2 SLIDER 12 188 184 221 human-repro-rate human-repro-rate 0 0.02 0.0090 1.0E-4 1 NIL SWITCH 203 293 349 326 zombie-smash!? zombie-smash!? 0 1 -1000 SLIDER 13 252 185 285 wall-strength wall-strength 5 200 50 5 1 NIL TEXTBOX 204 102 307 120 zombie properties TEXTBOX 13 102 163 120 human properties SLIDER 303 10 395 43 clock-scale clock-scale 5 100 35 5 1 NIL SLIDER 222 52 394 85 plaza-size plaza-size 1 25 20 1 1 % SWITCH 203 327 320 360 blood-lust? blood-lust? 1 1 -1000 SWITCH 72 288 167 321 graphics? graphics? 1 1 -1000 SWITCH 80 330 183 363 watch? watch? 1 1 -1000 @#$#@#$#@ WHAT IS IT? ----------- This is a zombie room model. A population of people exist inside a labyrinth of rooms and corridors (a "city"). At the outset, a person dies, infected with zombie-ism! After an incubation period expires, the corpse rises again, as a zombie. Zombies exist to kill people and infect them with zombie-ism. HOW IT WORKS ------------ People have too modes of operation: Normal and Panic. A normal person moves at normal speed. People wander, occaisionally turning. A person panics when a zombie or another paniced person appears within the vision range of the person in the direction the person is headed. A paniced person reverses direction, moves twice as fast as a normal person, does not look out for zombies, and moves in a straight line. A paniced person remains paniced for a short time, or until it hits a wall or is caught by a zombie. Zombies also have too modes. Normal and Frenzy. A normal zombie stumbles around and moves just as fast as humans. A zombie frenzies when a person appears within the vision range of the zombie. A frenzied zombie moves twice as fast as a normal zombie. A frenzied zombie always moves in a straight line. A frenzied zombie stays frenzied for a short time, or until it catches a person, or hits a wall, or collapses. HOW TO USE IT ------------- Adjust the sliders. Click Setup. CLick Go. To use the same "map" with different settings, click Reset instead of Setup. THINGS TO NOTICE ---------------- This resembles a simulation of the spread of a disease through a population, sort of. Note that even though a person who becomes paniced might actually run *toward* danger, a population that does panic survies longer than a population that does not. This seems to indicate that in the absense of other self-preservation abilities, blind, unthinking panic is a species survival trait. EXTENDING THE MODEL ------------------- Add police or WHO agents who kill or cure zombies. Make people smarter. Make them able to: Avoid corpses. Move, or destroy corpses before they rise. Seek police or other assitance. Build barriers or create traps. Seek rooms with no outlets (hide in closets) Avoid rooms with no outlets (avoid being trapped) CREDITS AND REFERENCES ---------------------- Based on other zombie models seen on the internet. @#$#@#$#@ default true 0 Polygon -7500403 true true 150 5 40 250 150 205 260 250 clock true 0 Circle -16777216 true false 0 0 300 Circle -1 true false 30 30 240 Rectangle -2674135 true false 120 30 180 105 Circle -16777216 true false 90 90 120 corpse false 0 Circle -7500403 true true 35 50 80 Polygon -7500403 true true 199 187 85 241 26 194 109 202 49 142 94 127 124 187 94 97 139 142 124 67 169 67 199 97 154 157 214 112 214 157 244 127 244 217 199 247 Line -16777216 false 90 75 75 90 Line -16777216 false 75 75 90 90 Line -16777216 false 45 90 60 105 Line -16777216 false 45 105 60 90 Polygon -16777216 true false 64 121 77 104 94 96 107 103 dot false 0 Circle -7500403 true true 74 74 153 fan true 0 Circle -16777216 true false 0 0 300 Circle -1 true false 30 30 240 Rectangle -16777216 true false 75 30 120 150 Circle -16777216 true false 74 74 152 Rectangle -16777216 true false 150 75 270 120 Rectangle -16777216 true false 30 180 150 225 Rectangle -16777216 true false 180 165 225 270 person false 0 Circle -7500403 true true 110 5 80 Polygon -7500403 true true 105 90 120 195 90 285 105 300 135 300 150 225 165 300 195 300 210 285 180 195 195 90 Rectangle -7500403 true true 127 79 172 94 Polygon -7500403 true true 195 90 240 150 225 180 165 105 Polygon -7500403 true true 105 90 60 150 75 180 135 105 square false 0 Rectangle -7500403 true true 30 30 270 270 zombie false 0 Polygon -7500403 true true 128 87 159 163 72 207 106 302 106 216 152 196 190 222 173 296 235 222 179 188 168 91 Rectangle -7500403 true true 142 76 155 97 Polygon -7500403 true true 154 98 238 53 289 118 230 79 Polygon -7500403 true true 77 101 21 30 64 130 135 94 Polygon -7500403 true true 140 77 111 56 108 28 145 43 140 24 108 24 107 6 135 14 141 2 159 16 175 4 174 18 196 7 189 28 163 29 162 43 190 29 183 62 166 55 153 61 145 52 142 58 122 46 130 61 144 71 149 63 160 72 170 62 174 71 181 67 179 76 @#$#@#$#@ NetLogo 3.0.2 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@ @#$#@#$#@