Fish Spotters

Fish Spotters preview image

1 collaborator

Uri_dolphin3 Uri Wilensky (Author)

Tags

ccl 

Tagged by Uri Wilensky about 12 years ago

Model group CCL | Visible to everyone | Changeable by group members (CCL)
Model was written in NetLogo 5.0.1 • Viewed 556 times • Downloaded 47 times • Run 0 times
Download the 'Fish Spotters' 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 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.

CC BY-NC-SA 3.0

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

Click to Run Model

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.

Uploaded by When Description Download
Uri Wilensky over 11 years ago Updated to NetLogo 5.0.4 Download this version
Uri Wilensky about 12 years ago Updated version tag Download this version
Uri Wilensky about 12 years ago Updated to version from NetLogo 5.0.3 distribution Download this version

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.