X-Git-Url: https://code.consxy.com/gitweb/gitweb.cgi?p=clnl;a=blobdiff_plain;f=src%2Fmain%2Fnvm.lisp;h=79b0b36be2fa3d463e95fd02c470a7f1a2de30a0;hp=3ea76d9309c681662c6f35e686348dc8212fc812;hb=d429346c4e41599eaae8de2f4baa9c1b8a81aea6;hpb=d0e9e5aea40d947370e90276fe12fbaa671c8992 diff --git a/src/main/nvm.lisp b/src/main/nvm.lisp index 3ea76d9..79b0b36 100644 --- a/src/main/nvm.lisp +++ b/src/main/nvm.lisp @@ -2,8 +2,82 @@ ; This is the engine. Yay. +(defvar *current-id* 0) + +(defstruct turtle who color heading xcor ycor) +(defvar *turtles* nil) +(defvar *myself* nil) +(defvar *self* nil) + +(defun show (n) + (format t "Showing: ~A~%" (dump-object n))) + +(defun create-turtle () + (setf + *turtles* + (nconc + *turtles* + (list + (make-turtle :who *current-id* + :color (coerce (+ 5 (* 10 (cl-nl.random:next-int 14))) 'double-float) + :heading (coerce (cl-nl.random:next-int 360) 'double-float) + :xcor 0d0 + :ycor 0d0)))) + (incf *current-id*)) + +(defun turtles () *turtles*) + +(defun ask (agent-set fn) + (let + ((iter (shufflerator agent-set))) + (loop for agent = (funcall iter) + while agent + do (let ((*myself* *self*) (*self* agent)) (funcall fn))))) + +(defun shufflerator (agent-set) + (let + ((copy (copy-list agent-set)) + (i 0) + (agent nil)) + (flet + ((fetch () + (let + ((idx (when (< i (1- (length copy))) (+ i (cl-nl.random:next-int (- (length copy) i)))))) + (when idx (setf agent (nth idx copy))) + (when idx (setf (nth idx copy) (nth i copy))) + (incf i)))) + (fetch) ; we pre-fetch because netlogo does, rng sync hype! + (lambda () + (cond + ((> i (length copy)) nil) + ((= i (length copy)) (incf i) (car (last copy))) + (t (let ((result agent)) (fetch) result))))))) + +(defun random-float (n) + (cl-nl.random:next-double n)) + +(defun fd (n) + (when (not (turtle-p *self*)) (error "Gotta call fd in turtle scope, dude (~A)" *self*)) + (setf (turtle-xcor *self*) (+ (turtle-xcor *self*) (* n (sin (* pi (/ (turtle-heading *self*) 180)))))) + (setf (turtle-ycor *self*) (+ (turtle-ycor *self*) (* n (cos (* pi (/ (turtle-heading *self*) 180))))))) + (defun create-turtles (n) - (format t "HELLO WORLD ~A~%" n)) + (loop for i from 1 to n do (create-turtle))) + +(defun create-world () + (setf *turtles* nil) + (setf *current-id* 0)) + +; These match netlogo's dump +(defgeneric dump-object (o)) +(defmethod dump-object ((n double-float)) + (multiple-value-bind (int rem) (floor n) + (if (eql 0d0 rem) + (format nil "~A" int) + (let + ((output (format nil "~D" n))) + (cl-ppcre:regex-replace "d-" (cl-ppcre:regex-replace "d0" output "") "E-"))))) ; Someday we'll have d, but this is not that day! +(defmethod dump-object ((o string)) o) (defun export-world () (format nil "~{~A~%~}" @@ -13,11 +87,22 @@ "" (format nil "~S" "GLOBALS") "\"min-pxcor\",\"max-pxcor\",\"min-pycor\",\"max-pycor\",\"perspective\",\"subject\",\"nextIndex\",\"directed-links\",\"ticks\"," - "\"-1\",\"1\",\"-1\",\"1\",\"0\",\"nobody\",\"0\",\"\"\"NEITHER\"\"\",\"-1\"" + (format nil "\"-1\",\"1\",\"-1\",\"1\",\"0\",\"nobody\",\"~A\",\"\"\"NEITHER\"\"\",\"-1\"" *current-id*) "" (format nil "~S" "TURTLES") "\"who\",\"color\",\"heading\",\"xcor\",\"ycor\",\"shape\",\"label\",\"label-color\",\"breed\",\"hidden?\",\"size\",\"pen-size\",\"pen-mode\"" - "" + (format nil "~{~A~%~}" + (mapcar + (lambda (turtle) + (format nil + "\"~A\",\"~A\",\"~A\",\"~A\",\"~A\",\"\"\"default\"\"\",\"\"\"\"\"\",\"9.9\",\"{all-turtles}\",\"false\",\"1\",\"1\",\"\"\"up\"\"\"" + (turtle-who turtle) + (dump-object (turtle-color turtle)) + (dump-object (turtle-heading turtle)) + (dump-object (turtle-xcor turtle)) + (dump-object (turtle-ycor turtle)) + )) + *turtles*)) (format nil "~S" "PATCHES") "\"pxcor\",\"pycor\",\"pcolor\",\"plabel\",\"plabel-color\"" "\"-1\",\"1\",\"0\",\"\"\"\"\"\",\"9.9\""