-(defun random-float (n)
- "RANDOM-FLOAT N => RANDOM-NUMBER
-
-ARGUMENTS AND VALUES:
-
- N: a double, the upper bound of the random float
- RANDOM-NUMBER: a double, the random result
-
-DESCRIPTION:
-
- Returns a random number strictly closer to zero than N.
-
- If number is positive, returns a random floating point number greater than
- or equal to 0 but strictly less than number.
-
- If number is negative, returns a random floating point number less than or equal
- to 0, but strictly greater than number.
-
- If number is zero, the result is always 0.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-float"
- (clnl-random:next-double n))
-
-(defun random (n)
- "RANDOM N => RANDOM-NUMBER
-
-ARGUMENTS AND VALUES:
-
- N: an integer, the upper bound of the random
- RANDOM-NUMBER: an integer, the random result
-
-DESCRIPTION:
-
- Returns a random number strictly closer to zero than N.
-
- If number is positive, returns a random integer greater than or equal to 0,
- but strictly less than number.
-
- If number is negative, returns a random integer less than or equal to 0,
- but strictly greater than number.
-
- If number is zero, the result is always 0.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random"
- (coerce (clnl-random:next-long (truncate n)) 'double-float))
-
-(defun random-xcor ()
- "RANDOM-XCOR => RANDOM-NUMBER
-
-ARGUMENTS AND VALUES:
-
- RANDOM-NUMBER: a float, the random result
-
-DESCRIPTION:
-
- Returns a random floating point number in the allowable range of turtle
- coordinates along the x axis.
-
- These range from min-pxcor - 0.5 (inclusive) to max-pxcor + 0.5 (exclusive)
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
- (let
- ((min (- (min-pxcor) 0.5d0))
- (max (+ (max-pxcor) 0.5d0)))
- (+ min (clnl-random:next-double (- max min)))))
-
-(defun random-ycor ()
- "RANDOM-YCOR => RANDOM-NUMBER
-
-ARGUMENTS AND VALUES:
-
- RANDOM-NUMBER: a float, the random result
-
-DESCRIPTION:
-
- Returns a random floating point number in the allowable range of turtle
- coordinates along the y axis.
-
- These range from min-pycor - 0.5 (inclusive) to max-pycor + 0.5 (exclusive)
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#random-cor"
- (let
- ((min (- (min-pycor) 0.5d0))
- (max (+ (max-pycor) 0.5d0)))
- (+ min (clnl-random:next-double (- max min)))))
-
-(defun one-of (list-or-agentset)
- "ONE-OF LIST-OR-AGENTSET => RESULT
-
- LIST-OR-AGENTSET: LIST | AGENTSET
- RESULT: RANDOM-VALUE | RANDOM-AGENT | :nobody
-
-ARGUMENTS AND VALUES:
-
- LIST: A list
- AGENTSET: An agent set
- RANDOM-VALUE: a value in LIST
- RANDOM-AGENT: an agent if AGENTSET is non empty
-
-DESCRIPTION:
-
- From an AGENTSET, returns a RANDOM-AGENT. If the agentset is empty, returns :nobody.
- From a list, returns a RANDOM-VALUE. If the list is empty, an error occurs.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#one-of"
- (cond
- ((agentset-p list-or-agentset)
- (let*
- ((agentset-list (agentset-list list-or-agentset))
- (length (length agentset-list)))
- (if (zerop length) :nobody (nth (clnl-random:next-int length) agentset-list))))
- ((listp list-or-agentset)
- (let*
- ((length (length list-or-agentset)))
- (if (zerop length)
- (error "one-of requires a nonempty list")
- (nth (clnl-random:next-int length) list-or-agentset))))
- (t (error "one-of requires a list or agentset"))))
-
-(defun jump (n)
- (when (not (turtle-p *self*)) (error "Gotta call jump in turtle scope, dude (~A)" *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
-
-ARGUMENTS AND VALUES:
-
- X: a double
- Y: a double
- RESULT: undefined
-
-DESCRIPTION:
-
- Sets the x-coordinate and y-coordinate for the turle. Equivalent to
- set xcor x set ycor y, except it happens in one step inside of two.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#setxy"
- (when (not (turtle-p *self*)) (error "Gotta call setxy in turtle scope, dude (~A)" *self*))
- (setf (turtle-xcor *self*) (wrap-x *topology* x))
- (setf (turtle-ycor *self*) (wrap-y *topology* y)))
-
-(defun set-default-shape (breed shape)
- "SET-DEFAULT-SHAPE BREED SHAPE => RESULT
-
-ARGUMENTS AND VALUES:
-
- BREED: a valid breed
- SHAPE: a string
- RESULT: undefined
-
-DESCRIPTION:
-
- Specifies a default initial shape for a BREED. When a turtle, or it changes breeds,
- its shape is set to the given shape.
-
- SET-DEFAULT-SHAPE doesn't affect existing agents, only agents you create afterwards.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#set-default-shape"
- (when (not (breed-p breed)) (error "Need a valid breed"))
- (setf (breed-default-shape breed) shape))
-
-(defun forward (n)
- "FORWARD N => RESULT
-
-ARGUMENTS AND VALUES:
-
- N: a double, the amount the turtle moves forward
- RESULT: undefined
-
-DESCRIPTION:
-
- Moves the current turtle forward N steps, one step at a time.
-
- This moves forward one at a time in order to make the view updates look
- good in the case of a purposefully slow running instance. If the number
- is negative, the turtle moves backward.
-
- If the current agent is not a turtle, it raises an error.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#forward"
- (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
- (labels
- ((internal (i)
- (cond
- ((< (abs i) 3.2e-15) nil)
- ((< (abs i) 1d0) (jump i))
- (t (jump (if (> i 0d0) 1d0 -1d0)) (internal (- i (if (> i 0d0) 1d0 -1d0)))))))
- (internal n)))
-
-(defun turn-right (n)
- "TURN-RIGHT N => RESULT
-
-ARGUMENTS AND VALUES:
-
- N: a double, the amount the turtle turns
- RESULT: undefined
-
-DESCRIPTION:
-
- The turtle turns right by number degrees. (If number is negative, it turns left.)
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"
- (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*))
- (let
- ((new-heading (+ (turtle-heading *self*) n)))
- (setf (turtle-heading *self*)
- (cond
- ((< new-heading 0) (+ (mod new-heading -360) 360))
- ((>= new-heading 360) (mod new-heading 360))
- (t new-heading)))))
-
-(defun turn-left (n)
- "TURN-LEFT N => RESULT
-
-ARGUMENTS AND VALUES:
-
- N: a double, the amount the turtle turns
- RESULT: undefined
-
-DESCRIPTION:
-
- The turtle turns left by number degrees. (If number is negative, it turns right.)
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#right"
- (turn-right (- n)))
-
-(defun create-turtles (n &optional breed fn)
- "CREATE-TURTLES N &optional BREED FN => RESULT
-
-ARGUMENTS AND VALUES:
-
- N: an integer, the numbers of turtles to create
- BREED: a breed
- FN: A function, applied to each turtle after creation
- RESULT: undefined
-
-DESCRIPTION:
-
- Creates N new turtles at the origin.
-
- New turtles have random integer headings and the color is randomly selected
- from the 14 primary colors. If FN is supplied, the new turtles immediately
- run it. If a BREED is supplied, that is the breed the new turtles are set
- to.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#create-turtles"
- (let
- ((new-turtles (loop :repeat n :collect (create-turtle breed))))
- (when fn (ask (list->agentset new-turtles :turtles) fn))))
-
-(defun hatch (n &optional fn)
- "HATCH N &optional FN => RESULT
-
-ARGUMENTS AND VALUES:
-
- N: an integer, the numbers of turtles to hatch
- FN: A function, applied to each turtle after creation
- RESULT: undefined
-
-DESCRIPTION:
-
- The turtle in *self* creates N new turtles. Each new turtle inherits of all its
- variables, including its location, from self.
-
- If FN is supplied, the new turtles immediately run it.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#hatch"
- (when (not (turtle-p *self*)) (error "Can only hatch from turtle scope"))
- (let
- ((new-turtles (loop :repeat n :collect (create-turtle nil *self*))))
- (when fn (ask (list->agentset new-turtles :turtles) fn))))
-
-(defun reset-ticks ()
- "RESET-TICKS => RESULT
-
-ARGUMENTS AND VALUES:
-
- RESULT: undefined
-
-DESCRIPTION:
-
- Resets the tick counter to zero, sets up all plots, then updates all plots.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#reset-ticks"
- (setf *ticks* 0d0))
-
-(defun tick ()
- "RESET-TICKS => RESULT
-
-ARGUMENTS AND VALUES:
-
- RESULT: undefined
-
-DESCRIPTION:
-
- Advances the tick counter by one and updates all plots.
-
- If the tick counter has not been started yet with reset-ticks, an error results.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#tick"
-
- (when (not *ticks*) (error "reset-ticks must be called"))
- (incf *ticks*))
-
-(defun ticks ()
- "TICKS => CURRENT-TICKS
-
-ARGUMENTS AND VALUES:
-
- CURRENT-TICKS: A positiv double, representing the current number of ticks
-
-DESCRIPTION:
-
- Reports the current value of the tick counter. The result is always a number and never negative.
-
- If the tick counter has not been started yet with reset-ticks, an error results.
-
- See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#ticks"
- (when (not *ticks*) (error "reset-ticks must be called"))
- *ticks*)
-
-(defun clear-patches ()
- (setf
- *patches*
- (loop
- :for y :from (max-pycor) :downto (min-pycor)
- :append (loop
- :for x :from (min-pxcor) :to (max-pxcor)
- :collect (make-patch
- :xcor (coerce x 'double-float)
- :ycor (coerce y 'double-float)
- :color 0d0)))))
-
-(defun clear-turtles ()
- (setf *turtles* nil)
- (setf *current-id* 0))
-
-(defun clear-ticks ()
- (setf *ticks* nil))
-