;;; snake.el --- implementation of Snake for Emacs
-;; Copyright (C) 1997, 2001-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 2001-2016 Free Software Foundation, Inc.
;; Author: Glynn Clements <glynn@sensei.co.uk>
;; Created: 1997-09-10
;;; Code:
-(eval-when-compile
- (require 'cl))
+(eval-when-compile (require 'cl-lib))
(require 'gamegrid)
(defvar snake-velocity-x 1)
(defvar snake-velocity-y 0)
(defvar snake-positions nil)
-(defvar snake-cycle 0)
(defvar snake-score 0)
(defvar snake-paused nil)
(defvar snake-moved-p nil)
(make-variable-buffer-local 'snake-velocity-x)
(make-variable-buffer-local 'snake-velocity-y)
(make-variable-buffer-local 'snake-positions)
-(make-variable-buffer-local 'snake-cycle)
(make-variable-buffer-local 'snake-score)
(make-variable-buffer-local 'snake-paused)
(make-variable-buffer-local 'snake-moved-p)
(defun snake-display-options ()
(let ((options (make-vector 256 nil)))
- (loop for c from 0 to 255 do
+ (dotimes (c 256)
(aset options c
(cond ((= c snake-blank)
snake-blank-options)
(defun snake-update-score ()
(let* ((string (format "Score: %05d" snake-score))
(len (length string)))
- (loop for x from 0 to (1- len) do
+ (dotimes (x len)
(gamegrid-set-cell (+ snake-score-x x)
snake-score-y
(aref string x)))))
snake-buffer-height
snake-space)
(let ((buffer-read-only nil))
- (loop for y from 0 to (1- snake-height) do
- (loop for x from 0 to (1- snake-width) do
- (gamegrid-set-cell x y snake-border)))
- (loop for y from 1 to (- snake-height 2) do
- (loop for x from 1 to (- snake-width 2) do
- (gamegrid-set-cell x y snake-blank)))))
+ (dotimes (y snake-height)
+ (dotimes (x snake-width)
+ (gamegrid-set-cell x y snake-border)))
+ (cl-loop for y from 1 to (- snake-height 2) do
+ (cl-loop for x from 1 to (- snake-width 2) do
+ (gamegrid-set-cell x y snake-blank)))))
(defun snake-reset-game ()
(gamegrid-kill-timer)
snake-velocity-x snake-initial-velocity-x
snake-velocity-y snake-initial-velocity-y
snake-positions nil
- snake-cycle 1
snake-score 0
snake-paused nil
snake-moved-p nil
(dotimes (i snake-length)
(gamegrid-set-cell x y snake-snake)
(setq snake-positions (cons (vector x y) snake-positions))
- (incf x snake-velocity-x)
- (incf y snake-velocity-y)))
+ (cl-incf x snake-velocity-x)
+ (cl-incf y snake-velocity-y)))
(snake-update-score))
+(defun snake-set-dot ()
+ (let ((x (random snake-width))
+ (y (random snake-height)))
+ (while (not (= (gamegrid-get-cell x y) snake-blank))
+ (setq x (random snake-width))
+ (setq y (random snake-height)))
+ (gamegrid-set-cell x y snake-dot)))
+
(defun snake-update-game (snake-buffer)
"Called on each clock tick.
Advances the snake one square, testing for collision.
(= c snake-snake))
(snake-end-game)
(cond ((= c snake-dot)
- (incf snake-length)
- (incf snake-score)
- (snake-update-score))
+ (cl-incf snake-length)
+ (cl-incf snake-score)
+ (snake-update-score)
+ (snake-set-dot))
(t
(let* ((last-cons (nthcdr (- snake-length 2)
snake-positions))
(tail-pos (cadr last-cons))
(x0 (aref tail-pos 0))
(y0 (aref tail-pos 1)))
- (gamegrid-set-cell x0 y0
- (if (= (% snake-cycle 5) 0)
- snake-dot
- snake-blank))
- (incf snake-cycle)
+ (gamegrid-set-cell x0 y0 snake-blank)
(setcdr last-cons nil))))
(gamegrid-set-cell x y snake-snake)
(setq snake-positions
(cons (vector x y) snake-positions))
- (setq snake-moved-p nil)))))
+ (setq snake-moved-p nil)))))
(defun snake-update-velocity ()
(unless snake-moved-p
"Start a new game of Snake."
(interactive)
(snake-reset-game)
+ (snake-set-dot)
(use-local-map snake-mode-map)
(gamegrid-start-timer snake-tick-period 'snake-update-game))
(put 'snake-mode 'mode-class 'special)
-(defun snake-mode ()
- "A mode for playing Snake.
-
-Snake mode keybindings:
- \\{snake-mode-map}
-"
- (kill-all-local-variables)
+(define-derived-mode snake-mode special-mode "Snake"
+ "A mode for playing Snake."
(add-hook 'kill-buffer-hook 'gamegrid-kill-timer nil t)
(use-local-map snake-null-map)
- (setq major-mode 'snake-mode)
- (setq mode-name "Snake")
-
(unless (featurep 'emacs)
(setq mode-popup-menu
'("Snake Commands"
(setq gamegrid-use-glyphs snake-use-glyphs-flag)
(setq gamegrid-use-color snake-use-color-flag)
- (gamegrid-init (snake-display-options))
-
- (run-mode-hooks 'snake-mode-hook))
+ (gamegrid-init (snake-display-options)))
;;;###autoload
(defun snake ()