Bladder Patrol

Bladder Patrol preview image

1 collaborator

Breadcrab2 Jason Bertsche (Author)

Tags

coyote 

"This model has coyotes with lasers"

Tagged by Jason Bertsche about 11 years ago

game 

"Simulation game, but not interactive"

Tagged by Jason Bertsche about 11 years ago

hell 

"You must see it to believe it"

Tagged by Jason Bertsche about 11 years ago

reality tv 

"It's like what you would see on TV"

Tagged by Jason Bertsche about 11 years ago

survival 

"It's hard to survive in this model"

Tagged by Jason Bertsche about 11 years ago

urine 

"We all have it"

Tagged by Jason Bertsche about 11 years ago

Model group Really Super Awesome Jasons | Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.0.5 • Viewed 807 times • Downloaded 60 times • Run 0 times
Download the 'Bladder Patrol' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

This model simulates the lives of lunatics trapped in a hellish world. It is my first (and only) NetLogo model, written in 2012 shortly after I started work at the CCL on the NetLogo Development team, and loosely inspired by my day-to-day goings-on at work.

HOW IT WORKS

To begin, there are 5 players (differently-colored person sprites) standing at the center of the game canvas. As time elapses, the players' biological needs grow, based on values determined by the sliders. Generally, hunger and thirst rise over time, eventually reaching thresholds at which the needs must be addressed, lest the player die within a certain number of ticks (ghost sprite, body replaced by a flower sprite). A player wins the game when he/she is the last one left alive.

There are pretzels strewn about the canvas that can be used to reduce the accumulating hunger. If a player encounters a pretzel on the floor while hungry, he/she will eat it directly (Pacman icon). If a player encounters a pretzel on the floor while not hungry, he/she will hold onto it for possible later use (box icon). If a player grows hungry and has surplus pretzels, he/she will eat it (open box icon). If a player grows hungry and does not have any surplus pretzels, he/she will attempt to find a pretzel on the ground, or might approach a nearby player who has surplus pretzels and buy one (red dollar icon for buyer, green dollar icon for seller).

Eating pretzels, though, incurs thirst (which also accumulates over time). The water fountain (blue/gray water drop sprite) at the left side of the canvas is the only place where thirst can be quenched. The water fountain has a limited amount of water that replensishes over time. When there is enough water present in the fountain to help in quenching a thirsty, nearby player's thirst, he/she will attempt to drink the water (water bottle icon), lowering thirst. An unlimited number of players can drink from the fountain simulataneously.

Drinking water, though, incurs "tinkles"--a measure of the player's desire to urinate. The toilet on the right side of the canvas (toilet sprite) is the only place where tinkles can be safely diminished. However, only one player can use the toilet at a time. If a near-to-the-toilet player desires to urinate, and the toilet is unoccupied, the player may ascend the throne and reduce his/her tinkles over time (rocket icon).

If, however, the player keeps an elevated count of tinkles for a certain number of ticks, he/she will uncontrollably reduce his/her tinkle count by having a bladder explosion (yellow water drop sprite). Experiencing a bladder explosion forces a player to be fined (red dollar icon), since it is indecent to leave a mess of urine on the floor in a public place.

This public place, however, has a coyote problem, and coyotes have a tendency of marking their territory with their urine. After a player experiences a certain number of bladder explosions, a territorial, alpha male robot coyote with a laser cannon strapped to its back will appear from off-screen, dashing to the opposite side of the screen, and shooting the offending player to death with a laser on its way through.

Under ideal settings, the players will find "freetime", where all of his/her needs are sated and ticks can be spent on anything of the player's choosing.

If toilet-troll is true, one role-free player will be assigned the role of "toilet troll", causing him/her to, during freetime, hog the toilet as much as possible, possibly forcing other players to have unnecessary bladder explosions.

If pretzel-protector is true, one role-free player will be assigned the role of "pretzel protector", causing him/her to, during freetime, gather pretzels unnecessarily, possibly forcing other players to starve or need to buy pretzels from the protector.

If water-waster is true, one role-free player will be assigned the role of "water waster", causing him/her to, during freetime, drink from the water fountain unnecessarily, possibly forcing other players to die of thirst (due to a depleted water supply), and almost certainly causing the water waster to experience numerous bladder explosions quite quickly.

HOW TO USE IT

Click "Setup". Then, click "Go". I discourage you from turning up the speed slider much, because the most interesting part of the whole thing happens really quickly.

THINGS TO NOTICE

ZAP!

THINGS TO TRY

Play with all of the sliders. Less intimidatingly, try turning on the personalities (by using the switches in the top-right of the interface). The default settings for the model cause enabling "water waster" to have a profound impact on the game.

EXTENDING THE MODEL

People sit on the toilet out in the open, without any sort of privacy. Obviously, this is empiracally inaccurate and warrants improvement.

NETLOGO FEATURES

  • Animated icons (handle-anims)
  • Solid-colored bar graphs (see both the code of the plot pens within the plots as well as the general boilerplate at the bottom of the "Code" tab (below the "Plotting Code" comment))
  • Lasers (direct-lasers)
  • List[T].take(n: Int): List[T] => take
  • List[T].zipWithIndex: List[(Int, T)] => zip-with-index

RELATED MODELS

No one dares make a mode related to my own.

CREDITS AND REFERENCES

Jason Bertsche IS AWESOME

Comments and Questions

How do you do it? (Question)

impressed.

Posted about 11 years ago

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 11 years ago

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 11 years ago by Jason Bertsche.

Attached files

File Type Description Last updated
Bladder Patrol.png preview Preview for 'Bladder Patrol' about 11 years ago, by Jason Bertsche Download

This model does not have any ancestors.

This model does not have any descendants.