`(handler-case (progn ,@forms) (stop (s) (declare (ignore s)) :stop)))
(defstruct turtle who color heading xcor ycor (label "") (label-color 9.9d0) (size 1d0) shape own-vars)
-(defstruct patch color xcor ycor own-vars)
+(defstruct patch color xcor ycor own-vars turtles)
(defun agentset-list (agentset)
(cond
:shape (breed-default-shape :turtles)
:xcor (if base-turtle (turtle-xcor base-turtle) 0d0)
:ycor (if base-turtle (turtle-ycor base-turtle) 0d0))))
+ (let
+ ((patch (patch-at (turtle-xcor new-turtle) (turtle-ycor new-turtle))))
+ (setf (patch-turtles patch) (nconc (patch-turtles patch) (list new-turtle))))
(setf *turtles* (nconc *turtles* (list new-turtle)))
(incf *current-id*)
new-turtle))
See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles"
:turtles)
+(defun turtles-here ()
+ "TURTLES-HERE => TURTLES
+
+ARGUMENTS AND VALUES:
+
+ TURTLES: an agentset
+
+DESCRIPTION:
+
+ Returns the agentset consisting of all the turtles sharing the patch
+ with the agent in by *self*
+
+ See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#turtles-here"
+ (when (not (turtle-p *self*)) (error "Gotta call turtles-here with a turtle"))
+ (list->agentset (patch-turtles (patch-at (turtle-xcor *self*) (turtle-ycor *self*))) :turtles))
+
(defun ask (agent-or-agentset fn)
"ASK AGENT-OR-AGENTSET FN => RESULT
(defun jump (n)
(when (not (turtle-p *self*)) (error "Gotta call jump in turtle scope, dude (~A)" *self*))
- (setf
- (turtle-xcor *self*)
- (wrap-x *topology*
- (+ (turtle-xcor *self*) (* n (using-cached-sin (turtle-heading *self*))))))
- (setf
- (turtle-ycor *self*)
- (wrap-y *topology*
- (+ (turtle-ycor *self*) (* n (using-cached-cos (turtle-heading *self*)))))))
+ (with-patch-update *self*
+ (setf
+ (turtle-xcor *self*)
+ (wrap-x *topology*
+ (+ (turtle-xcor *self*) (* n (using-cached-sin (turtle-heading *self*))))))
+ (setf
+ (turtle-ycor *self*)
+ (wrap-y *topology*
+ (+ (turtle-ycor *self*) (* n (using-cached-cos (turtle-heading *self*))))))))
(defun setxy (x y)
"SETXY X Y => RESULT
(defun using-cached-cos (n)
(if (= (floor n) n) (nth (floor n) *cached-coses*) (strictmath:cos (strictmath:to-radians n))))
+
+(defun patch-at (xcor ycor)
+ (flet
+ ((rnd (d) (truncate (if (< d 0) (- d 0.5d0) (+ d 0.5d0)))))
+ (or
+ (find-if
+ (lambda (patch)
+ (and (equalp (patch-xcor patch) (rnd xcor)) (equalp (patch-ycor patch) (rnd ycor))))
+ *patches*)
+ (error "This shouldn't be possible: ~S ~S ~S" (rnd xcor) (rnd ycor) *patches*))))
+
+(defmacro with-patch-update (turtle &rest forms)
+ (let
+ ((patch (gensym)) (new-patch (gensym)))
+ `(let
+ ((,patch (patch-at (turtle-xcor ,turtle) (turtle-ycor ,turtle)))
+ (retn (progn ,@forms)))
+ (let
+ ((,new-patch (patch-at (turtle-xcor ,turtle) (turtle-ycor ,turtle))))
+ (when (not (eql ,patch ,new-patch))
+ (setf (patch-turtles ,patch) (remove ,turtle (patch-turtles ,patch)))
+ (setf (patch-turtles ,new-patch) (nconc (patch-turtles ,new-patch) (list ,turtle))))))))
#:show
#:stop
#:turtles
+ #:turtles-here
#:tick
#:ticks
#:turn-right #:turn-left
(defprim :tick () 0)
(defprim :ticks () 10)
(defprim :turtles () 10)
+(defprim :turtles-here () 10)
(defprim :who () 10)
; colors
(defsimpleprim :tick :command clnl-nvm:tick)
(defsimpleprim :ticks :reporter clnl-nvm:ticks)
(defsimpleprim :turtles :reporter clnl-nvm:turtles)
+(defsimpleprim :turtles-here :reporter clnl-nvm:turtles-here)
(defagentvalueprim :who)
(defsimpleprim :with :reporter clnl-nvm:with)
(defsimplecommandtest "stop 2" "crt 10 ask turtles [ fd 1 stop fd 1 ]"
"A6C980CC9843CDD211ABD9C13899010D555F3DC5")
+
+(defsimplecommandtest "turtles-here 1"
+ "crt 1000 ask turtles [ fd random-float 10 ] ask turtles [ set label [ who ] of one-of turtles-here ]"
+ "F34192513765D221A15D939A2BC8FFE18B6ADF4C")