Fish Spotters
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This is a HubNet activity of natural selection. This selection model shows how the interaction of mates and predators on a population can generate two opposing pressures from natural selection. One of these pressures is from sexual selection and the other is from predation.
When you run the model, you can either play the role of a predator or the role of a mate.
As a predator, you will try to find fish, trying to click on them to "eat" them as fast as you can. As you hunt it is likely that you will find more fish that are easier to see. In other words, the more the appearance of the fish stands out from the background, the more likely it will be seen by you, the predator. In this model the fish population over many generations, pushed by predation pressures, will adapt to accumulate trait variations that make them better camouflaged and harder to find. Such changes typically include a smaller body size, a color similar to the tank background, spotting (or lack of) that makes the fish appear to have a texture similar to the background, and movement that is similar to the movement of the debris in its environment.
As a mate, you will try to mate with fish by clicking on them. As you mate with more and more fish, you will notice that it becomes progressively easier to find fish. In this model the fish population over many generations, pushed by sexual selection pressures, will adapt to accumulate trait variations that make them easier to find. Such changes typically include a larger body size, a color that is "flashier" against the background, spotting (or lack of) that makes the fish appear to have a texture different than the background, and movement that is different than the movement of the debris in its environment. The "flashier" a male fish is, the more likely a female fish will choose him as a mate, passing his genes to the next generation. This is sexual selection at work, and it is the force that drives the fish population to greater conspicuousness.
When both predators and mates interact with a population the outcomes are more difficult to predict, since each type of interaction tends to counterbalance the effects of the other type.
Quoting from "Sex and the Single fish" [2]: There may be several evolutionary reasons why fishs (or fish) prefer flashier mates. On the most basic level, the male with the biggest, brightest tail spot announces most loudly, "Hey, I'm over here" to any female it can see. Flashy colors are simply easier to locate. However, there is also research to suggest that bright colors serve as an indicator of good genes in the way the strong physique of a human athlete is a direct indicator of that individual's health and vitality. Or, bright coloration may signal to a potential mate that he's got something else going for him. After all, he's been able to survive the very handicap -- conspicuousness to predators -- that his flashiness creates.
HOW IT WORKS
You can assume either the role of a predator or the role of a mate.
When the HubNet simulation is started after pressing GO, participants should try to click on fish as fast as they can with the mouse.
Each participant can monitor his or her relative success compared to other participants by watching the monitors in the client that show the TOP PREDATOR (the person with most catches), how many that person caught (TOP PREDATOR'S CATCHES) or TOP MATE (the person with most catches), how many that person caught (TOP MATE'S MATINGS).
When GO is pressed, if you are a predator you should try to click on the fish, as fast as you can, in order to eat them. Each time you click on a fish it will be removed from the fish population. At that point, another randomly selected fish in the population will hatch an offspring to replace the one that was caught (keeping the population of fish constant).
If you are a mate (a female fish), you should try to click on the male fish as fast as you can (they are all males). When you click on a fish that is old enough to mate, your mating will hatch an offspring that is similar in appearance to its dad. In this way the population increases with each mating event. But, when the population of fish exceeds the carrying capacity, a random fish will be removed.
Each new offspring fish may undergo small mutations in its genetics for its color, size, motion, and visibility of a spotting pattern (5 spots) based on the genetic information inherited from the fish clicked on (the male) only.
Predators prey on the most easily spotted individuals more often than those that are hard to spot eliminating them from the gene pool. Thus, predators cause fish populations to remain relatively drab, small, and still (with respect to colors and patterns of the environment they live in).
However, fish looking for a mate exert the opposite selection. Relatively small drab fish are hard to find and mate with, while large fish with garish colors and patterns that move in patterns that help them stand out are easier to find. As these fish reproduce, the frequency of their genes increases in the gene pool.
The adaptation of the population in terms of movement is sometimes harder to predict than color changes. In environments with lots of motion (debris floating in water currents, ripples on the surface of the water) staying still might actually cause a fish to stand out, just as moving much faster than the surroundings would also make a fish stand out.
The adaptation of spotting patterns for a population is also sometimes harder to predict than color changes. In environments with a grainy background, spotting may help the fish blend in. However, in an environment with large regular colored shapes (rocks), spots might make the fish stand out.
In general however, the population will evolve to blend in, and/or stand out (being more easily spotted), from their environment depending on which of the selective pressures are stronger. When there is an equal number of predators and mates, the selective pressures may not strongly push the adaptation of the population in a clear direction - the result may be a population that is balanced between having traits that help the fish stand out and traits that help the fish remain hidden.
When you run the simulation you can set up two different tank environments to compare the outcomes from the same selective pressures from mates and predators in these different surroundings.
HOW TO USE IT
To run the activity press the GO/STOP button. To start the activity over with the same group of students stop the GO/STOP button by pressing it again, press the SETUP button, and press GO/STOP again.
Make sure you select Mirror 2D view on clients in the HubNet Control Center after you press SETUP.
LISTENING? when switched "off," prevents clients from clicking on the WORLD & VIEW and selecting fishes. Turn this switch to "on" after GO/STOP is pressed to allow clients to interact with the fishes and turn it "off" if you want to ignore any of the mouse clicks registered in the client windows.
CLIENT-ROLES can be set to "all mates", in which case every client assumes the role of a a mate, or it can be set to "all predators", in which case every client assumes the role of a predator. This chooser can also be set to "mix of predators & mates", in which case for every client assigned the role of a predator, the next client is assigned the role of a mate. This last setting allows you to coordinate an experiment where all the mates interact with the fish in one tank and all the predators interact with the fish in another tank. While such coordination can be directed by the teacher, or designed by the entire class, this model is embedded within the BEAGLE curriculum, and serves as a test bed for designing an experiment by a team of students. Decisions about how to coordinate participant roles in such an experiment is part of the challenge of the related student activities.
TANK-CAPACITY determines the size of the population in each of the two tanks on SETUP. It also determines how many fish are in each tank at one time when GO is pressed and fish are being eaten or offspring are being produced. Sliding it back and forth while the model runs can simulate the effects of population effects and founder effects, since it will cause the population to be culled or undergo a population boom, depending which way you slide it.
TOP-WATER specifies the type of debris in the water. "Ripples" move from left to right, while "debris" represent leaves that drift around the tank. TOP-FLOW specifies how fast this debris moves. BOTTOM-WATER and BOTTOM-FLOW specify these same values for the bottom tank.
TOP-GROUND specifies the type of background to draw in the top tank. BOTTOM-GROUND specified it for the bottom tank. While this value will often be set before the model is run, when the value of either option is changed during a model run, the environment is automatically updated.
TOP-INITIAL-FISH specifies the colors of the fish in the initial population in each tank. "Multi-colored" sets each fish to a random set of rgb value genes, "All gray" sets each fish to have equal values of 150 150 150 for its rgb gene values. And "Black or white" sets each fish to have either the rgb gene values of 0 0 0 (black) or 255 255 255 (white).
AMOUNT-OF-DEBRIS controls the % of debris in the tanks. 100% will populate the tank with the same amount of debris (leaves or ripples) as there are patches in the tank.
COLOR-MUTATIONS? when set to "on" allows offspring to incur mutations in their color they inherit.
SWIM-MUTATIONS? when set to "on" allows offspring to incur mutations in the amount of motion they inherit. AVG. FISH MOTIONS keeps track of the average gene values for each population (the top tank and bottom tank)
SIZE-MUTATIONS? when set to "on" allows offspring to incur mutations in the adult body size they inherit. AVG. FISH SIZE keeps track of the average gene values for size for each population (the top tank and bottom tank)
SPOT-MUTATIONS? when set to "on" allows offspring to incur mutations in the visibility of a 5 spot pattern near its tail. When the gene is 0, the spot pattern is completely transparent. When the gene is 255, the spot pattern is completely opaque (black). AVG. FISH SPOTTING keeps track of the average gene values for spotting for each population (the top tank and bottom tank)
The PREDATIONS monitor keeps track of how many fish the predators have caught.
The MATING monitor keeps track of the number of mating events that have occurred.
FLASH FISH will temporarily alternately flash the fish black and white so that they are visible. This will last for about 3 seconds.
THINGS TO NOTICE
Fish get smaller and harder to find over time when only predators are present. Fish get larger and easier to find over time when only mates are present. Fish motion depends on the amount of environmental movement in the background. If the background has little environmental movement, then fish with a lot of movement stand out, but if the background has some amount of environmental movement, then fish with a less (or a lot more) movement stand out.
THINGS TO TRY
If you are having trouble finding the fish, it is useful to press FLASH to show where they are (and how they are camouflaged);
Try setting up experiments where the predators prey on only fish in one tank and the mates only breed with fish in the other tank.
EXTENDING THE MODEL
What if fish needed to move and eat food to survive? Would that create other counter balancing selective pressure? What if fish released pheromones for other creatures to detect? Could that replace the need for garish appearances? Would mates evolve pheromones that could be detected only by mates and not predators?
NETLOGO FEATURES
IN-RADIUS is the primitive used to check if the mouse is within the graphical "footprint" of a turtle.
This model uses RGB colors, that is, colors expressed as a three item list of red, green and blue. This gives a larger range of color possibilities than with NetLogo colors.
The background for each fish tank is created using the stamp command for turtle images of plants and rocks.
RELATED MODELS
Bub Hunters Camouflage Peppered Moth
CREDITS AND REFERENCES
This model is a part of the BEAGLE curriculum (http://ccl.northwestern.edu/simevolution/beagle.shtml)
[1] Inspired by Sex and the Single Guppy http://www.pbs.org/wgbh/evolution/sex/guppy/index.html
HOW TO CITE
If you mention this model in a publication, we ask that you include these citations for the model itself and for the NetLogo software:
- Novak, M. and Wilensky, U. (2012). NetLogo Fish Spotters model. http://ccl.northwestern.edu/netlogo/models/FishSpotters. Center for Connected Learning and Computer-Based Modeling, Northwestern Institute on Complex Systems, Northwestern University, Evanston, IL.
- Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern Institute on Complex Systems, Northwestern University, Evanston, IL.
COPYRIGHT AND LICENSE
Copyright 2012 Uri Wilensky.
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Commercial licenses are also available. To inquire about commercial licenses, please contact Uri Wilensky at uri@northwestern.edu.
Comments and Questions
breed [players player] ;; each client controls one player turtle, players are always hidden in the view breed [fish a-fish] ;; fish is the main agent that fish parts are attached to breed [fish-spots a-fish-spot] ;; fish spots are attached to the main fish body breed [debris a-debris] ;; debris includes any of the "moving" distractors in the tank (leaves floating about or ripples on the water surface) breed [edges edge] ;; square shaped agents used to cover the edges of the tank, so that ripples and leaves (debris) float behind these edges breed [rocks rock] ;; temporary agent used for creating a shape "stamped" image for the background breed [plants plant] ;; temporary agent used for creating a shape "stamped" image for the background rocks-own [which-tank] patches-own [debris-spot? type-of-patch tank] ;; gene-frequencies determine the color ;; of each fish and mutate as fish reproduce fish-own [ red-gene ;; gene for strength of expressing red pigment (0-100) blue-gene ;; gene for strength of expressing blue pigment (0-100) green-gene ;; gene for strength of expressing green pigment (0-100) spot-transparency-gene ;; gene for transparency value of the spots (0-255) size-gene ;; gene for the size of the fish motion-gene ;; gene for how much the fish are moving birthday ;; when this fish was born ] players-own [ user-name ;; the unique name users enter on their clients role ;; set as predator or mate caught ;; the number of fish this user as caught attempts ;; times the user has clicked in the view trying to catch a fish percent ;; percent of catches relative to the leader ] globals [ predator-leader ;; a string expressing the player who has caught the most fish (or a tie if appropriate) predator-leader-caught ;; the number of fish the leader has caught mate-leader ;; a string expressing the player who has caught the most fish (or a tie if appropriate) mate-leader-caught ;; the number of fish the leader has caught predator-total-found ;; running total of the total number of fish caught mate-total-found ;; running total of the total number of fish caught adult-age ;; the age at which recently hatched fish become full sized offspring-distance ;; how far away offspring appear from where the parent mated number-of-predators ;; keeps track of the number of predators (clients that are assigned this role) in the competition number-of-mates ;; keeps track of the number of mates (clients that are assigned this role) in the competition last-mouse-down-check? ;; keeps track of last mouse-down? state max-color-mutation-step ;; maximum amount the color can change from a mutation old-client-roles ;; keeps track of previous state of the client-roles chooser, so .... ;; that if it is changed while GO/STOP is running, roles will be reassigned to the clients ripple-debris-color ;; keeps track of color of water ripple debris tank-1-avg-spot-transparency ;; statistic for tank 1 tank-2-avg-spot-transparency ;; statistic for tank 2 tank-1-avg-motion ;; statistic for tank 1 tank-2-avg-motion ;; statistic for tank 2 tank-1-avg-size ;; statistic for tank 1 tank-2-avg-size ;; statistic for tank 2 top-ground-previous-value ;; keeps track of previous top-ground value from that chooser, in case it is changed while GO/STOP is running bottom-ground-previous-value ;; keeps track of previous bottom-ground value from that chooser, in case it is changed while GO/STOP is running top-water-previous-value ;; keeps track of previous top-water value from that chooser, in case it is changed while GO/STOP is running bottom-water-previous-value ;; keeps track of previous bottom-water value from that chooser, in case it is changed while GO/STOP is running ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Setup Procedures;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to startup ;; standard HubNet setup hubnet-set-client-interface "COMPUTER" [] hubnet-reset setup-clear end ;; this kills off all the turtles (including the players) ;; so we don't necessarily want to do this each time we setup to setup-clear clear-all set adult-age 20 set offspring-distance 3 setup set number-of-mates 0 set number-of-predators 0 end ;; setup the model for another round of fish catching ;; with the same group of users logged in to setup clear-patches clear-all-plots reset-ticks ask fish [ die ] ask fish-spots [die] ask debris [die] ask rocks [die] set old-client-roles "" set predator-leader "" set predator-leader-caught 0 set mate-leader "" set mate-leader-caught 0 set ripple-debris-color [100 100 200 100] set top-ground-previous-value "" set bottom-ground-previous-value "" set top-water-previous-value "" set bottom-water-previous-value "" set max-color-mutation-step 25 set tank-1-avg-spot-transparency 0 set tank-2-avg-spot-transparency 0 set tank-1-avg-motion 0 set tank-2-avg-motion 0 set tank-1-avg-size 0 set tank-2-avg-size 0 set adult-age 50 ;; ensures it takes a bit over a second to grow to full size ;; make sure to return players to initial conditions ask players [ initialize-player ] set number-of-mates count players with [role = "mate"] set number-of-predators count players with [role = "predator"] set-default-shape fish "fish" set last-mouse-down-check? false ask patches [set debris-spot? false set pcolor [0 0 0]] change-bottom setup-regions check-debris-count ask debris [ set-debris-appearance] update-tank-states adjust-fish-population-size-to-carrying-capacity calculate-statistics ask players [ send-player-info broadcast-competition-info ] tick end to make-one-initial-fish [in-tank] let target-patch one-of patches with [type-of-patch = "water" and tank = in-tank] move-to target-patch set birthday ticks ;; start at full size assign-initial-color-genes set spot-transparency-gene 0 set size-gene 1 set motion-gene 2 set heading random 360 color-this-fish add-fish-spots grow-this-fish end to assign-initial-color-genes ;; fish procedure if (top-initial-fish = "multi-colored" and tank = 1) or (bottom-initial-fish = "multi-colored" and tank = 2) [ set red-gene (random 255) set blue-gene (random 255) set green-gene (random 255) ] if (top-initial-fish = "all gray" and tank = 1) or (bottom-initial-fish = "all gray" and tank = 2) [ set red-gene 150 set blue-gene 150 set green-gene 150 ] if (top-initial-fish = "black or white" and tank = 1) or (bottom-initial-fish = "black or white" and tank = 2) [ ifelse random 2 = 0 [ set red-gene 0 set blue-gene 0 set green-gene 0 ][ set red-gene 255 set blue-gene 255 set green-gene 255 ] ] end to add-fish-spots ;; fish procedure hatch-fish-spots 1 [ ;;;make tail set size 1 set shape "spots" set color (list [red-gene] of myself [green-gene] of myself [blue-gene] of myself [spot-transparency-gene] of myself) ;; set color to rgb values of attached fish create-link-with myself [set hidden? true set tie-mode "fixed" tie ] ;; fish-spots will link to the fish body - thus following the fish body around as it moves ] end to color-this-fish ;; fish procedure set color rgb red-gene green-gene blue-gene end to change-bottom let gravel-size .6 let bottom-patches patches with [pycor < 0] let top-patches patches with [pycor > 0] clear-drawing create-rocks 1 [set shape top-ground set which-tank "top tank"] create-rocks 1 [set shape bottom-ground set which-tank "bottom tank"] if bottom-ground = "rock" [ask bottom-patches [set pcolor approximate-hsb 30 75 (60 + 80)]] if top-ground = "rock" [ask top-patches [set pcolor approximate-hsb 30 75 (60 + 80)]] if bottom-ground = "sand" [ask bottom-patches [set pcolor approximate-hsb 30 0 (0 + 160)]] if top-ground = "sand" [ask top-patches [set pcolor approximate-hsb 30 0 (0 + 160)]] if bottom-ground = "plants" [ask bottom-patches [set pcolor approximate-hsb 30 0 (0 + 60)]] if top-ground = "plants" [ask top-patches [set pcolor approximate-hsb 30 0 (0 + 60)]] if bottom-ground = "nothing" [ask bottom-patches [set pcolor approximate-hsb 0 0 255]] if top-ground = "nothing" [ask top-patches [set pcolor approximate-hsb 0 0 255]] ;; 3000 repetitions ensures that the bottom looks covered with rocks or plants or sand repeat 3000 [ ask rocks [ penup rt random 360 if which-tank = "top tank" [setxy random-float 100 random-float max-pycor ] if which-tank = "bottom tank" [setxy random-float 100 (-1 * random-float (abs min-pycor)) ] if my-tank = "sand" [set size gravel-size + random-float .2 set color approximate-hsb 30 (10 + random-float 50) (150 + random-float 90) ] if my-tank = "rock" [set size gravel-size + random-float 1.2 set color approximate-hsb 30 (30 + random-float 90) (60 + random-float 160) ] if my-tank = "plants" [set size gravel-size + random-float 1.2 set color approximate-hsb 90 (120 + random-float 100) (random-float 160) ] stamp ] ] ask rocks [die] end to setup-regions let min-pycor-edge min-pycor let max-pycor-edge max-pycor let water-patches nobody ask edges [die] ask patches [ set tank 0 set type-of-patch "water" if ((pxcor = min-pxcor + 1 or pxcor = max-pxcor - 1) or (pycor = min-pxcor + 1 or pycor = max-pxcor - 1) or (pycor = -1 or pycor = 1)) [set type-of-patch "edge"] if (pycor = 0 or pxcor = min-pxcor or pxcor = max-pxcor or pycor = min-pxcor or pycor = max-pxcor) [set type-of-patch "outside-tank"] if pycor >= 1 [set tank 1] if pycor <= -1 [set tank 2] if type-of-patch = "outside-tank" [ sprout-edges 1 [ set color black set shape "edges" ] ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Runtime Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go every 0.2 [ ;; these procedures do not need to be called as often check-change-player-roles adjust-fish-population-size-to-carrying-capacity check-debris-count check-changed-tank ] listen-clients move-debris wander ask fish [grow-this-fish] calculate-statistics tick end to wander ;; fish procedure let nearest-water-patch nobody let water-patches patches with [type-of-patch = "water"] ask fish [ rt random 70 - random 70 fd motion-gene / 20 set nearest-water-patch min-one-of water-patches [distance myself] if type-of-patch != "water" [ face nearest-water-patch fd motion-gene / 10 ] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reproduction and Aging Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to grow-this-fish ;; fish procedure ;; grow the newly hatched offspring until they reach their ADULT-AGE, at which point they should be the full fish-SIZE let age ticks - birthday ifelse age < adult-age [ set size size-gene * (age / adult-age)] [ set size size-gene ] ask link-neighbors [set size [size] of myself] end ;; keep a stable population of fish as predation and mating rates go up or down to adjust-fish-population-size-to-carrying-capacity let #-fish-top-tank count fish with [tank = 1] let #-fish-bottom-tank count fish with [tank = 2] ;; adjust top tank if #-fish-top-tank = 0 [ create-fish tank-capacity [make-one-initial-fish 1]] ;; if all the fish are removed by predators at once, make a new batch of random fish if #-fish-top-tank < tank-capacity [ ask one-of fish with [tank = 1][ make-one-offspring-fish ] ] ;; reproduce random other fish until you've reached the carrying capacity if #-fish-top-tank > tank-capacity [ ask one-of fish with [tank = 1][ remove-fish ] ];; remove other fish until you've reached the carrying capacity ;; adjust bottom tank if #-fish-bottom-tank = 0 [ create-fish tank-capacity [make-one-initial-fish 2]] ;; if all the fish are removed by predators at once, make a new batch of random fish if #-fish-bottom-tank < tank-capacity [ ask one-of fish with [tank = 2][ make-one-offspring-fish ] ] ;; reproduce random other fish until you've reached the carrying capacity if #-fish-bottom-tank > tank-capacity [ ask one-of fish with [tank = 2][ remove-fish ] ];; remove other fish until you've reached the carrying capacity end to remove-fish ;; fish procedure ask link-neighbors [die] ;; kill fish parts first die end to make-one-offspring-fish ;; fish procedure hatch 1 [ set size 0 if color-mutations? [mutate-body-color] if spot-mutations? [mutate-spot-transparency] if swim-mutations? [mutate-motion] if swim-mutations? [mutate-size] add-fish-spots color-this-fish grow-this-fish set birthday ticks lay-offspring ] end ;; used to move fish slightly away from their parent to lay-offspring ;; fish procedure let this-tank tank let birth-sites-in-radius patches with [distance myself <= offspring-distance] let birth-sites-in-tank birth-sites-in-radius with [tank = this-tank] if any? birth-sites-in-tank [ move-to one-of birth-sites-in-tank ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Visualization Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; a visualization technique to find fish if you are convinced they are not there anymore ;; it allows flashing without actually changing and recalculating the color attribute of the fish to flash-fish repeat 3 [ ask fish [ set color black ask link-neighbors [set color black ]] wait 0.1 display ask fish [ set color white ask link-neighbors [set color white ]] wait 0.1 display ] ask fish [color-this-fish] end to check-finish-flash-predator-strike ask players [ if hidden? = false and color = [0 0 0 200] [set hidden? true set color [255 255 255 200] ] if hidden? = false and color = [255 255 255 200] [set color [0 0 0 200]] ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Environmental Debris Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to move-debris let top-debris debris with [tank = 1] let bottom-debris debris with [tank = 2] ask debris [ if (top-water = "debris" and tank = 1) or (bottom-water = "debris" and tank = 2) [rt random-float 10 lt random-float 10] ;; drift if tank = 1 [fd top-flow ] if tank = 2 [fd bottom-flow ] ifelse type-of-patch = "outside-tank" [set hidden? true][set hidden? false] if pycor = 0 or pycor = min-pycor or pycor = max-pycor [die] ] end to check-changed-tank let ground-changed (top-ground != top-ground-previous-value or bottom-ground != bottom-ground-previous-value) let water-changed (top-water != top-water-previous-value or bottom-water != bottom-water-previous-value) if ground-changed or water-changed [ if ground-changed [user-message "this change will take a few seconds" change-bottom] if water-changed [ask debris [set-debris-appearance] ] update-tank-states ] end to update-tank-states set top-ground-previous-value top-ground set bottom-ground-previous-value bottom-ground set top-water-previous-value top-water set bottom-water-previous-value bottom-water end to check-debris-count let floating-debris nobody let tank-patches nobody let target-debris 0 foreach [1 2] [ set floating-debris debris with [tank = ?] set tank-patches patches with [tank = ?] set target-debris round ((amount-of-debris / 100) * count tank-patches) if target-debris > count floating-debris ;; need more debris [ ask n-of (target-debris - count floating-debris) tank-patches [setup-debris-at-this-patch] ] if target-debris < count floating-debris ;; need less debris [ ask n-of (count floating-debris - target-debris) floating-debris [ die] ] ] end to setup-debris-at-this-patch sprout-debris 1 [ set size .5 + random-float 2 set-debris-appearance ] end to set-debris-appearance if top-water = "clear" and tank = 1 [set heading 90 set shape "empty" ] if bottom-water = "clear" and tank = 2 [set heading 90 set shape "empty" ] if top-water = "ripples" and tank = 1 [set heading 0 bk 0.5 fd random-float 1 set heading 90 bk 0.5 fd random-float 1 set color ripple-debris-color set shape "ripples" ] if bottom-water = "ripples" and tank = 2 [set heading 0 bk 0.5 fd random-float 1 set heading 90 bk 0.5 fd random-float 1 set color ripple-debris-color set shape "ripples" ] if top-water = "debris" and tank = 1 [set heading random 360 set color (list 0 (100 + random 155) 0 (50 + random 205)) set shape "debris" ] if bottom-water = "debris" and tank = 2 [set heading random 360 set color (list 0 (100 + random 155) 0 (50 + random 205)) set shape "debris" ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HubNet Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to listen-clients while [hubnet-message-waiting?] [ hubnet-fetch-message ifelse hubnet-enter-message? [ add-player ] [ ifelse hubnet-exit-message? [ remove-player ] [ if ( listening? ) [ if hubnet-message-tag = "View" [ ask players with [ user-name = hubnet-message-source ] [check-caught-fish] ] ] ] ] ] end ;; when a client logs in make a new player and give it the default attributes to add-player create-players 1 [ set user-name hubnet-message-source initialize-player ] end to initialize-player ;; player procedure hide-turtle set number-of-mates count players with [role = "mate"] set number-of-predators count players with [role = "predator"] if client-roles = "all mates" [set role "mate"] if client-roles = "all predators" [set role "predator"] if client-roles = "mix of mates & predators" [ ifelse number-of-mates >= number-of-predators [set role "predator"] [set role "mate"] ] set attempts 0 set caught 0 send-player-info broadcast-competition-info end to check-change-player-roles set number-of-mates count players with [role = "mate"] set number-of-predators count players with [role = "predator"] if old-client-roles != client-roles [ ask players [ set number-of-mates count players with [role = "mate"] set number-of-predators count players with [role = "predator"] if client-roles = "all mates" [set role "mate"] if client-roles = "all predators" [set role "predator"] if client-roles = "mix of mates & predators" [ ifelse number-of-mates >= number-of-predators [set role "predator"] [set role "mate"] ] send-player-info broadcast-competition-info ] set old-client-roles client-roles ] end ;; when clients log out simply get rid of the player turtle to remove-player ask players with [ user-name = hubnet-message-source ] [ die ] end to check-caught-fish ;; extract the coords from the hubnet message let clicked-xcor (item 0 hubnet-message) let clicked-ycor (item 1 hubnet-message) let this-tank 0 if clicked-ycor > 0 [set this-tank 1] if clicked-ycor < 0 [set this-tank 2] ask players with [ user-name = hubnet-message-source ] [ let this-player-role role set xcor clicked-xcor ;; go to the location of the click set ycor clicked-ycor set attempts attempts + 1 ;; each mouse click is recorded as an attempt for that player ;; if the players clicks close enough to a fish's location, they catch it ;; the in-radius (fish-size / 2) calculation helps make sure the user catches the fish ;; if they click within one shape radius (approximately since the shape of the fish isn't ;; a perfect circle, even if the size of the fish is other than 1) let candidates fish with [(distance myself) < size / 2 and tank = this-tank] ifelse any? candidates [ ;; randomly select one of the fish you clicked on let caught-fish one-of candidates set caught caught + 1 ifelse this-player-role = "mate" [set mate-total-found mate-total-found + 1] [set predator-total-found predator-total-found + 1] ask caught-fish [ ;; if you are a mate, kill of a random fish, make two offspring from your mating, and the selected mate is killed off too if this-player-role = "mate" [ make-one-offspring-fish make-one-offspring-fish ask one-of other fish with [tank = this-tank] [remove-fish ] remove-fish] ;; if you are a predator, make an offspring from another random fish, then remove the one you selected if this-player-role = "predator" [ ask one-of other fish with [tank = this-tank] [make-one-offspring-fish] remove-fish ] ] ;; if a fish is caught update the leader as it may have changed update-leader-stats ;; all the players have monitors displaying information about the leader ;; so we need to make sure that gets updated when the leader changed ask players [ send-player-info broadcast-competition-info ] ] ;; even if we didn't catch a fish we need to update the attempts monitor [ send-player-info broadcast-competition-info] ] end ;; update the monitors on the client to send-player-info ;; player procedure hubnet-send user-name "Your name" user-name hubnet-send user-name "Your role" role hubnet-send user-name "You have found" caught hubnet-send user-name "# Attempts" attempts end to broadcast-competition-info hubnet-broadcast "# of predators" count players with [role = "predator"] hubnet-broadcast "Top predator" predator-leader hubnet-broadcast "Top predator's catches" predator-leader-caught hubnet-broadcast "# of mates" count players with [role = "mate"] hubnet-broadcast "Top mate" mate-leader hubnet-broadcast "Top mate's matings" mate-leader-caught end ;; do the bookkeeping to display the proper leader and score to update-leader-stats let all-predators players with [role = "predator"] let all-mates players with [role = "mate"] if any? all-predators [ let predator-leaders all-predators with-max [ caught ] let number-predator-leaders count predator-leaders ifelse number-predator-leaders > 1 ;; if there is more than one leader just report a tie otherwise report the name [ set predator-leader word number-predator-leaders "-way tie" ] [ ask one-of predator-leaders [ set predator-leader user-name ] ] set predator-leader-caught [caught] of one-of predator-leaders ] if any? all-mates [ let mate-leaders all-mates with-max [ caught ] let number-mate-leaders count mate-leaders ifelse number-mate-leaders > 1 ;; if there is more than one leader just report a tie otherwise report the name [ set mate-leader word number-mate-leaders "-way tie" ] [ ask one-of mate-leaders [ set mate-leader user-name ] ] set mate-leader-caught [caught] of one-of mate-leaders ] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Mutation Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; three possible random mutations can occur, one in each frequency of gene expression ;; the max-color-mutation-step determines the maximum amount the gene frequency can drift up ;; or down in this offspring to mutate-body-color ;; fish procedure let red-mutation random (max-color-mutation-step + 1) - random (max-color-mutation-step + 1) let green-mutation random (max-color-mutation-step + 1) - random (max-color-mutation-step + 1) let blue-mutation random (max-color-mutation-step + 1) - random (max-color-mutation-step + 1) set red-gene limit-gene (red-gene + red-mutation) set green-gene limit-gene (green-gene + green-mutation) set blue-gene limit-gene (blue-gene + blue-mutation) end to mutate-spot-transparency ;; fish procedure let max-spot-transparency 255 let min-spot-transparency 25 set spot-transparency-gene spot-transparency-gene + (random-float 20) - (random-float 20) if spot-transparency-gene > max-spot-transparency [set spot-transparency-gene max-spot-transparency] if spot-transparency-gene < min-spot-transparency [set spot-transparency-gene min-spot-transparency] end to mutate-motion ;; fish procedure let max-motion 10 let min-motion 0 set motion-gene motion-gene + (random-float .5) - (random-float .5) if motion-gene > max-motion [set motion-gene max-motion] if motion-gene < min-motion [set motion-gene min-motion] end to mutate-size ;; fish procedure let max-size 1.5 let min-size .5 set size-gene size-gene + (random-float .1) - (random-float .1) if size-gene > max-size [set size-gene max-size] if size-gene < min-size [set size-gene min-size] end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Reporters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; imposes a threshold limit on gene-frequency. ;; without this genes could drift into negative values ;; or very large values (any value above 100%) to-report limit-gene [gene] if gene < 0 [ report 0 ] if gene > 255 [ report 255 ] report gene end to-report my-tank let value-to-report "" if which-tank = "top tank" [ set value-to-report top-ground] if which-tank = "bottom tank" [ set value-to-report bottom-ground] report value-to-report end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Statistics Procedures ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to calculate-statistics set tank-1-avg-spot-transparency mean [ spot-transparency-gene ] of fish with [tank = 1] set tank-2-avg-spot-transparency mean [ spot-transparency-gene ] of fish with [tank = 2] set tank-1-avg-motion mean [ motion-gene ] of fish with [tank = 1] set tank-2-avg-motion mean [ motion-gene ] of fish with [tank = 2] set tank-1-avg-size mean [ size-gene ] of fish with [tank = 1] set tank-2-avg-size mean [ size-gene ] of fish with [tank = 2] end ; Copyright 2012 Uri Wilensky. ; See Info tab for full copyright and license.
There are 3 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
Fish Spotters.png | preview | Preview for 'Fish Spotters' | over 11 years ago, by Uri Wilensky | Download |
This model does not have any ancestors.
This model does not have any descendants.