;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Program: Fish Schooling Model ;; Authors: Jude Battista and Kendra Knudtzon ;; Date: December 15, 1999 ;; Purpose: To model fish schooling among a breed, fear of different breeds, and ;; a predator/prey paradigm with sharks that eat all fish in its path ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; breeds [redfish yellowfish greenfish sharks bubbles] patches-own [red-here green-here yellow-here shark-here red-near green-near yellow-near shark-near total-near] ;; variables used in the program turtles-own [rClosest rClosest-dist rProximity rNeighborhood rFear rFear-dist rShark rShark-dist gClosest gClosest-dist gProximity gNeighborhood gFear gFear-dist gShark gShark-dist yClosest yClosest-dist yProximity yNeighborhood yFear yFear-dist yShark yShark-dist oClosest oClosest-dist sClosest sClosest-dist] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; setup method ;; Create all fish and randomly place them on screen , specified by user (sliders) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup clearall create-redfish numberOfRed create-greenfish numberOfGreen create-yellowfish numberOfYellow create-sharks numberOfSharks ask-redfish [ setcolor red setheading (random 360) ifelse heading > 180 [setshape red-fish-left] [setshape red-fish] setxy (random screen-size) (random screen-size) setrNeighborhood Sociable_red ] ask-greenfish [setcolor green setheading (random 360) ifelse heading > 180 [setshape green-fish-left] [setshape green-fish] setxy (random screen-size) (random screen-size) setgNeighborhood Sociable_green ] ask-yellowfish [setcolor yellow setheading (random 360) ifelse heading > 180 [setshape yellow-puffer-left] [setshape yellow-puffer] setxy (random screen-size) (random screen-size) setyNeighborhood Sociable_yellow ] ask-sharks [setcolor grey setheading (random 360) ifelse heading > 180 [setshape shark-left] [setshape shark] setxy (random screen-size) (random screen-size) ] ;; color the patches (background) blue and make some bubbles in the water setpc blue create-bubbles 100 ask-bubbles [setshape bubble setxy (random screen-size) (random screen-size) seth 0] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; start the interactions in the pond ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to goFish update-water if breed = redfish [move-redfish] if breed = greenfish [move-greenfish] if breed = yellowfish [move-yellowfish] if breed = sharks [move-sharks] if breed = bubbles [move-bubbles] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; update water variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to update-water setred-here 0 setgreen-here 0 setyellow-here 0 setshark-here 0 if color = red [setred-here 1] if color = green [setgreen-here 1] if color = yellow [setyellow-here 1] if color = grey [setshark-here 1] nsum red-here red-near ;; 8-neighbor sum nsum green-here green-near nsum yellow-here yellow-near nsum shark-here shark-near settotal-near red-near + green-near + yellow-near + shark-near end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Move the fish, according to several rules: ;; Fear sharks, Fear Others, Desire to be near to fish of your kind (schooling) ;; (Priority of these factors is based on user slider input) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-redfish wait 0.01 ifelse (heading > 180) [setshape red-fish-left] [setshape red-fish] ;;find closest redfish and its distance setrClosest who-min-of-redfish [distance xcor-of myself ycor-of myself] setrClosest-dist distance xcor-of rClosest ycor-of rClosest ;; find the nearest shark setrShark who-min-of-sharks [distance xcor-of myself ycor-of myself] setrShark-dist distance xcor-of rShark ycor-of rShark ;;find closest green or yellow fish setrFear who-min-of-turtles-with [breed = greenfish or breed = yellowfish] [distance xcor-of myself ycor-of myself] setrFear-dist distance xcor-of rFear ycor-of rFear ;; highly sociable fish want to be closer to neighbors setrProximity ( 6 - Sociable_red ) if rShark-dist < 1 [die] ;; fish dies if it is too near a shark getRheading fd 0.05 * fishSpeedRed rt 1.0 * (-1 + random 3) ;; allow for alteration in the fish's course end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Set the desired heading based on interactions with other fish in the pond ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to getRheading ;; if shark is in fear radius, run away ifelse rShark-dist <= FearOtherRed [seth-fish 180 + towards xcor-of rShark ycor-of rShark 2 * fearOtherRed] ;; else if a fish is within our proximity, run away [ifelse rClosest-dist <= rProximity [seth-fish 180 + towards xcor-of rClosest ycor-of rClosest 5] ;; if we aren't avoiding collision, then we need to know which way to head [ifelse rFear <= FearOtherRed [ifelse rClosest <= rNeighborhood ;;determine how much to fear others and how much to try schooling ;; seth-fish (towards xcor ycor) (degrees) [seth-fish (towards fearOtherRed * cos (180 + towards xcor-of rFear ycor-of rFear) + Sociable_red * cos heading-of rClosest fearOtherRed * sin (180 + towards xcor-of rFear ycor-of rFear) + Sociable_red * sin heading-of rClosest ) (Sociable_red + fearOtherRed) / 2 ] [seth-fish (towards fearOtherRed * cos (180 + towards xcor-of rFear ycor-of rFear) + xcor-of rClosest fearOtherRed * sin (180 + towards xcor-of rFear ycor-of rFear) + ycor-of rClosest ) (Sociable_red + fearOtherRed) / 2 ] ] ;; if there isn't other fish to fear, school based on closeness of breed [ifelse rClosest <= rNeighborhood [seth-fish heading-of rClosest Sociable_red] [seth-fish towards xcor-of rClosest ycor-of rClosest Sociable_red] ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Sharks move to avoid collision, and to chase after other fish to eat ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-sharks wait 0.01 rt 1.0 * (-1 + random 3) ;;find the closest shark setsClosest who-min-of-sharks [distance xcor-of myself ycor-of myself] setsClosest-dist distance xcor-of sClosest ycor-of sClosest ;; find the closest fish to eat setoClosest who-min-of-turtles-with [breed = yellowfish or breed = redfish or breed = greenfish] [distance xcor-of myself ycor-of myself] setoClosest-dist distance xcor-of oClosest ycor-of oClosest ;; if another shark is close, avoid colliding with it ifelse sClosest-dist < 2 [seth-fish 180 + towards xcor-of sClosest ycor-of sClosest 10] ;; otherwise, go towards the closest fish [if oClosest-dist <= Hunger [seth towards xcor-of oClosest ycor-of oClosest]] ifelse heading > 180 [setshape shark-left] [setshape shark] fd ( (random Hunger) * Speed / 100) end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Moves the desired heading of the fish from its current heading by degrees, unless ;; the fish are already close, in which case the fish match heading ;; ;; This is copied from the StarLogo flocking example included with the Mac ;; download version of StarLogo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to seth-fish :other-heading :degrees ;;copied from flocking example ifelse ((:other-heading >= heading) and ((:other-heading - heading) <= :degrees)) or ((:other-heading <= heading) and ((heading - :other-heading) <= :degrees)) [seth :other-heading] [ifelse ((:other-heading - heading) mod 360) < 180 [rt :degrees] [lt :degrees]] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Bubbles move randomly up ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-bubbles wait 0.01 fd ( (random 10) / 200) end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; function so that we can have empty buttons for interface labels ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to doNothing end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; moving green and yellow fish is the same as moving red fish ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-yellowfish wait 0.01 ifelse (heading > 180) [setshape yellow-puffer-left] [setshape yellow-puffer] ;;find closest yellowfish and its distance setyClosest who-min-of-yellowfish [distance xcor-of myself ycor-of myself] setyClosest-dist distance xcor-of yClosest ycor-of yClosest ;; find the nearest shark setyShark who-min-of-sharks [distance xcor-of myself ycor-of myself] setyShark-dist distance xcor-of yShark ycor-of yShark ;;find closest green or red fish setyFear who-min-of-turtles-with [breed = greenfish or breed = redfish] [distance xcor-of myself ycor-of myself] setyFear-dist distance xcor-of yFear ycor-of yFear setrProximity ( 6 - Sociable_yellow ) if yShark-dist < 1 [die] getYheading fd 0.05 * fishSpeedYellow rt 1.0 * (-1 + random 3) ;; allows for alteration in the fish's course end to move-greenfish wait 0.01 ifelse (heading > 180) [setshape green-fish-left] [setshape green-fish] ;;find closest redfish and its distance setgClosest who-min-of-greenfish [distance xcor-of myself ycor-of myself] setgClosest-dist distance xcor-of gClosest ycor-of gClosest ;; find the nearest shark setgShark who-min-of-sharks [distance xcor-of myself ycor-of myself] setgShark-dist distance xcor-of gShark ycor-of gShark ;;find closest red or yellow fish setgFear who-min-of-turtles-with [breed = redfish or breed = yellowfish] [distance xcor-of myself ycor-of myself] setgFear-dist distance xcor-of gFear ycor-of gFear setrProximity ( 6 - Sociable_green ) if gShark-dist < 1 [die] getGheading fd 0.05 * fishSpeedGreen rt 1.0 * (-1 + random 3) ;; allows for alteration in the fish's course end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Setting headings for green and yellow fish is the same as for red ones ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to getYheading ifelse yShark-dist <= FearOtherYellow ;;shark is in fear radius, run away [seth-fish 180 + towards xcor-of yShark ycor-of yShark 2 * fearOtherYellow] [ifelse yClosest-dist <= yProximity ;; if a fish is within our proximity, run away [seth-fish 180 + towards xcor-of yClosest ycor-of yClosest 5] [ifelse yFear <= FearOtherYellow [ifelse yClosest <= yNeighborhood [seth-fish towards fearOtherYellow * cos (180 + towards xcor-of yFear ycor-of yFear) + Sociable_yellow * cos heading-of yClosest ;;x-cor fearOtherYellow * sin (180 + towards xcor-of yFear ycor-of yFear) + Sociable_yellow * sin heading-of yClosest ;;y-cor (Sociable_yellow + fearOtherYellow) / 2 ] [seth-fish towards fearOtherYellow * cos (180 + towards xcor-of yFear ycor-of yFear) + xcor-of yClosest ;;x-cor fearOtherYellow * sin (180 + towards xcor-of yFear ycor-of yFear) + ycor-of yClosest ;;y-cor (Sociable_yellow + fearOtherYellow) / 2 ] ] [ifelse yClosest <= yNeighborhood [seth-fish heading-of yClosest Sociable_yellow] [seth-fish towards xcor-of yClosest ycor-of yClosest Sociable_yellow] ] ] ] end to getGheading ifelse gShark-dist <= FearOtherGreen ;;shark is in fear radius, run away [seth-fish 180 + towards xcor-of gShark ycor-of gShark 2 * fearOtherGreen] [ifelse gClosest-dist <= gProximity ;; if a fish is within our proximity, run away [seth-fish 180 + towards xcor-of gClosest ycor-of gClosest 5] [ifelse gFear <= FearOtherGreen [ifelse gClosest <= gNeighborhood [seth-fish towards fearOtherGreen * cos (180 + towards xcor-of gFear ycor-of gFear) + Sociable_green * cos heading-of gClosest ;;x-cor fearOtherGreen * sin (180 + towards xcor-of gFear ycor-of gFear) + Sociable_green * sin heading-of gClosest ;;y-cor (Sociable_green + fearOtherGreen) / 2 ] [seth-fish towards fearOtherGreen * cos (180 + towards xcor-of gFear ycor-of gFear) + xcor-of gClosest ;;x-cor fearOtherGreen * sin (180 + towards xcor-of gFear ycor-of gFear) + ycor-of gClosest ;;y-cor (Sociable_green + fearOtherGreen) / 2 ] ] [ifelse gClosest <= gNeighborhood [seth-fish heading-of gClosest Sociable_green] [seth-fish towards xcor-of gClosest ycor-of gClosest Sociable_green] ] ] ] end @#$#@#$#@ BUTTON 152 11 212 41 Red Fish doNothing NIL 3 T BUTTON 286 11 346 41 Yellow Fish doNothing NIL 4 T BUTTON 407 10 467 40 Green Fish doNothing NIL 5 T BUTTON 537 11 597 41 Sharks doNothing NIL 6 T SLIDER 140 47 230 72 slider1 Sociable_red 1 5 5 1 SLIDER 144 139 234 164 slider15 numberOfRed 1 20 10 15 SLIDER 268 141 358 166 slider14 numberOfYellow 1 20 10 14 SLIDER 402 139 492 164 slider13 numberOfGreen 1 20 10 13 SLIDER 531 79 621 104 slider11 Speed 1 10 5 11 SLIDER 271 45 361 70 slider4 Sociable_yellow 1 5 2 4 SLIDER 396 44 486 69 slider3 Sociable_green 1 5 4 3 SLIDER 144 108 234 133 slider8 fearOtherRed 0 5 5 8 SLIDER 143 78 233 103 slider5 fishSpeedRed 1 10 10 5 SLIDER 272 106 362 131 slider9 fearOtherYellow 0 5 4 9 SLIDER 397 108 487 133 slider10 fearOtherGreen 0 5 2 10 SLIDER 527 44 617 69 slider2 Hunger 0 10 4 2 SLIDER 271 78 361 103 slider7 fishSpeedYellow 1 10 10 7 SLIDER 395 78 485 103 slider6 fishSpeedGreen 1 10 10 6 SLIDER 530 140 620 165 slider12 numberOfSharks 1 10 3 12 BUTTON 11 10 71 40 setup setup NIL 1 NIL BUTTON 9 106 69 136 step goFish NIL 7 T BUTTON 11 61 71 91 go Fish goFish T 2 T @#$#@#$#@ Neural Networks Final Project: ArtiFishial Life by Jude Battista and Kendra Knudtzon How the Model Works: This project models fish schooling. We have created three types of fish, red fish, yellow fish, and green fish. Users can change four aspects of a fish's behaviour: * Sociable factor * Speed * Fear factor * Number The Sociable factor affects how much the fish wish to school. This manifests itself in a couple of ways. First, it determines how closely it desires to be to fish of its kind. Second, it determines how large of a neighborhood is considered when it wants to move towards another fish. If a fish is already within the neighborhood, it will just match its direction, if it is outside the neighorhood, the fish will swim toward another, some number of degrees (which is also based on its sociable factor.) The Speed factor affects how fast the fish will swim. The Fear factor affects how scared the fish is of anything besides its breed, including the sharks. This is manifested by first checking to see if a shark is within a fish's fear radius, if it is, all other behaviours are ignored, and the fish will try to run away from the shark. Otherwise, if another fish is within the fear radius, this fear factor is weighted with sociable factors to determine which way the fish wishes to head. If no other fish are within the fear radius, the fear factor plays no role in a fish's behaviour. The Number sets how many fish are created at the beginning of the simulation. This project also models a simple predator example. Sharks are distinct from other fish. While fish fear these sharks with the same weight as they do other fish, a shark within the fear radius causes the fish to panic and run away. Sharks can be created to be super-stellar. The Hunger factor of the shark determines the radius in which it looks for fish to eat. It also helps to randomize the sharks speed. Very hungry sharks will sometimes move rapidly towards the prey fish. The Speed factor affects how fast the fish will swim along with the random hunger factor. When a shark catches another fish, it eats the fish, and the fish will die. We have not implemented the eating of a fish to decrease the shark's hunger, because the way we had to model the system allows only the fish to know when it has been eaten. Hence, the shark cannot know when its hunger has been satisfied. Even with these limitations, the shark model is realistic looking. Things to Note: Starlogo doens't allow for labels to exist, so in order to label the columns for each of our fish types, we had to create buttons - when you create a button, you have to associate its behaviour with an instruction, so we had to create a doNothing instruction in the code to make the labels we have in the interface. The Interface window is always completely customizable, which could cause some problems, as users could possibly change things that shouldn't be changed. This feature does however, allow any user to add features and enhance the program, which is nice in an educational setting. A Starlogo bug that we encountered: Once all the fish die, or if number of the fish is set to or becomes zero, the min-of functions that search for fish will return -1, indicating that no such fish are left. However, when you then set the distance to the fish that you found while searching, instead of giving an error, or a -1 value, some random value is assigned. We think that this is value may set itself to the center of the screen, since after running the simulation several times with sharks set up to eat everything, all the sharks migrate to the center and stay there. Also note, that some of the code is very repetitive - we had to repeat exactly the same methods for moving and setting headings of green and yellow fish. This is because the breeds were different, and there was no way to get or set variables in a generalized matter (at least, not any way that we could find) Couple of graphical problems: We still have some flipping of fish (between left and right shapes) Also, sometimes fish (and sharks) seem to hide behind the bubbles and despite our code to avoid other fish, sometimes the fish still collide and then hide behind each other. We can see no easy way to fix these bugs at this point. Future Enhancements: (Educational) * Make sharks smarter - decrease their hunger with time or have them gang up on fish * Find a way that schooling can offer protection for fish * Add food pellets for prey fish * Have water affect fish (temperature patches, maybe some fish want to be near top of pond, others near bottom) * Could add divers - fish could be friendly or not friendly to people * Could add obstacles that the fish have to swim around. * Could add following behaviours to the fish - they could follow bubbles, or be attracted to shiny objects. @#$#@#$#@ StarLogo 2.0 @#$#@#$#@ (install-shapenames '(("green-fish-left" . 113) ("green-puffer" . 10) ("red-puffer" . 11) ("healthy-person-shape" . 28) ("yellow-puffer" . 12) ("green-fish" . 5) ("bubble" . 8) ("red-fish-left" . 112) ("yellow-puffer-left" . 115) ("shark-left" . 114) ("red-fish" . 6) ("shark" . 7))) @#$#@#$#@ @#$#@#$#@