1 ; Copyright 2022 Frank Duncan (frank@consxy.com) under AGPL3. See distributed LICENSE.txt.
2 (in-package #:clnl-nvm)
4 (defcommand create-turtles (n &optional breed fn)
5 "CREATE-TURTLES N &optional BREED FN => RESULT
11 N: an integer, the numbers of turtles to create
13 FN: A function, applied to each turtle after creation
17 Creates N new turtles at the origin.
19 New turtles have random integer headings and the color is randomly selected
20 from the 14 primary colors. If FN is supplied, the new turtles immediately
21 run it. If a BREED is supplied, that is the breed the new turtles are set
24 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#create-turtles"
26 ((new-turtles (loop :repeat n :collect (create-turtle breed))))
27 (when fn (ask (list->agentset new-turtles :turtles) fn))))
36 The turtle or link dies
38 A dead agent ceases to exist. The effects of this include:
39 - The agent will not execute any further code.
40 - The agent will disappear from any agentsets it was in, reducing the size of those agentsets by one.
41 - Any variable that was storing the agent will now instead have nobody in it.
42 - If the dead agent was a turtle, every link connected to it also dies.
43 - If the observer was watching or following the agent, the observer's perspective resets.
45 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#die"
46 (when (not (turtle-p *self*)) (error "Gotta call die in turtle scope, dude (~A)" *self*))
47 (setf (turtle-who *self*) -1)
48 (setf *turtles* (remove *self* *turtles*))
50 ((patch (patch-at (turtle-xcor *self*) (turtle-ycor *self*))))
51 (setf (patch-turtles patch) (remove *self* (patch-turtles patch))))
52 (error (make-condition 'death)))
54 (defcommand hatch (n &optional fn)
55 "HATCH N &optional FN => RESULT
61 N: an integer, the numbers of turtles to hatch
62 FN: A function, applied to each turtle after creation
66 The turtle in *self* creates N new turtles. Each new turtle inherits of all its
67 variables, including its location, from self.
69 If FN is supplied, the new turtles immediately run it.
71 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#hatch"
72 (when (not (turtle-p *self*)) (error "Can only hatch from turtle scope"))
74 ((new-turtles (loop :repeat n :collect (create-turtle nil *self*))))
75 (when fn (ask (list->agentset new-turtles :turtles) fn))))
77 (defcommand forward (n)
84 N: a double, the amount the turtle moves forward
88 Moves the current turtle forward N steps, one step at a time.
90 This moves forward one at a time in order to make the view updates look
91 good in the case of a purposefully slow running instance. If the number
92 is negative, the turtle moves backward.
94 If the current agent is not a turtle, it raises an error.
96 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#forward"
97 (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
101 ((< (abs i) 3.2e-15) nil)
102 ((< (abs i) 1d0) (jump i))
103 (t (jump (if (> i 0d0) 1d0 -1d0)) (internal (- i (if (> i 0d0) 1d0 -1d0)))))))
107 (when (not (turtle-p *self*)) (error "Gotta call jump in turtle scope, dude (~A)" *self*))
108 (with-patch-update *self*
112 (+ (turtle-xcor *self*) (* n (using-cached-sin (turtle-heading *self*))))))
116 (+ (turtle-ycor *self*) (* n (using-cached-cos (turtle-heading *self*))))))))
118 (defun random-xcor ()
119 "RANDOM-XCOR => RANDOM-NUMBER
121 ARGUMENTS AND VALUES:
123 RANDOM-NUMBER: a float, the random result
127 Returns a random floating point number in the allowable range of turtle
128 coordinates along the x axis.
130 These range from min-pxcor - 0.5 (inclusive) to max-pxcor + 0.5 (exclusive)
132 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
134 ((min (- (min-pxcor) 0.5d0))
135 (max (+ (max-pxcor) 0.5d0)))
136 (+ min (clnl-random:next-double (- max min)))))
138 (defun random-ycor ()
139 "RANDOM-YCOR => RANDOM-NUMBER
141 ARGUMENTS AND VALUES:
143 RANDOM-NUMBER: a float, the random result
147 Returns a random floating point number in the allowable range of turtle
148 coordinates along the y axis.
150 These range from min-pycor - 0.5 (inclusive) to max-pycor + 0.5 (exclusive)
152 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
154 ((min (- (min-pycor) 0.5d0))
155 (max (+ (max-pycor) 0.5d0)))
156 (+ min (clnl-random:next-double (- max min)))))
158 (defcommand set-default-shape (breed shape)
159 "SET-DEFAULT-SHAPE BREED SHAPE => RESULT
163 ARGUMENTS AND VALUES:
170 Specifies a default initial shape for a BREED. When a turtle, or it changes breeds,
171 its shape is set to the given shape.
173 SET-DEFAULT-SHAPE doesn't affect existing agents, only agents you create afterwards.
175 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#set-default-shape"
176 (when (not (breed-p breed)) (error "Need a valid breed"))
177 (setf (breed-default-shape breed) shape))
179 (defcommand setxy (x y)
184 ARGUMENTS AND VALUES:
191 Sets the x-coordinate and y-coordinate for the turle. Equivalent to
192 set xcor x set ycor y, except it happens in one step inside of two.
194 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#setxy"
195 (when (not (turtle-p *self*)) (error "Gotta call setxy in turtle scope, dude (~A)" *self*))
196 (setf (turtle-xcor *self*) (wrap-x *topology* x))
197 (setf (turtle-ycor *self*) (wrap-y *topology* y)))
199 (defun turtles-here (&optional breed)
200 "TURTLES-HERE => TURTLES
202 ARGUMENTS AND VALUES:
208 Returns the agentset consisting of all the turtles sharing the patch
209 with the agent in by *self*
211 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles-here"
212 (when (not (turtle-p *self*)) (error "Gotta call turtles-here with a turtle"))
214 ((patch-turtles (patch-turtles (patch-at (turtle-xcor *self*) (turtle-ycor *self*)))))
216 (if breed (remove breed patch-turtles :key #'turtle-breed :test-not #'eql) patch-turtles)
217 (or breed :turtles))))
219 (defcommand turn-right (n)
220 "TURN-RIGHT N => RESULT
224 ARGUMENTS AND VALUES:
226 N: a double, the amount the turtle turns
230 The turtle turns right by number degrees. (If number is negative, it turns left.)
232 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"
233 (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
235 ((new-heading (+ (turtle-heading *self*) n)))
236 (setf (turtle-heading *self*)
238 ((< new-heading 0) (+ (mod new-heading -360) 360))
239 ((>= new-heading 360) (mod new-heading 360))
242 (defcommand turn-left (n)
243 "TURN-LEFT N => RESULT
247 ARGUMENTS AND VALUES:
249 N: a double, the amount the turtle turns
253 The turtle turns left by number degrees. (If number is negative, it turns right.)
255 See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"