Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (in-package #:snake-utils)
- (defclass snake ()
- ((body
- :accessor snake-body ;; list of snake-parts
- :initarg :body
- :initform '())
- (length
- :accessor snake-length
- :initarg :length
- :initform 0)
- (head-direction ;; :up, :down, :left, :right
- :accessor snake-head-direction
- :initarg :head-direction
- :initform :down)
- (dead-p
- :accessor snake-dead-p
- :initform nil)
- ;; can later add other fields like power-up-status
- ))
- (defclass snake-part ()
- ((position
- :accessor sp-position
- :initarg :position)
- (direction
- :accessor sp-direction
- :initarg :direction
- :initform :down)
- (previous
- :accessor sp-previous
- :initarg :previous
- :initform nil)))
- ;;------------------------------------------------------------
- (defun spawn-snake (&key board-dim (pos '(0 0)) (direction :down) (body-length 3))
- "Create instance of snake on board.
- ARGS:
- `board-dim' - a list like '(16 9)
- `pos' - position of snake-head on board e.g.: '(3 5)
- `direction' - :up, :down, :left, :right
- `body-length' - how many snake-parts the snake consists of"
- (let ((x-dim (first board-dim))
- (y-dim (second board-dim))
- (x-pos (first pos))
- (y-pos (second pos)))
- (labels ((snake-make-body ()
- "create list out of `body-length' snake-parts. Starting from the tail"
- (labels ((calc-x-pos (index)
- (case direction
- (:up x-pos)
- (:down x-pos)
- (:left (+ x-pos (1- (- body-length index))))
- (:right (- x-pos (1- (- body-length index))))))
- (calc-y-pos (index)
- (case direction
- (:up (- y-pos (1- (- body-length index))))
- (:down (+ y-pos (1- (- body-length index))))
- (:left y-pos)
- (:right y-pos))))
- (do* ((i 0 (1+ i))
- (previous-part nil)
- (curr-part nil)
- (result '() (cons curr-part result)))
- ((= i body-length) result)
- (setf curr-part (make-instance 'snake-part
- :position `(,(calc-x-pos i) ,(calc-y-pos i))
- :previous previous-part))
- (setf previous-part curr-part))))
- (outside-board-p ()
- "Checks weather the snake fits completely onto the board."
- (labels ((head-not-on-board-p ()
- (or (or (> 0 x-pos) (>= x-pos x-dim))
- (or (> 0 y-pos) (>= y-pos y-dim))))
- (tail-in-wall-p ()
- (case direction
- (:up (> 0 (- y-pos (1- body-length))))
- (:down (< y-dim (+ y-pos (1- body-length))))
- (:left (< x-dim (+ x-pos (1- body-length))))
- (:right (> 0 (- x-pos (1- body-length)))))))
- (or (head-not-on-board-p)
- (tail-in-wall-p)))))
- ;;----------------------------------------
- (unless (outside-board-p) ;; checks weather the snake can be created
- (make-instance 'snake
- :body (snake-make-body)
- :length body-length
- :head-direction direction)))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement