Connect the Dots

Connect-the-dots is a simple NetLogo application that allows users to place a series of dots on the screen, then ask the turtle to connect the dots:

We decide to store the dots (i.e., the selected patches) in a list called dots:

globals [dots]

At this point dots is just a name. No list exists. We set dots to be the empty list in the init-model procedure, which is called when the setup button is clicked:

to init-model
  ca
  set dots []
  crt 1 [set color green]
end

The place-dots procedure is repeatedly called by clicking the place-dots button. This procedure calls NetLogo's mouse-down? reporter, which reports true if it happens to be called when the mouse is down (this is likely since it will be called repeatedly). When we catch the mouse button down, we identify the patch under the mouse and add it to the start of the dots list using the fput reporter:

to place-dots
  if mouse-down?
  [
    let dot patch mouse-xcor mouse-ycor
    ask dot [set pcolor orange]
    set dots fput dot dots
  ]
end

Note: fput is a reporter, not a procedure. It reports a new list like dots, but with dot added to the front. It does not alter dots. Instead, this must be done by reassigning the reported list to dots:

set dots fput dot dots

The connect-dots button calls the connect-dots procedure:

to connect-dots
   connect dots
end

The connect procedure demonstrates classic list recursion:

to connect [dot-list]
  if not empty? dot-list
  [
    ask turtle 0 [move-to first dot-list pd]
    connect but-first dot-list
  ]
  ask turtle  0 [pu]
end

Let's trace a call to connect:

connect [p1 p2 p3]
ask turtle 0 [move-to p1 pd]
connect [p2 p3]
ask turtle 0 [move-to p2 pd]
connect [p3]
ask turtle 0 [move-to p3 pd]
connect []
ask turtle 0 [pu]

Notice how the but-first reporter reports progressively shorter lists until the procedure is called with the empty list, which escapes the recursion.

Notice that each time the first reporter returns the next element in the original list.

As an alternative to list recursion, we could have used list iteration:

to connect [dot-list]
  foreach dot-list [ask turtle 0 [move-to ? pd]]
end

Note: If we want the turtle to connect the dots in the order they were placed, then use lput (last-put) instead of fput:

set dots lput dot dots

Note: While iteration consumes the same amount of time as classic recursion, it uses less memory.