Missile Command

The arcade game Missile Command was legendary back in its time. ICBMs rained down from the top of the screen. To intercept them, the player frantically launches ABMs from the bottom of the screen. This is done by clicking on the screen where he wants the ABM to explode and destroy everything in its blast radius. Each ICBM that strikes the ground wipes out everything in its blast radius. The game ends when there is no ground left.

Here's a screen shot of the NetLogo version of Missile Command that we will build:

Notice that the number of ICBM kills are tracked. ICBMs are yellow and ABMs are blue.

Breeds

Here's how mc.nlogo begins:

breed [icbms icbm]
breed [abms abm]
abms-own [target-xcor target-ycor]
globals [kills]  ; # of ICBMs killed by ABMs

to init
  ca
  ask patches with [pycor < min-pycor + 3] [set pcolor green]
  set kills 0
end

to update
   ; see below
end

We begin by creating two breeds of turtles: ICBMs and ABMs. ABM's have a target. This is where the mouse was clicked and this is where the ABM will explode when it is near enough.

The init procedure will be associated with the init button and the update procedure will be associated with the start button.

The update procedure will be called repeatedly. Each time it must update every turtle. If the turtle is an ABM, then the turtle advances 2 steps toward its target. If the turtle is an ICBM, it will descend 1 step straight down.

Listening to the Mouse/Launching ABMs

Every time the mouse is clicked, we need to launch an ABM. Here's how:

if mouse-down? [launch-abm mouse-xcor mouse-ycor]

Launching an ABM uses the create-breed command:

create-BREED N [init each new turtle]

In our case N = 1. We set the newly minted turtles target to the mouse coordinates, set his color to blue, set his starting point to the bottom center of the world, and use the facexy command to face him toward his target:

to launch-abm [tx ty]
   create-abms 1
   [
     set target-xcor tx
     set target-ycor ty
     set color blue
     set xcor 0
     set ycor min-pycor
     facexy tx ty
   ]
end

The problem is that the observer must execute this command frequently, or else the game will seem unresponsive.

Turning Sets into Lists using of

The of command can be used to get the value of a turtle or patch property:

[color] of turtle 0

[altitude] of patch 0 0

In the case of a set of turtles or patches the of command returns a list of values:

[color] of turtles ; = list of colors
[altitude] of patches ; = list of altitudes

Every turtle or patch can refer to itself using the word self. We can get a list of all turtles as follows:

let turtle-list [self] of turtles

Once we have a list we can iterate over it using for-each:

foreach turtle-list
[
   if ? != nobody [ask ? [update-turtle]]
   if mouse-down? [launch-abm mouse-xcor mouse-ycor]
]

Inside this loop ? is used to refer to the turtle and nobody means the turtle is already dead (because it was blown up).

Detonation

Here's how a turtle explodes, taking everyone nearby—patches and turtles-- with him:

to explode
  ask patches in-radius 3
      [ set pcolor red ]
  beep
  ask patches in-radius 3
      [ set pcolor black ]
  ask turtles in-radius 3 [die]
end

Ending it

The with operator returns the set of all patches or turtles with some property:

patches with [pcolor = green]
turtles with [color = red]

The count procedure tells the size of a set. The stop procedure ends the program. In our case, the game ends when all of the green patches have been blown up:

if count patches with [pcolor = green] = 0 [stop]