;;; -*- Mode:LISP; Package: (CA :use LISP); Readtable:CL; Base:10 -*-



(defvar *current*)
(defvar *next*)
(defvar *width*)
(defvar *height*)

(defun generation ()
  (dotimes (y *height*)
    (dotimes (x *width*)
      


(defvar *address* 0)

(defvar *x*)
(defvar *y*)
(defvar *array*)

(defmacro center ()
  `(si:ar-2-reverse *current* *x* *y*))

(defmacro north ()
  `(si:ar-2-reverse *current* *x* (1- *y*)))

(defmacro south ()
  `(si:ar-2-reverse *current* *x* (1+ *y*)))

(defmacro east ()
  `(si:ar-2-reverse *current* (1+ *x*) *y*))

(defmacro west ()
  `(si:ar-2-reverse *current* (1- *x*) *y*))

(defmacro n-west ()
  `(si:ar-2-reverse *current* (1- *x*) (1- *y*)))

(defmacro n-east ()
  `(si:ar-2-reverse *current* (1+ *x*) (1- *y*)))

(defmacro s-west ()
  `(si:ar-2-reverse *current* (1- *x*) (1+ *y*)))

(defmacro s-east ()
  `(si:ar-2-reverse *current* (1+ *x*) (1+ *y*)))


(defmacro do-binary (vars &body body)
  (if (null vars)
      `(PROGN ,@body)
    `(DOTIMES (,(car vars) 2)
       (DO-BINARY ,(cdr vars) ,@body))))

(defvar center)

(defvar north)
(defvar south)
(defvar east)
(defvar west)

(defvar n-west)
(defvar n-east)
(defvar s-west)
(defvar s-east)

(defvar *make-address-function*)
(defvar *make-table-function*)

(defun make-address ()
  (funcall *make-address-function*))

(defun make-table (f)
  (funcall *make-table-function* f))

(defmacro %make-address (&rest bits)
  (do ((bits bits (cdr bits))
       (n (1- (length bits)) (1- n))
       (form 0 `(DPB ,(car bits) (BYTE 1 ,n) ,form)))
      ((null bits) form)))
       
(defun make-moore-neighborhood-address ()
  (%make-address n-west north  n-east
	         west   center east
	         s-west south  s-east))

(defun get-moore-neighborhood-address ()
  (%make-address (n-west) (north)  (n-east)
		 (west)   (center) (east)
		 (s-west) (south)  (s-east)))
  
(defun make-moore-neighborhood-table (f) 
  (do-binary (n-west north  n-east
	      west   center east
	      s-west south  s-east)
     (funcall f)))

  
(defun use-moore-neighborhood ()
  (setq *make-address-function* #'make-moore-neighborhood-address)
  (setq *make-table-function*   #'make-moore-neighborhood-table))

(defconstant address-lines 12)
(defvar *plane-0-table* (make-array (expt 2 address-lines) :element-type '(unsigned-byte 1)))

(defun >plane-0 (value)
  (setf (aref *plane-0-table* (make-address))
	value))
  




(defun 8sum ()
  (+ n-west north  n-east
     west          east
     s-west south  s-east))


(defun 1-out-of-8 ()
  (>plane-0
    (if (= 1 (8sum))
	1
      center)))


      