Matrix digital rain

From Rosetta Code
Revision as of 18:08, 18 December 2018 by Avi (talk | contribs) (→‎{{header|Common Lisp}}: rename function)
Task
Matrix digital rain
You are encouraged to solve this task according to the task description, using any language you may know.

Implement the Matrix Digital Rain visual effect from the movie "The Matrix" as described in Wikipedia.

Provided is a reference implementation in Common Lisp to be run in a terminal.

Common Lisp

Runs in the terminal (using the Ncurses C library and the croatoan Lisp wrapper).

<lang lisp> (defun matrix-digital-rain ()

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

</lang>