RosettaCodeData/Task/Matrix-digital-rain/Common-Lisp/matrix-digital-rain.lisp
2023-07-01 13:44:08 -04:00

32 lines
1.6 KiB
Common Lisp

(defun matrix-digital-rain ()
(with-screen (scr :input-echoing nil :input-blocking nil :cursor-visible nil)
(let* ((width (width scr))
(height (height scr))
;; start at a random height in each column.
(positions (loop repeat width collect (random height)))
;; run each column at a random speed.
(speeds (loop repeat width collect (random 4))))
;; generate a random ascii char
(flet ((randch () (+ 64 (random 58))))
;; hit the q key to exit the main loop.
(bind scr #\q 'exit-event-loop)
(bind scr nil
(lambda (win event)
(loop for col from 0 to (1- width) do
(loop repeat (nth col speeds) do
;; position of the first point in the current column
(let ((pos (nth col positions)))
(setf (attributes win) '(:bold))
(setf (fgcolor win) :green)
(add win (randch) :y (mod pos height) :x col :fgcolor :white)
(add win (randch) :y (mod (- pos 1) height) :x col)
(add win (randch) :y (mod (- pos 2) height) :x col)
(setf (attributes win) '())
(add win (randch) :y (mod (- pos 3) height) :x col)
;; overwrite the last char half the height from the first char.
(add win #\space :y (mod (- pos (floor height 2)) height) :x col)
(refresh win)
;; advance the current column
(setf (nth col positions) (mod (+ pos 1) height))))))))
(setf (frame-rate scr) 20)
(run-event-loop scr))))