;;; -*- Mode:LISP; Package:USER; Readtable:CL; Base:10 -*-


(defvar *i*)
(defvar *x*)
(defvar *y*)

(defvar *xmin* 0)
(defvar *xmax* 500)

(defvar *ymin* 0)
(defvar *ymax* 500)

(defun remote-eval (form host)
  (WITH-OPEN-STREAM (STREAM (chaos:OPEN-STREAM HOST "EVAL" :ERROR NIL))
    (send stream :string-out form)
    (send stream :finish)
    (read stream)))

(defvar *worm-lambda*)

(eval-when (compile load eval)
(setq *worm-lambda*
      '(lambda (stream len xmax ymax)
	 (let* ((i 0)
		(x (floor xmax 2))
		(y (floor ymax 2))
		(xmin 0)
		(ymin 0)
		(xlist (make-list len :initial-element x))
		(ylist (make-list len :initial-element y))
		real-stream)
	   (flet ((move-worm (stream xmax ymax xlist ylist)
			     (setq i (logand #x0f (+ i -1 (random 3))))
			 ;;; (if (> (random 1000) 994)
			 ;;;     (teleport))
			     (cond ((= y ymax)
				    (decf y))
				   ((= y ymin)
				    (incf y))
				   ((<= 0 i 5)
				    (incf y))
				   ((<= 8 i 13)
				    (decf y)))
			     (cond ((= x xmax)
				    (incf x))
				   ((= x xmin)
				    (incf x))
				   ((<= 4 i 9)
				    (incf x))
				   ((not (<= 2 i 11))
				    (decf x)))
			     (setf (tenth xlist) x
				   (tenth ylist) y)
			     (send stream :draw-line (car xlist) (car ylist) x y tv:alu-xor t)
			     (if (< (random 30) 30)
				 (send stream :draw-line (elt xlist 20) (elt ylist 20) (elt xlist 29) (elt ylist 29) tv:alu-xor t)
			       (send stream :draw-line (elt xlist 20) (elt ylist 20) (elt xlist 29) (elt ylist 29))))
		  #+never
	       ;;;(teleport()
		     ;;;   (setf x (random xmax))
		     ;;;   (setf y (random ymax)))
	     (rplacd (nthcdr (1- len) xlist) xlist)
	     (rplacd (nthcdr (1- len) ylist) ylist)
	     (do-forever
	       (setq real-stream (or stream
				     (tv:window-under-mouse)))
	       (dotimes (i 2000)
		 (move-worm real-stream xmax ymax xlist ylist)
		 (setq xlist (cdr xlist)
		       ylist (cdr ylist))
		 (process-allow-schedule)))))))
)

(defun remote-worm (host)
  (remote-eval (format nil "(progn (process-run-function \"Worm\" (compile nil '~s) nil 60. 500 500) nil)"
		       *worm-lambda*)
	       host))

(defun random-walk (&optional (size ()))
  (let ((len (cond (size size)
		   (t (prompt-and-read :number "~&What is length? ")))))
    (worm *terminal-io* len *xmax* *ymax*)))

(defun process-run-worm (len xmax1 ymax1 &optional (stream ()))
  (process-run-function '(:name "Worm" :priority -3) #'worm (cond (stream stream)
								  (t (tv:window-under-mouse)))
			len xmax1 ymax1))

(defun wormicide ()
  (dolist (p si:all-processes)
    (when (string-equal "Worm" (process-name p))
      (send p :kill))))
  
(defun worm #.(cadr *worm-lambda*) #.(cons 'progn (cddr *worm-lambda*)))




























