Bladder Patrol
Model was written in NetLogo 5.0.5
•
Viewed 470 times
•
Downloaded 33 times
•
Run 0 times
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
Comments and Questions
Click to Run Model
breed [pretzels pretzel] pretzels-own [ owner-id ] breed [water-stands water-stand] water-stands-own [ id thirsties-on-tap ] breed [toilets toilet] toilets-own [ id is-occupied? ] breed [puddles puddle] breed [corpses corpse] corpses-own [ is-dead? ] breed [people person] people-own [ id pretzel-count thirsties hungries tinkles money ticks-hungry ticks-thirsty ticks-wanting-bathroom occupied-toilet-id bex-count did-buy-pretzel-this-tick? is-drinking? is-dead? specialty-type ] breed [lasers laser] lasers-own [ target-hunted ] breed [coyotes coyote] coyotes-own [ target-id exit-dir ] breed [pick-up-anims pick-up-anim] pick-up-anims-own [ ticks-alive j-dist ] breed [from-bag-anims from-bag-anim] from-bag-anims-own [ ticks-alive j-dist ] breed [drink-anims drink-anim] drink-anims-own [ ticks-alive j-dist ] breed [eat-anims eat-anim] eat-anims-own [ ticks-alive j-dist ] breed [money-plus-anims money-plus-anim] money-plus-anims-own [ ticks-alive j-dist ] breed [money-minus-anims money-minus-anim] money-minus-anims-own [ ticks-alive j-dist ] breed [bex-anims bex-anim] bex-anims-own [ ticks-alive j-dist ] breed [tinkle-anims tinkle-anim] tinkle-anims-own [ ticks-alive j-dist ] breed [death-anims death-anim] death-anims-own [ ticks-alive j-dist ] globals [ is-won? color-list player-count specialty-types toilet-troll-str pretzel-prot-str water-waster-str coyote-jump-dist coyote-laser-range laser-velocity anim-lifespan anims-list anim-float-rate ghost-float-rate rocket-float-rate anim-placement-above dollar-size default-anim-size ] to setup clear-all initialize make-turtles reset-ticks end to initialize set is-won? false set color-list [violet green red orange pink gray blue yellow brown white] set player-count 5 set toilet-troll-str "toilet-troll" set pretzel-prot-str "pretzel-protector" set water-waster-str "water-waster" set specialty-types (list toilet-troll-str pretzel-prot-str water-waster-str) set coyote-jump-dist 3 set coyote-laser-range 12 set laser-velocity 7 set anim-lifespan 5 set anims-list (list eat-anims money-plus-anims money-minus-anims drink-anims from-bag-anims pick-up-anims bex-anims tinkle-anims death-anims) set anim-float-rate .5 set ghost-float-rate 1 set rocket-float-rate 2 set anim-placement-above 2 set default-anim-size 2 end to go handle-anims handle-spoilers handle-water-level if ((count people = 1) and not is-won?) [ print (word (id-to-color-name ([id] of (one-of people))) " has won!") set is-won? true stop ] amplify-desires assess-desires spawn-new-pretzels spawn-new-coyotes direct-coyotes direct-lasers act-on-desires tick end to handle-anims foreach anims-list [ ask ? [ set ticks-alive (ticks-alive + 1) ifelse ((ticks-alive >= anim-lifespan) or ((max-pycor - ycor) <= j-dist)) [die] [jump j-dist] ] ] end to handle-spoilers ifelse (spoilers) [ ask people with [ specialty-type = water-waster-str ] [ ifelse (water-waster) [ set shape "water-waster" ] [ set shape "person" ] ] ask people with [ specialty-type = toilet-troll-str ] [ ifelse (toilet-troll) [ set shape "toilet-troll" ] [ set shape "person" ] ] ask people with [ specialty-type = pretzel-prot-str ] [ ifelse (pretzel-protector) [ set shape "pretzel-protector" ] [ set shape "person" ] ] ] [ ask people with [ specialty-type != -1 ] [ set shape "person" ] ] end to handle-water-level ask water-stands [ replenish-water determine-water-stand-shape ] end to replenish-water let inc water-replenishment-rate let thirsties-until-full (water-level-max - thirsties-on-tap) if (water-replenishment-rate > thirsties-until-full) [ set inc thirsties-until-full ] set thirsties-on-tap (thirsties-on-tap + inc) end ; For use by water-stands only to determine-water-stand-shape let percentage ((thirsties-on-tap / water-level-max) * 100) ifelse (percentage < 25) [ set shape "water0" ] [ ifelse (percentage < 50) [ set shape "water25" ] [ ifelse (percentage < 75) [ set shape "water50" ] [ ifelse (percentage < 100) [ set shape "water75" ] [ set shape "water100" ] ] ] ] end to spawn-new-pretzels let x (random (max-new-pretzels-per-tick - min-new-pretzels-per-tick)) let new-pretzel-count (x + min-new-pretzels-per-tick) create-pretzels new-pretzel-count [initialize-pretzel] end to spawn-new-coyotes if (bladder-explosion-threshold > 0) [ ask people with [ (bex-count >= bladder-explosion-threshold) and (not any? coyotes with [[id] of myself = target-id]) ] [ hatch-coyotes 1 [ let x -1 let y -1 let exit-on "null" let vertical (random 3) ifelse (vertical = 0) [ ; Baseline set x ((random (max-pxcor + (abs min-pxcor))) - (abs min-pxcor)) set y min-pycor set exit-on "top" ] [ ifelse (vertical = 1) [ ; Topline set x ((random (max-pxcor + (abs min-pxcor))) - (abs min-pxcor)) set y max-pycor set exit-on "bottom" ] [ let horizon (random 2) ifelse (horizon = 1) [ set x max-pycor set y ((random (max-pycor + (abs min-pycor))) - (abs min-pycor)) set exit-on "left" ] [ set x min-pycor set y ((random (max-pycor + (abs min-pycor))) - (abs min-pycor)) set exit-on "right" ] ] ] set target-id ([id] of myself) set exit-dir exit-on set size 4 setxy x y face myself ] ] ] end to direct-coyotes ask coyotes [ let hunteds (people with [id = [target-id] of myself]) ifelse (any? hunteds) [ let hunted (one-of hunteds) move-towards hunted if ((distance hunted) <= coyote-laser-range) [ hatch-lasers 1 [ face hunted set size 2.5 set target-hunted hunted ] ] ] [ let should-die false ifelse (exit-dir = "right") [ set heading 90 set should-die (coyote-jump-dist >= (max-pxcor - xcor)) ] [ ifelse (exit-dir = "left") [ set heading 270 set should-die (coyote-jump-dist >= (abs (xcor - min-pxcor))) ] [ ifelse (exit-dir = "top") [ set heading 0 set should-die (coyote-jump-dist >= (max-pycor - ycor)) ] [ if (exit-dir = "bottom") [ set heading 180 set should-die (coyote-jump-dist >= (abs (ycor - min-pycor))) ] ] ] ] if (should-die) [die] jump coyote-jump-dist ] ] end to direct-lasers ask lasers [ if ([is-dead?] of target-hunted) [die] let base-looks 3 let looks base-looks while [(looks > 0) and (target-hunted != nobody)] [ jump (laser-velocity / base-looks) if ((distance target-hunted) < 2) [ ask target-hunted [ print (word (id-to-color-name id) " died of LASERED!") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true ] die ] set looks (looks - 1) ] ] end to place-bladder-explosion hatch-puddles 1 [ set color yellow set ycor (ycor - 1.5) ] end to-report id-to-color-name [thing-id] let color-num (item (thing-id - 1) color-list) if color-num = 9.9 [ report "white" ] report item (color-num mod 10) base-colors end to amplify-desires ask people [ set thirsties (thirsties + thirst-rate) set hungries (hungries + hunger-rate) ] end to assess-desires ask people [ if (hungries >= hunger-activation-threshold) [ set ticks-hungry (ticks-hungry + 1) ] if (thirsties >= thirst-activation-threshold) [ set ticks-thirsty (ticks-thirsty + 1) ] if (tinkles >= tinkle-activation-threshold) [ set ticks-wanting-bathroom (ticks-wanting-bathroom + 1) ] if (ticks-hungry >= ticks-hungry-before-death) [ print (word (id-to-color-name id) " died of hunger") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true stop ] if (ticks-thirsty >= ticks-thirsty-before-death) [ print (word (id-to-color-name id) " died of thirst") hatch-death-anims 1 [ initialize-ghost myself ] set breed corpses set is-dead? true stop ] if (ticks-wanting-bathroom >= ticks-before-bladder-explosion) [ place-bladder-explosion set bex-count (bex-count + 1) hatch-bex-anims 1 [ initialize-anim myself ] set money (money - fine-for-bladder-explosion) set ticks-wanting-bathroom 0 set tinkles 0 ] ] end to act-on-desires ask people [ ifelse (is-drinking?) [ do-thirst ] [ ifelse (did-buy-pretzel-this-tick?) [ set did-buy-pretzel-this-tick? false ] [ ifelse (occupied-toilet-id != -1) [do-use-toilet] [ ifelse (hungries >= hunger-activation-threshold) [ ifelse (thirsties >= thirst-activation-threshold) [ ; If closer to dying of hunger than of thirst ifelse ((ticks-hungry-before-death - ticks-hungry) < (ticks-thirsty-before-death - ticks-thirsty)) [do-hunger] [do-thirst] ] [do-hunger] ] [ ifelse (thirsties >= thirst-activation-threshold) [do-thirst] [ ifelse ((tinkles >= tinkle-activation-threshold) and not is-water-wasting?) [do-find-toilet] [ ifelse (is-toilet-trolling?) [do-find-toilet] [ ifelse (is-water-wasting?) [do-thirst] [ ifelse (is-pretzel-protecting?) [do-scavenge-pretzels] [ let pretzel-needer (find-nearest-pretzel-needer-with-money pretzel-selling-price) ifelse ((pretzel-count > 0) and (pretzel-needer != nobody) and (is-reachable? pretzel-needer)) [ do-sell-pretzel pretzel-needer ] [do-scavenge-pretzels] ] ] ] ] ] ] ] ] ] ] end ; For use by people only to-report find-nearest [targets] report min-one-of targets [distance myself] end to-report find-nearest-pretzel-needer-with-money [price] let needers (people with [(pretzel-count < 1) and (money >= price) and (myself != self)]) ifelse (any? needers) [ report find-nearest needers ] [ report nobody ] end ; For use by people only to-report is-reachable? [target] let dist ([distance target] of self) report (dist <= distance-travelable-per-tick) end ; For use by people only to move-towards [target] move-towards-dist target distance-travelable-per-tick end ; For use by people only to move-towards-dist [target dist] face target jump dist end ; For use by people only to move-randomly set heading (random 360) jump distance-travelable-per-tick end ; For use by people only to move-next-to [target] let dist-minus 2 let dist-to-target distance target let moving-dist (dist-to-target - dist-minus) if (0 > moving-dist) [move-towards-dist target moving-dist] end ; For use by people only to-report already-next-to? [target] report distance target <= 2 end ; For use by people only to consume-pretzel let bottomed-hungries 0 let unbottomed-hungries (hungries - pretzel-hunger-reduction) if (unbottomed-hungries > 0) [ set bottomed-hungries unbottomed-hungries ] set pretzel-count (pretzel-count - 1) set hungries bottomed-hungries set thirsties (thirsties + thirst-incurred-by-pretzels) if (hungries < hunger-activation-threshold) [ set ticks-hungry 0 ] end ; For use by people only to consume-water [nearest-water] let topped-on-tap water-thirst-reduction if (([thirsties-on-tap] of nearest-water) < water-thirst-reduction) [ set topped-on-tap ([thirsties-on-tap] of nearest-water)] show [thirsties-on-tap] of nearest-water let bottomed-thirsties 0 let unbottomed-thirsties (thirsties - topped-on-tap) if (unbottomed-thirsties > 0) [ set bottomed-thirsties unbottomed-thirsties ] let water-taken (topped-on-tap - bottomed-thirsties) if (water-taken < 0) [ set water-taken 0 ] ask nearest-water [ set thirsties-on-tap (thirsties-on-tap - water-taken) ] set thirsties bottomed-thirsties set tinkles (tinkles + tinkles-incurred-by-water) hatch-drink-anims 1 [ initialize-anim myself ] if (thirsties < thirst-activation-threshold) [ set ticks-thirsty 0 ] end ; For use by people only to do-use-toilet set tinkles (tinkles - tinkles-lost-per-tick-in-bathroom) hatch-tinkle-anims 1 [ initialize-rocket myself ] if (tinkles <= 0) [ set tinkles 0 ask toilets with [ id = [occupied-toilet-id] of myself ] [ set is-occupied? false ] set occupied-toilet-id -1 ] end ; For use by people only to do-hunger ifelse (pretzel-count > 0) [ consume-pretzel hatch-from-bag-anims 1 [ initialize-anim myself ] ] [ let nearest-pretzel (find-nearest pretzels) ifelse (nearest-pretzel != nobody) [ ifelse (is-reachable? nearest-pretzel) [ move-to nearest-pretzel ask nearest-pretzel [die] set pretzel-count (pretzel-count + 1) consume-pretzel hatch-eat-anims 1 [ initialize-anim myself ] ] [move-towards nearest-pretzel] ] [do-find-pretzel-seller] ] end ; For use by people only ; Does not accomodate for setups without water to do-thirst let nearest-water (find-nearest water-stands) ifelse (is-reachable? nearest-water) [ if (not already-next-to? nearest-water) [ move-next-to nearest-water ] consume-water nearest-water if (thirsties = 0) [ set is-drinking? false ] ] [ move-towards nearest-water ] end ; For use by people only to do-find-toilet let nearest-toilet (find-nearest toilets) ifelse (is-reachable? nearest-toilet) [ ifelse (not ([is-occupied?] of nearest-toilet)) [ do-occupy-toilet nearest-toilet ] [ move-next-to nearest-toilet ] ] [ move-towards nearest-toilet ] end ; For use by people only to do-sell-pretzel [buyer] print (word (id-to-color-name id) " sold a pretzel to " (id-to-color-name ([id] of buyer))) move-next-to buyer set pretzel-count (pretzel-count - 1) set money (money + pretzel-selling-price) hatch-money-plus-anims 1 [ initialize-anim myself ] ask buyer [ set pretzel-count (pretzel-count + 1) consume-pretzel hatch-money-minus-anims 1 [ initialize-anim myself ] set money (money - pretzel-selling-price) ] end ; For use by people only to do-scavenge-pretzels let nearest-pretzel (find-nearest pretzels) ifelse (nearest-pretzel != nobody) [ ifelse (is-reachable? nearest-pretzel) [ move-to nearest-pretzel set pretzel-count (pretzel-count + 1) ask nearest-pretzel [die] hatch-pick-up-anims 1 [ initialize-anim myself ] ] [ move-towards nearest-pretzel ] ] [move-randomly] end ; For use by people only to do-occupy-toilet [toilet] move-to toilet setxy (xcor - 0.4) (ycor + 0.6) set occupied-toilet-id ([id] of toilet) ask toilet [ set is-occupied? true ] do-use-toilet end ; For use by people only to do-find-pretzel-seller let nearest-seller (min-one-of people with [pretzel-count > 0] [distance self]) ifelse (nearest-seller != nobody) [ ifelse (is-reachable? nearest-seller) [ move-next-to nearest-seller ] [ move-towards nearest-seller ] ] [ move-randomly ] end ; For use by people only to-report is-toilet-trolling? report ((specialty-type = toilet-troll-str) and toilet-troll) end ; For use by people only to-report is-pretzel-protecting? report ((specialty-type = pretzel-prot-str) and pretzel-protector) end ; For use by people only to-report is-water-wasting? report ((specialty-type = water-waster-str) and water-waster) end ; Setup stuff to make-turtles let color-tuple-list (zip-with-index (take color-list player-count)) let toilet-count 1 let water-stand-count 1 let invalid-id -1 set-default-shape people "person" set-default-shape pretzels "pretzel" set-default-shape toilets "toilet" set-default-shape water-stands "drop" set-default-shape puddles "drop" set-default-shape corpses "flower" set-default-shape coyotes "coyote" set-default-shape lasers "lazor" set-default-shape eat-anims "pacman" set-default-shape money-plus-anims "green-dollar" set-default-shape money-minus-anims "red-dollar" set-default-shape drink-anims "bottle" set-default-shape from-bag-anims "opened-gift" set-default-shape pick-up-anims "gift" set-default-shape bex-anims "red-dollar" set-default-shape tinkle-anims "red-rocket" set-default-shape death-anims "ghost" create-pretzels (3 * player-count) [ initialize-pretzel ] create-toilets 1 [ set size 5 set heading 90 set id -1 set is-occupied? false jump 14 ] while [toilet-count > 0] [ ask one-of toilets with [ id = -1 ] [ set id toilet-count ] set toilet-count (toilet-count - 1) ] create-water-stands 1 [ set color blue set size 4 set heading 270 set thirsties-on-tap starting-water-level set id -1 jump 14 determine-water-stand-shape ] while [water-stand-count > 0] [ ask one-of water-stands with [ id = -1 ] [ set id water-stand-count ] set water-stand-count (water-stand-count - 1) ] create-ordered-people player-count [ jump 1.75 set size 2.5 set id invalid-id set pretzel-count starting-pretzels set thirsties ((random thirst-activation-threshold) + base-thirst) set hungries ((random hunger-activation-threshold) + base-hunger) set tinkles 0 set money starting-money set ticks-hungry 0 set ticks-thirsty 0 set ticks-wanting-bathroom 0 set occupied-toilet-id -1 set bex-count 0 set did-buy-pretzel-this-tick? false set is-drinking? false set is-dead? false set specialty-type -1 ] handle-specialty-types while [not (empty? color-tuple-list)] [ let head (first color-tuple-list) let tail (but-first color-tuple-list) ask one-of people with [ id = invalid-id ] [ set id ((first head) + 1) set color (first (but-first head)) ] set color-tuple-list tail ] end ; For use by pretzels only to initialize-pretzel set size 1.5 let angle (random 360) let dist (((random 1100) / 100) + 6) set heading angle set owner-id -1 jump dist end to handle-specialty-types let max-iters (length specialty-types) if (player-count < max-iters) [ set max-iters player-count ] let types (shuffle specialty-types) handle-specialty-types-helper types 0 max-iters end to handle-specialty-types-helper [types iters max-iters] if (iters < max-iters) [ ask one-of people with [specialty-type = -1] [ set specialty-type (first types)] handle-specialty-types-helper (but-first types) (iters + 1) max-iters ] end ; For use by anims only to initialize-anim [creator] initialize-anim-base creator anim-float-rate end to initialize-rocket [creator] initialize-anim-base creator rocket-float-rate end to initialize-ghost [creator] initialize-anim-base creator ghost-float-rate end to initialize-anim-base [creator jump-dist] set j-dist jump-dist set ticks-alive 0 set heading 0 set size default-anim-size move-to creator let new-ycor (ycor + anim-placement-above) if (new-ycor < max-pycor) [ set ycor new-ycor ] end to-report zip-with-index [xs] let indexes (n-values (length xs) [?]) report zip indexes xs end to-report zip [xs ys] report (map [list ?1 ?2] xs ys) end to-report take [xs num] report take-helper xs num [] end to-report take-helper [xs num acc] if-else num <= 0 or (empty? xs) [ report reverse acc ] [ report take-helper (but-first xs) (num - 1) (fput (first xs) acc) ] end ; +-------------------------+ ; | Plotting code | ; +-------------------------+ to plot-people-base [x plot-type is-border?] let my-turtle (one-of people with [id = (x + 1)]) let tx (get-true-x x) ifelse (my-turtle = nobody) [ plotxy tx 0 ] [ ifelse (is-border?) [ plot-switchboard tx plot-type my-turtle ] [ let i tx repeat (get-true-repeats x) [ plot-switchboard i plot-type my-turtle set i (i + .01) ] ] ] end to plot-switchboard [x plot-type my-turtle] let y (run-switchboard plot-type my-turtle) plotxy x y end to-report run-switchboard [plot-type my-turtle] report [runresult plot-type] of my-turtle end to plot-threshold [threshold] plotxy 0 threshold end to-report get-true-x [x] ifelse (x = 0) [report 0.02] [report x] end to-report get-true-repeats [x] ifelse x = 0 or x = player-count - 1 [report 97] [report 99] end
There is only one version of this model, created about 9 years ago by Jason Bertsche.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Bladder Patrol.png | preview | Preview for 'Bladder Patrol' | about 9 years ago, by Jason Bertsche | Download |
This model does not have any ancestors.
This model does not have any descendants.
Corey Brady
How do you do it? (Question)
impressed.
Posted about 9 years ago
Jason Bertsche
Re: How do you do it?
This is a skill that can no more be taught than "having three arms" can be taught.
Posted about 9 years ago