comparison lisp/play/life.el @ 923:9f3cc03dae67

entered into RCS
author Jim Blandy <jimb@redhat.com>
date Tue, 04 Aug 1992 04:15:43 +0000
parents 20674ae6bf52
children 2c7997f249eb
comparison
equal deleted inserted replaced
922:52cd80cb5be1 923:9f3cc03dae67
52 52
53 ;; Macros are used macros for manifest constants instead of variables 53 ;; Macros are used macros for manifest constants instead of variables
54 ;; because the compiler will convert them to constants, which should 54 ;; because the compiler will convert them to constants, which should
55 ;; eval faster than symbols. 55 ;; eval faster than symbols.
56 ;; 56 ;;
57 ;; The (require) wrapping forces the compiler to eval these macros at
58 ;; compile time. This would not be necessary if we did not use macros
59 ;; inside of macros, which the compiler doesn't seem to check for.
60 ;;
61 ;; Don't change any of the life-* macro constants unless you thoroughly 57 ;; Don't change any of the life-* macro constants unless you thoroughly
62 ;; understand the `life-grim-reaper' function. 58 ;; understand the `life-grim-reaper' function.
63 (require 59
64 (progn 60 (defmacro life-life-char () ?@)
65 (defmacro life-life-char () ?@) 61 (defmacro life-death-char () (1+ (life-life-char)))
66 (defmacro life-death-char () (1+ (life-life-char))) 62 (defmacro life-birth-char () 3)
67 (defmacro life-birth-char () 3) 63 (defmacro life-void-char () ?\ )
68 (defmacro life-void-char () ?\ ) 64
69 65 (defmacro life-life-string () (char-to-string (life-life-char)))
70 (defmacro life-life-string () (char-to-string (life-life-char))) 66 (defmacro life-death-string () (char-to-string (life-death-char)))
71 (defmacro life-death-string () (char-to-string (life-death-char))) 67 (defmacro life-birth-string () (char-to-string (life-birth-char)))
72 (defmacro life-birth-string () (char-to-string (life-birth-char))) 68 (defmacro life-void-string () (char-to-string (life-void-char)))
73 (defmacro life-void-string () (char-to-string (life-void-char))) 69 (defmacro life-not-void-regexp () (concat "[^" (life-void-string) "\n]"))
74 (defmacro life-not-void-regexp () (concat "[^" (life-void-string) "\n]")) 70
75 71 ;; try to optimize the (goto-char (point-min)) & (goto-char (point-max))
76 ;; try to optimize the (goto-char (point-min)) & (goto-char (point-max)) 72 ;; idioms. This depends on goto-char's not griping if we underrshoot
77 ;; idioms. This depends on goto-char's not griping if we underrshoot 73 ;; or overshoot beginning or end of buffer.
78 ;; or overshoot beginning or end of buffer. 74 (defmacro goto-beginning-of-buffer () '(goto-char 1))
79 (defmacro goto-beginning-of-buffer () '(goto-char 1)) 75 (defmacro maxint () (lsh (lsh (lognot 0) 1) -1))
80 (defmacro maxint () (lsh (lsh (lognot 0) 1) -1)) 76 (defmacro goto-end-of-buffer () '(goto-char (maxint)))
81 (defmacro goto-end-of-buffer () '(goto-char (maxint))) 77
82 78 (defmacro increment (variable) (list 'setq variable (list '1+ variable)))
83 (defmacro increment (variable) (list 'setq variable (list '1+ variable))) 79
84 'life))
85 80
86 ;; list of numbers that tell how many characters to move to get to 81 ;; list of numbers that tell how many characters to move to get to
87 ;; each of a cell's eight neighbors. 82 ;; each of a cell's eight neighbors.
88 (defconst life-neighbor-deltas nil) 83 (defconst life-neighbor-deltas nil)
89 84
96 ;; Sadly, mode-line-format won't display numbers. 91 ;; Sadly, mode-line-format won't display numbers.
97 (defconst life-generation-string nil) 92 (defconst life-generation-string nil)
98 93
99 (defun abs (n) (if (< n 0) (- n) n)) 94 (defun abs (n) (if (< n 0) (- n) n))
100 95
96 ;;;###autoload
101 (defun life (&optional sleeptime) 97 (defun life (&optional sleeptime)
102 "Run Conway's Life simulation. 98 "Run Conway's Life simulation.
103 The starting pattern is randomly selected. Prefix arg (optional first 99 The starting pattern is randomly selected. Prefix arg (optional first
104 arg non-nil from a program) is the number of seconds to sleep between 100 arg non-nil from a program) is the number of seconds to sleep between
105 generations (this defaults to 1)." 101 generations (this defaults to 1)."
106 (interactive "p") 102 (interactive "p")
107 (or sleeptime (setq sleeptime 1)) 103 (or sleeptime (setq sleeptime 1))
108 (life-setup) 104 (life-setup)
109 (life-display-generation sleeptime) 105 (life-display-generation sleeptime)
110 (while t 106 (catch 'life-exit
111 (let ((inhibit-quit t)) 107 (while t
112 (life-grim-reaper) 108 (let ((inhibit-quit t))
113 (life-expand-plane-if-needed) 109 (life-grim-reaper)
114 (life-increment-generation) 110 (life-expand-plane-if-needed)
115 (life-display-generation sleeptime)))) 111 (life-increment-generation)
112 (life-display-generation sleeptime)))))
116 113
117 (fset 'life-mode 'life) 114 (fset 'life-mode 'life)
118 (put 'life-mode 'mode-class 'special) 115 (put 'life-mode 'mode-class 'special)
119 116
120 (random t) 117 (random t)
265 (setq life-window-start (+ life-window-start fill-column 1))))) 262 (setq life-window-start (+ life-window-start fill-column 1)))))
266 263
267 (defun life-display-generation (sleeptime) 264 (defun life-display-generation (sleeptime)
268 (goto-char life-window-start) 265 (goto-char life-window-start)
269 (recenter 0) 266 (recenter 0)
270 (sit-for sleeptime)) 267
268 ;; Redisplay; if the user has hit a key, exit the loop.
269 (or (eq t (sit-for sleeptime))
270 (throw 'life-exit nil)))
271 271
272 (defun life-extinct-quit () 272 (defun life-extinct-quit ()
273 (life-display-generation 0) 273 (life-display-generation 0)
274 (signal 'life-extinct nil)) 274 (signal 'life-extinct nil))
275 275