goal-seeking-boids

goal-seeking-boids preview image

1 collaborator

Army_coat_pix R. Wade Schuette (Author)

Tags

goal-seeking 

Tagged by R. Wade Schuette over 4 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 6.2.0 • Viewed 386 times • Downloaded 127 times • Run 0 times
Download the 'goal-seeking-boids' 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 models the ability of a swarm to reach a goal based on communication, memory, and observations limited by distance and noise.

The model also allows agents to learn over time what rules seem to work, and co-evolve cultural wisdom which is passed on to new agents.

It can be used to study evolution of cultural shared opinions ( tribes ) as well as robustness of the overall planet to sudden changes in the landscape properties. ( once learned does behavior perseverate ? )

TAGS

computational social-science, education, policy-making, polarization, peer-pressure, cancel-culture, sharing, humility, cultural-evolution, culture-robustness

WHAT IS THE PURPOSE OF THE MODEL AND INTENDED AUDIENCE?

People of all ages might enjoy seeing what kind of problems occur in such a "simple" situation. Everyone can relate.

More serious students of decision-theory could find insight into the understudied question of how to make an optimal decision in a noisy world.

Lessons can be setup at selected points in complexity for maximum Axelrod-impact on segmented audiences by being near to them and familiar

HOW IT WORKS CONCEPTUALLY

  • there are mountains of "wealth" where higher on the hill represents more wealth. the swarm of agents move across this landscape and seek to get all of them on the highest peak of wealth.

  • Agents are initally distributed randomly across the landscape. There are no links between agents. Agents cannot see what wealth other agents have.

  • Agents all have the same set of rules and rules don't change during the run.

  • Different rules can be selected for testing.

  • At each tick, one random agent makes a decision about which direction is best to move. They base this decision by trade-offs between

    • a global observation: where is everyone else ?

      • a local observation : which way appears to be "uphill" ?
      • memory: which way have I been moving recently?

      Then they either move one step forward and their wealth changes too the wealth of the new patch, or they can elect to stay where they are.

    • The run stops when all agents have reached the highest peak of wealth, or after a maximum time-limit

    • The same situation can be tested using different rules to see what impact the rules have on the results.

    • The same rules can be tested against different landscapes to see if they work as well.

WHY IS THIS NON-TRIVIAL?

If there were only one smooth hill of wealth, a very simple hill-climbing rule would succeed: Everyone just move whatever way is locally uphill. You can set that up and see it work.

But, there are real-world complications to finding the best place, and these cause the simple hill-climbing rule to fail.

There might be more than one large-scale hill, so agents will get stuck on the wrong large hill. You can try that out and see.

There might be small-scale variations on the landscape (it may be "noisy" and not smooth ) so agents might get trapped on a local bump. You can see that in action.

The landscape might have blind-alleys where the "go uphill" rule fails on a location that is not even the top of any hill. An example that generates a blind-alley can be tried out.

Finally, there might be actual obstacles to travel in the landscape, such as walls. How well do rules work if there are such obstacles? A few such worlds have been supplied as examples that can be imported into the model to explore. Advanced users could make others to import.

We've all been stuck in a blind-alley or behind an obstacle. Are there rules that can get you unstuck?

WHAT ARE THE INTERESTING QUESTIONS?

This illustrates the problems of trying locate the best point in a noisy fitness landsape. How can agents avoid being trapped on a local maximum?

What are the trade-offs between observation and memory?

Agents can communicate, so strategies that involve jointly locating a best point are useful, such as moving towards each other, but these have a downside of too much coherence, in that everyone may end up into small clusters that are near each other, but still far from the best hill.

Agents can also effectively smooth out the landscape by remembering which way they have been moving, and consider that as important as the local "uphill" measurement in deciding which way is "up".

Is there a "best" algorithm that works for all combinations of long-range and short-range noise?

IMPORTANT LIFE LESSONS THE MODEL HELPS CONVEY

  • Being "greedy" is not always the best rule. (A series of "best" short-run decisions does not always get you to the best possible long-term result.)

    possible application area: public policy, Congressional "progress".

  • The best rule may still fail in some situations. ( A bad outcome doesn't mean that a bad policy was used.)

    possible application: evaluating doctors or policy-makers

  • Sometimes it pays to be slow to change one's opinion.

  • What is "obvious" ( locally ) and what is real (globally) may differ.

    possible application: intellectual humility

  • Sometimes you have to just try and see what happens.

    pososible application: more tolerance for "mistakes" by self and others

HOW IS THE MODEL IMPLEMENTED IN NETLOGO?

  • the world wraps horizontally and vertically
  • N turtles are created in random locations. N is a slider choice
  • all turtles follow the same rules ( There is no wisdom-distribution )
  • turtles don't communicate with each other or see each other

    *??? agents cannot see what wealth other agents have.

    ( variant of model, let them discover it and broadcast it as a population, gradually )

  • each turtle has two local rules at each tick (1) if it is possible to move uphill locally, do so and reset own wealth to the local pcolor value ELSE (2) if turtle is at a local maximum and realizes it is not the current best GLOBAL max, turn blue, and take a leap of size (3 + random 4) in a random direction OTHERWISE ... turn green and stay there

    The success of a migration critically depends on ability to get off a local maximum in this version ( hill-climbing-03) the leap step is simply forward (3 + random 4) in a random direction ( varies with iteration ) and is the same for every turtle These "magic numbers" are buried at the bottom of the move-turtles section and were picked for convenience because they worked out for the given hill locations and shapes used for developing the code

HOW TO USE IT

If you want to reuse an older random seed to repeat a run, possibly with different slider values, set the reuse-seed? switch to ON. You can also type the seed you want to reuse directly in the "randomseed" text box at the same time. Otherwise, it will resuse whatever the last random seed was, which is the value show in that box.

[ coming, Feb 2021 ]

THINGS TO NOTICE

[ coming, Feb 2021 ]

THINGS TO TRY

[ coming, Feb 2021 ]

EXTENDING THE MODEL

[ coming, Feb 2021 ]

NETLOGO FEATURES

[ coming, Feb 202 1 ]

RELATED MODELS

The hill creation code is inspired from the "Hill Climbing example" model

CREDITS AND REFERENCES

Copyright (c) 2021 R. Wade Schuette, all rights reserved. wade.schuette@gmail.com

YouTube video is scheduled to be added in February, 2021

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;; MODEL NAME:   goal-seeking-boids-v2-1py
;; DATE:  written 14-Nov-2019
;; HISTORY:
;;       01-Feb-2011  uploaded first version to modeling commons
;;                    latest version updated 1-Feb-2021 at 6:28 AM CST (Chicago time zone )
;;       14-Oct-2021  Modified to allow rerunning random-seed values.
;;                    Tests for running netlogo-web. If local, allows importing landscape and saving snapshots
;;                    added "maxwealth" and "stepsize" to turtles-own variables
;;
;;  TRANSIENT Work in process
;;      *  migrate local-gorup-horizon to all instances of everyone, wej ust put it in everyone uphill
;;      *  correction for angles near 360 has only been applied to every plus uphill case
;; known bugs:
;;  *  prints stopped when all turtles succeeded twice in output
;;  *  on stop for everyone,  neither of the plots are accurate, and the last 45 or so never are caught
;;  *  motion can get locked up in a corner


 ;;============ UN-comment the next line if you are running locally! =================
 ; extensions [view2.5d]
 ;; ==================================================================================

globals [


  stop-now?        ;; stop flag for subroutines to back up to the go command
  patch-count      ;; for this size display
  on-peak-count    ;; number of turtles on the peak
  peak-height      ;; height of highest patch
  my-center        ;; weighted centroid of all the agents, or possibly of VISIBLE nearby agents
  timestamp        ;; updated date-and-time to show on interface, only updated when taking snapshot
  stop-at-tick     ;; stop run when ticks >= stop-at-tick
  filechoice       ;; imported landscape jpg file name, if any

  ;; global variables defined by the interface controls
  ;; note - these are NOT cleared by "clear-globals" or "clear-all"
  ;; ===============================================
  ;; randomseed   ;; ( added 13-Oct-2021 )
  ;; number-of-hits
  ;; turtle-count
  ;; rule-to-use
  ;; leave-a-trail?
  ;; run-title
  ;; turtle-color
  ;; turtle-shape
  ;; landscape-source
  ;; noise?
  ;; noise-size
  ;; noise-density
  ;; group-weight
  ;; timestamp
  ;; braking-pct   ( insert a wait X seconds into the end of the go loop for fine tuning)

;;; ============== automater's globals begin ====================
;  working-directory   ;; the operating system working directory
;  command-file        ;; where the commands will be read from
;  output-file         ;; optional, where output from the go step can be written
;  log-file            ;; a log of what commands were executed
;  run-title           ;; whatever you want to name this run
;  show-commands-as-run?        ;; controls whether you want to see commands as they are run
;  use-sample-input-file?       ;; if true, generates a file called test-01-input.txt to use
;                               ;; as input for this model.
;                               ;; This will destroy an existing file of that name!
;;; ================ automater's globals end =====================


]

turtles-own[
  maxwealth ;; maximum wealth turtle has ever seen - 10/13/21
  wealth    ;; just equal to the pcolor of the patch the turtle is on
  prior-wealth ;; wealth before this latest step
  on-peak?
  old-heading  ;; actually exponentially smoothed history of prior headings
  inertia      ;;  [0,1], turtle specific, weight of old-heading in updated heading, defaults to zero
  empathy      ;;  [0,1] actually misnamed to be shorter, susceptibility to group peer pressure
  step-size-multiplier    ;;  10/13/21
  good-step-count ;; counts number of steps with improving height
  my-heading-uphill ;; before step
  my-heading-group  ;; before step
]

patches-own [
  height
  basepcolor
]

to setup

      if ( netlogo-web? = false )
       [
      print "\n ================================== \n If you get an error that VIEW2.5:PATCH-VIEW is undefined, \n  uncomment out the EXTENSION definition in the first line of actual code \n ================================== \n";
       ]


   let mystr88 "Test"

    if  ( netlogo-web? = false )
  [
     run " view2.5d:patch-view  mystr88  [ [the-patch] -> [height] of the-patch ] "
     run " view2.5d:set-z-scale mystr88  zfactor "
  ]

  ;; we persist randomseed across runs by putting the prior value in the "local" variable "oldseed"
  ;; but if that has never been set, we need to set it as well.

  clear-all
  if (reuse-seed? = false ) [ set randomseed  ( random 999999 )  ]
  ;; note, if randomseed is not reset above, the value from the interface input box will persist
  random-seed randomseed

  set timestamp date-and-time
  set stop-now? false

 ;; no-display  ( won't work over the web ! )
  if landscape-source = "generated" [make-landscape  ]
  if landscape-source = "imported"  [import-landscape]
  make-turtles
;;  display( won't work over the web ! )
  set my-center (patch 0 0)   ;; weighted centroid of the agents, dynamically updated
  ;;======================================= automaters commands begin
  ;; setup-automater
  ;;======================================= automaters commands end
  prepare-outputs
  set stop-at-tick max-ticks ;; stop normally if time is reached

  ask patches [ set basepcolor pcolor ]
  ask patches [ ifelse  ( count turtles-here > 0 ) [ set pcolor green][set pcolor basepcolor]]
  reset-ticks
end 

to prepare-outputs  ;; called once during setup
  ;; select external log and output files here, if any

  ;; write experiment title and date to output area

  output-print run-title
  output-print timestamp  ;; set at start of run, not output date-and-time !
  output-print " "
  output-print (word "turtle-count: " turtle-count)
  output-print (word "rule-to-use: " rule-to-use)
  output-print (word "landscape: " landscape-source)

  if (landscape-source = "imported")
    [output-print (word "file: " filechoice)]

  ;; other experimental settings could be output here
  output-print "  "

  ;; write column headers to the output area

     (if-else
       rule-to-use = "single: wander"              [ output-print (word "turtle "   " ticks "   )  ]
       rule-to-use = "single: go-uphill"           [ output-print (word "turtle "   " ticks "    )  ]
       rule-to-use = "single: find-everyone"       [ output-print (word "turtle "   " ticks "   " group-weight: "   )  ]
       rule-to-use = "pair: uphill with inertia"   [ output-print (word "turtle "   " ticks "   " inertia "  )  ]
       rule-to-use = "pair: uphill with everyone"  [ output-print (word "turtle "   " ticks "   " group-weight "  )  ]
       rule-to-use = "triple: use all three"       [ output-print (word "turtle "   " ticks "   " group-weight "   " inertia "   )  ]
        ; else commands
    [ error (word " unexpected rule-to-use choice: " rule-to-use) ]
   )
end 

to import-landscape  ;; only if local. Won't compile in netlogo-web.
  ifelse ( netlogo-web? = false )
  [
    let msg1 "starting runstring"
    let msg2 " no file selected! "
    let msg3 "Importing image file "
    let msg4 " failed, so generating the image locally"
    let msg5 "generated"
    let msg6 "You asked to import this landscape file: "
    let runstring
       ( word
           " print msg1 "
           " set filechoice user-file "
           " if-else filechoice = false "
           "  [ "
           "     print msg2 "
           "     print (word  msg3 user-file msg4)  "
           "     set landscape-source msg5  "
           "     make-landscape "
           "  ]  "
           "  [  "
           "     print (word msg6 filechoice)     "
           "    import-pcolors filechoice  "
           "    ask  max-one-of patches [pcolor] [set peak-height pcolor]  "
           "    ask patches [ set height pcolor] "
           " ] "
       )
    run runstring
  ]
  [ print "Landscapes can only be imported if this model is downloaded and run locally! "]
end 

to trackwho
  inspect turtle monturtle
end 

to go

    ask patches [ ifelse  ( count turtles-here    > 0 ) [ set pcolor green][set pcolor basepcolor]]
    let mystr88 "Test"

    if  ( netlogo-web? = false )
  [
    run "view2.5d:set-z-scale mystr88 zfactor"
    run "view2.5d:update-all-patch-views"
  ]

  ;; WARNING -- this will not print final output if stopped by interface
  if stop-now? [ print "Stop was requested by a subroutine" stop ]

  if ticks > stop-at-tick [wrap-up-run stop]  ;; prevent runaway models from consuming computer time

  if all? turtles [on-peak?]
  [    wrap-up-run stop ]

  move-turtles
    if stop-now? [ print "Stop was requested by a subroutine." stop ]
    if stop-now? [ error "stop was requested but failed" ]
  update-status

  if braking-pct > 0 [ wait ( braking-pct / 100) ]  ;; slowdown despite top master speed switch

  tick
end 

to wrap-up-run ;; wrap up the entire run
  ;; this is a place-holder
  ;; print "any wrapping up will go here", such as writing output to a file

  if (ticks >= stop-at-tick) [
    print (word "stopped at time limit, ticks = " ticks)
    output-print (word "stopped at time limit, ticks = " ticks)
  ]

  if (stop-now?)   [
    print (word "stopped unexpectedly, ticks = " ticks)
    output-print (word "stopped unexpectedly, ticks = " ticks)
  ]

   if-else (all? turtles [on-peak?])  [
    print (word "stopped when all turtles succeeded, ticks = " ticks)
    output-print (word "stopped when all turtles succeeded, ticks = " ticks)
   ]
   [
    print ( word "count of turtles not yet on the peak: " count turtles with [on-peak? = false] )
    output-print ( word "count of turtles not yet on the peak: " count turtles with [on-peak? = false] )
   ]

   ;; for inertia plot, set the time to 100 and plot the straglers
      if   rule-to-use = "pair: uphill with inertia"   [

            set-current-plot "inertia-influence"
            ;;plotxy inertia ticks

             ask turtles with [on-peak? = false ]
            [
                 let cluster-show 98 + random-float 2
                 plotxy inertia cluster-show  ;
                 output-print   (word   " ? " "        " cluster-show )
            ]
    ]

  ;; for group plot, set the time to 100 and plot the straglers
     if   rule-to-use = "pair: uphill with everyone"   [

            set-current-plot "social-influence"

            ask turtles with [on-peak? = false ]
               [
                  let cluster-show2 98 + random-float 2
                  plotxy empathy cluster-show2 ;
                  output-print   (word   " ? " "        " cluster-show2  "       " 1.0 " (forced) "       )
               ]

       ]
end 

to update-status

 set on-peak-count count turtles with [on-peak?]

;; ======================================================= automater code begins
;;   file-open output-file
;;   file-print (word "turtles on peak: " on-peak-count)
;;======================================================== automater code ends
end 

to-report local-group-center ;; for each agent, vision limited by horizon ( or links ? )
   ;; side-effect:  this sets the global variable my-center
  let sumx 0
  let sumy 0
  let sumx-wealth 0
  let sumy-wealth 0

  let numnearby count turtles with [ (distance myself  )  < horizon]
  print ( word "nearby turtle count " numnearby)
  ask turtles with [ (distance myself  )  < horizon]   [
    set sumx sumx +(pxcor * wealth)
    set sumx-wealth sumx-wealth + wealth

    set sumy sumy +(pycor * wealth)
    set sumy-wealth sumy-wealth + wealth
  ]

  ;; at set-up avoid division by zero
  if-else ( sumx-wealth > 0 )
  [ set sumx sumx / sumx-wealth
    set sumy sumy / sumy-wealth]
  [ set sumx 0  set sumy 0 ]       ;; put centroid in the center on first pass

  report (patch sumx sumy)

  ;report (list sumx sumy)
end 

to-report centroid      ;; compute center of the swarm, weighted by wealth

  ;; side-effect:  this sets the global variable my-center
  let sumx 0
  let sumy 0
  let sumx-wealth 0
  let sumy-wealth 0

  ask turtles [
    set sumx sumx +(pxcor * wealth)
    set sumx-wealth sumx-wealth + wealth

    set sumy sumy +(pycor * wealth)
    set sumy-wealth sumy-wealth + wealth
  ]

  ;; at set-up avoid division by zero
  if-else ( sumx-wealth > 0 )
  [ set sumx sumx / sumx-wealth
    set sumy sumy / sumy-wealth]
  [ set sumx 0  set sumy 0 ]       ;; put centroid in the center on first pass

  set my-center (patch sumx sumy)

  report (list sumx sumy)
end 

; =========== turtle movement commands ===============

to wrap-up-step  ;;    Utility, called by every rule, in every step, in a turtle context
    set wealth height ;   transfer patch parameter to a turtle parameter

    ;; This output relies on the various move steps ONLY being called for
    ;; turtles that were not already at peak height.  Otherwise, this
    ;; will generate way too much output!!

    if  height = peak-height   ;; did we just reach the peak?
      [
        set on-peak? true
        set color green
        set label ""

       (if-else
          rule-to-use = "single: wander"              [ output-print (word   who "        " ticks                        )  ]
          rule-to-use = "single: go-uphill"           [ output-print (word   who "        " ticks                        )  ]
          rule-to-use = "single: find-everyone"       [ output-print (word   who "        " ticks  "       " group-weight    )  ]
          rule-to-use = "pair: uphill with inertia"
        [
            output-print (word   who "        " ticks  "       " inertia         )
            set-current-plot "inertia-influence"
            set-current-plot-pen "default"
            plotxy inertia ticks
        ]
          rule-to-use = "pair: uphill with everyone"
        [
          output-print (word   who "        " ticks  "       " group-weight    )
          set-current-plot "social-influence"
          set-current-plot-pen "default"
          plotxy empathy ticks
        ]
          rule-to-use = "triple: use all three"
         [
            output-print (word   who "        " ticks  "       " group-weight "       " inertia )
            set-current-plot "inertia-influence"
            set-current-plot-pen "default"
            plotxy inertia ticks

            set-current-plot "social-influence"
            set-current-plot-pen "default"
            plotxy empathy ticks
        ]
           ; else commands
          [ error (word " unexpected rule-to-use choice: " rule-to-use) ] )
      ]
end 

to go-wander

    ask turtles with [not on-peak?] [

      set heading heading + random 45
      set heading heading - random 45

      step-or-reverse ( 1 )

      ;;set wealth height
      wrap-up-step
   ]
end 

to step-or-reverse [ size-of-step ]

         set prior-wealth height
         if-else  can-move? size-of-step  [forward (size-of-step * step-size-multiplier)][ set heading heading + 180 forward ( size-of-step * step-size-multiplier) ]

         ifelse ( dynamic-speed? = true )
  [
         ;; following variable step-size control is experimental 14-Oct-2021
         set wealth height
         if ( wealth > maxwealth) [ set maxwealth wealth ]
         ifelse ( wealth > prior-wealth )
             [
                  if ( good-step-count < 0) [set good-step-count 0]
                  set good-step-count ( good-step-count + 1 )
             ]
             [
                    if ( good-step-count > 0) [set good-step-count 0]
                    set good-step-count ( good-step-count - 1 )
             ]
         set step-size-multiplier ( 1 +  ( good-step-count / 5 ) )
         if ( step-size-multiplier > 5 ) [ set step-size-multiplier 5]
         if ( step-size-multiplier < 0.2) [ set step-size-multiplier 0.2 ]
  ]
  [ set step-size-multiplier 1 ]
end 

to-report uphill-heading
    ;; heading is in degrees , 0 to 360
    ;; hard-codes a search radius

    let search-radius 2.5

   ;; ask turtles with [not on-peak?] [
        let old-patch patch-here
        let neighborhood patches with [ distance myself < search-radius ]
        let target max-one-of neighborhood [height ]
        face target             ;; WARNING -- side-effect
        report heading
   ;; ]
end 

to go-uphill
     ;; hard-codes a step size
     let step-size 1

     ask turtles with [not on-peak?] [
     set heading uphill-heading

     step-or-reverse ( 1 )

      wrap-up-step
      ]
end 

to go-find-everyone  ;;  centroid and my-center needs to be refactored

   ;; first, comput the  weighted centroid of all the turtles
   let new-centroid (list 0 0)
   set new-centroid centroid  ;; sets global my-center as side-effect
                              ;; computes new-centroid but only uses the side effect
                              ;; WARNING -- twisted way of simply setting my-center

   ask turtles with [not on-peak?] [

       ;; let old-patch patch-here ;; obsolete??
       face my-center
       step-or-reverse ( 1 )
       wrap-up-step
   ]
end 

to go-uphill-inertia   ;; draft

    ask turtles with [not on-peak?] [

         set label inertia

         let old-patch patch-here ;;  used????

         let heading-uphill uphill-heading

         set heading ( inertia * old-heading) + (1 - inertia) * heading-uphill
         step-or-reverse ( 1 )
         set old-heading heading ;;   this is a turtle-own variable
         wrap-up-step

    ]
end 

to go-use-all-rules    ;; runs but not validated, not even one full walk-through

    ;; first, compute the  weighted centroid of all the turtles
   let new-centroid (list 0 0)
   if ticks > 1 [ set new-centroid centroid ]  ;; can't run on first tick because weath is zero and get division error
   ;;  type "centroid is " show new-centroid

  ask turtles with [not on-peak?] [

    let old-patch patch-here

    ;; let's find what heading goes uphill

    let target max-one-of neighbors [height]
    face target
    let heading-uphill heading

    ;; ok soften that with inertia

           set heading-uphill ( inertia * old-heading) + (1 - inertia) * heading-uphill

         set old-heading heading ;;   this is a turtle-own variable


    face my-center
    let heading-group heading

    set heading (empathy)*(heading-group) + (1 - empathy)*(heading-uphill)
   ;; set heading (group-weight)*(heading-group) + (1 - group-weight)*(heading-uphill)


    step-or-reverse ( 1 )
    set old-heading heading ;;   this is a turtle-own variable

    wrap-up-step
  ]
end 

to go-uphill-everyone  ;;draft

   ;; first, comput the  weighted centroid of all the turtles
   let new-centroid (list 0 0)
   if ticks > 1 [ set new-centroid centroid ]  ;; can't run on first tick because weath is zero and get division error
   ;;  type "centroid is " show new-centroid

  ask turtles with [not on-peak?] [

    let old-patch patch-here

    ;; let's find what heading goes uphill

    let target max-one-of neighbors [height]
    face target
    let heading-uphill heading

    ifelse ( limit-horizon? = true ) [ face local-group-center ] [ face my-center]
    face my-center  ;; <&&&&&&&&&&&&&&&&&&&&&& if we limit horizon I think it can create polarization , split up groups.
    let heading-group heading

    set  my-heading-uphill heading-uphill
    set  my-heading-group heading-group


    if (( heading-uphill > 270) and ( heading-group < 90 )) [ set heading-uphill ( heading-uphill - 360 ) ]
    if (( heading-uphill < 90 ) and ( heading-group > 270 )) [ set heading-group ( heading-group - 360 ) ]


    set heading (empathy)*(heading-group) + (1 - empathy)*(heading-uphill)
   ;; set heading (group-weight)*(heading-group) + (1 - group-weight)*(heading-uphill)


    step-or-reverse ( 1 )
    wrap-up-step

   ]
end 

;================end of turtle movement commands =======

to snapshot   ;;  save a picture of the whole interface to disk,   bare bones draft only
  ;; ask for a file-name
  ;; This should set a directory and base file name then increment a number add .jpg and save silently
  set timestamp date-and-time

  ifelse ( netlogo-web? = true )
  [
      print " export snapshot only works locally "
  ]
  [
     run "export-interface user-new-file"
  ]

  ;; UNCOMMENT the next line to save a snapshot of the image to disk only works locally won't compile netlogo web
  ;; export-interface user-new-file
  ;; print OK
end 

to apologize
  print " that function is not yet working!"
  set stop-now? true
end 

to move-turtles

  if-else leave-a-trail? [ ask turtles [ pen-down ]]   [ ask turtles [ pen-up ]]

  (if-else
  rule-to-use = "single: wander"              [ go-wander          ]
  rule-to-use = "single: go-uphill"           [ go-uphill          ]
  rule-to-use = "single: find-everyone"       [ go-find-everyone   ]
  rule-to-use = "pair: uphill with inertia"   [ go-uphill-inertia  ]
  rule-to-use = "pair: uphill with everyone"  [ go-uphill-everyone ]
  rule-to-use = "triple: use all three"       [ go-use-all-rules   ]
   ; else commands
    [ error (word " unexpected rule-to-use choice: " rule-to-use) ]
   )

  ;;set stop-now? false
end 

to make-landscape
  set patch-count count  patches;
  ask patch -7 -4  [set pcolor 125]  ;; always make at least one hill
  if number-of-hills >= 2 [  ask patch  3 6  [set pcolor 95] ]
  if number-of-hills >= 3 [  ask patch  7 -5  [set pcolor 75] ]

  repeat 15 [ diffuse pcolor 1]  ;; smooth that out somewhat

    if noise?
  [ ask N-of (  noise-density * patch-count) patches [set pcolor pcolor + noise-size]  ]

   repeat 2 [ diffuse pcolor 1]  ;; smooth the noise

  ask  max-one-of patches [pcolor] [set peak-height pcolor]
  ask patches [ set height pcolor]
  ask patches [ set pcolor scale-color red height 0 peak-height ]
end 

to make-turtles

  ; set the turtle color from the user menu
  let use-color green  ;; default
  if turtle-color = "green" [ set use-color green ]
  if turtle-color = "white" [ set use-color white ]
  if turtle-color = "black" [ set use-color black ]
  if turtle-color = "red"   [ set use-color red ]


   create-turtles turtle-count [      ;;  turtle-count is set by a slider
     setxy random-xcor random-ycor
     set on-peak? FALSE
     set color use-color
     set size 2
     set shape turtle-shape
     set wealth 0
     set maxwealth 0
     set good-step-count 0
     set   step-size-multiplier 1.0

    if-else ( randomize-inertia? )  [
      set inertia precision (random-float 1) 2
    ]
    [ set inertia inertia-static ]

     if-else ( randomize-group-weight? )
      [set empathy precision (random-float 1) 2 ]                ;; set to random uniform on [0,1]
      [set empathy group-weight]                                 ;; set in slider
  ]
end 

to help
  ;; UNCOMMENT this section if you have a help file on your local PC

;if-else file-exists? "help-for-goals.txt"
;  [
;    file-open "help-for-goals.txt"
;    while [not file-at-end? ]
;    [print file-read-line]
;    file-close
;  ]
;  [
    print "The help file 'help-for-goals.txt' was not found!"
;  ]
end 

There are 10 versions of this model.

Uploaded by When Description Download
R. Wade Schuette almost 4 years ago try again hide view2.5 from web Download this version
R. Wade Schuette almost 4 years ago adapted so view2d is hidden to web Download this version
R. Wade Schuette almost 4 years ago fixed some headings, add horizon, track Download this version
R. Wade Schuette almost 4 years ago removed python, added set rand seed Download this version
R. Wade Schuette almost 4 years ago added python to persist random seed Download this version
R. Wade Schuette over 4 years ago commented out local-only code Download this version
R. Wade Schuette over 4 years ago removed export interface option on web Download this version
R. Wade Schuette over 4 years ago removed background image impoort for web Download this version
R. Wade Schuette over 4 years ago removed display comamnds Download this version
R. Wade Schuette over 4 years ago Initial upload Download this version

Attached files

File Type Description Last updated
goal-seeking-boids.png preview Preview for 'goal-seeking-boids' over 4 years ago, by R. Wade Schuette Download

This model does not have any ancestors.

This model does not have any descendants.