Matrix digital rain: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Perl 6}}: Add a sample image link)
(Small Lisp code edit, add output png, add categories)
Line 6: Line 6:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==

{{works with|SBCL}}


Runs in the terminal (using the Ncurses C library and the croatoan Lisp wrapper).
Runs in the terminal (using the Ncurses C library and the croatoan Lisp wrapper).
Line 15: Line 17:
(height (.height scr))
(height (.height scr))
;; start at a random height in each column.
;; start at a random height in each column.
(pos (loop repeat width collect (random height)))
(positions (loop repeat width collect (random height)))
;; run each column at a random speed.
;; run each column at a random speed.
(speeds (loop repeat width collect (random 4))))
(speeds (loop repeat width collect (random 4))))
Line 26: Line 28:
(loop for col from 0 to (1- width) do
(loop for col from 0 to (1- width) do
(loop repeat (nth col speeds) do
(loop repeat (nth col speeds) do
(setf (.attributes win) '(:bold))
;; position of the first point in the current column
(setf (.color-pair win) '(:white :black))
(let ((pos (nth col positions)))
(add win (randch) :y (mod (nth col pos) height) :x col)
(setf (.attributes win) '(:bold))
(setf (.color-pair win) '(:green :black))
(setf (.color-pair win) '(:white :black))
(add win (randch) :y (mod (- (nth col pos) 1) height) :x col)
(add win (randch) :y (mod pos height) :x col)
(add win (randch) :y (mod (- (nth col pos) 2) height) :x col)
(setf (.color-pair win) '(:green :black))
(setf (.attributes win) '())
(add win (randch) :y (mod (- pos 1) height) :x col)
(add win (randch) :y (mod (- (nth col pos) 3) height) :x col)
(add win (randch) :y (mod (- pos 2) height) :x col)
;; overwrite the last char half the height from the first char.
(setf (.attributes win) '())
(add win #\space :y (mod (- (nth col pos) (floor height 2)) height) :x col)
(add win (randch) :y (mod (- pos 3) height) :x col)
;; overwrite the last char half the height from the first char.
(refresh win)
;; advance the column
(add win #\space :y (mod (- pos (floor height 2)) height) :x col)
(setf (nth col pos) (mod (1+ (nth col pos)) height)))))))
(refresh win)
;; advance the current column
(setf (.frame-rate scr) 20)
(setf (nth col positions) (mod (+ pos 1) height))))))))
(run-event-loop scr))))
(setf (.frame-rate scr) 20)
(run-event-loop scr))))
</lang>
</lang>

{{out|Sample output}}
[https://i.imgur.com/17b36O3.png https://i.imgur.com/17b36O3.png]


=={{header|Perl 6}}==
=={{header|Perl 6}}==
Line 87: Line 94:
{{out|Sample output}}
{{out|Sample output}}
See [https://github.com/thundergnat/rc/blob/master/img/matrix-digital-rain-perl6.png matrix-digital-rain-perl6.png] (offsite png image)
See [https://github.com/thundergnat/rc/blob/master/img/matrix-digital-rain-perl6.png matrix-digital-rain-perl6.png] (offsite png image)


[[Category:Ncurses]]
[[Category:Curses]]

Revision as of 11:43, 19 December 2018

Matrix digital rain is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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

Works with: SBCL

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.
          (positions (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
               ;; position of the first point in the current column
               (let ((pos (nth col positions)))
                 (setf (.attributes win) '(:bold))
                 (setf (.color-pair win) '(:white :black))
                 (add win (randch) :y (mod pos height) :x col)
                 (setf (.color-pair win) '(:green :black))
                 (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))))

</lang>

Sample output:

https://i.imgur.com/17b36O3.png

Perl 6

Works with: Rakudo version 2018.11

Kind of cheap and cheesy, but what the heck... Probably will only work in POSIX compatible terminal. Runs until you hit ^C to exit.

<lang perl6>my @codes = flat 'Α' .. 'Π', 'Σ' .. 'ѵ', 'Ѐ' .. 'ѵ', 'Ҋ' .. 'ԯ', 'Ϣ' .. 'ϯ',

                'Ⲁ' .. '⳩', '∀' .. '∗', '℀' .. '℺', '⨀' .. '⫿';

my ($rows,$cols) = qx/stty size/.words;

my @c = flat "\e[38;2;255;255;255m", (255,240 … 30).map({"\e[38;2;0;$_;0m"}),

             "\e[38;2;0;25;0m" xx 250;

my $sz = +@c; my (@o, @s, @a); print "\e[?25l"; init($rows, $cols);

loop {

    my ($r,$c) = qx/stty size/.words;
    init($r, $c) if $r != $rows or $c != $cols;
    print "\e[1;1H";
    for ^@s {
        print (@c[@a[$_]<fg>], @a[$_]<bg>, @s[$_]).join;
        @a[$_]<fg> = (@a[$_]<fg> + 1) % $sz;
    }
    @s[(^@s).pick] = @codes.roll for ^100;

}

sub init ($r, $c) {

   @s = @codes.roll($r * $c);
   ($rows,$cols) = $r, $c;
   @a = {:bg("\e[48;5;232m")} xx +@s;
   my @o = (^@c).pick xx $cols;
   for ^$rows -> $row {
       for ^$cols -> $col {
           @a[$row * $cols + $col]<fg> = @o[$col];
       }
       @o = (^@o).map: {(@o[$_] - 1) % $sz};
   }

}

END { print "\e[?25h \e[H\e[J";} # clear and reset screen</lang>

Sample output:

See matrix-digital-rain-perl6.png (offsite png image)