93 lines
3.2 KiB
Ada
93 lines
3.2 KiB
Ada
with Ada.Text_IO;
|
|
with Ada.Numerics.Discrete_Random;
|
|
with Ada.Strings.Fixed;
|
|
|
|
procedure Digital_Rain is
|
|
type Column_Type is range 0 .. 150;
|
|
type Row_Type is range 0 .. 25;
|
|
type Character_Range is new Character range 'A' .. 'Z';
|
|
subtype Delay_Range is Integer range 2 .. 6;
|
|
|
|
package Column_Random is new Ada.Numerics.Discrete_Random (Column_Type);
|
|
package Row_Random is new Ada.Numerics.Discrete_Random (Row_Type);
|
|
package Character_Random is new Ada.Numerics.Discrete_Random (Character_Range);
|
|
package Delay_Random is new Ada.Numerics.Discrete_Random (Delay_Range);
|
|
|
|
Column_Generator : Column_Random.Generator;
|
|
Row_Generator : Row_Random.Generator;
|
|
Character_Generator : Character_Random.Generator;
|
|
Delay_Generator : Delay_Random.Generator;
|
|
|
|
Esc : constant Character := Character'Val (8#33#);
|
|
Running : Boolean := True;
|
|
Char : Character;
|
|
use Ada.Text_IO;
|
|
|
|
protected Text_Out is
|
|
procedure Put_At (Row : Row_Type; Col : Column_Type;
|
|
Color : Integer; Item : Character);
|
|
end Text_Out;
|
|
|
|
protected body Text_Out is
|
|
procedure Put_At (Row : Row_Type; Col : Column_Type;
|
|
Color : Integer; Item : Character)
|
|
is
|
|
use Ada.Strings;
|
|
begin
|
|
Put (Esc & "[" &
|
|
Fixed.Trim (Row'Image, Left) & ";" &
|
|
Fixed.Trim (Col'Image, Left) & "H"); -- Place Cursor
|
|
Put (Esc & "[" & Fixed.Trim (Color'Image, Left) & "m"); -- Foreground color
|
|
Put (Item);
|
|
end Put_At;
|
|
end Text_Out;
|
|
|
|
task type Rainer;
|
|
|
|
task body Rainer is
|
|
Row : Row_Type;
|
|
Col : Column_Type;
|
|
Del : Delay_Range;
|
|
begin
|
|
Outer_Loop:
|
|
loop
|
|
Col := Column_Random.Random (Column_Generator);
|
|
Row := Row_Random.Random (Row_Generator);
|
|
for Rain in reverse Boolean loop
|
|
Del := Delay_Random.Random (Delay_Generator);
|
|
for R in 0 .. Row loop
|
|
if Rain then
|
|
if R in 1 .. Row then
|
|
Text_Out.Put_At (R - 1, Col, Color => 32, Item => Char);
|
|
end if;
|
|
Char := Character (Character_Random.Random (Character_Generator));
|
|
if R in 0 .. Row - 1 then
|
|
Text_Out.Put_At (R, Col, Color => 97, Item => Char);
|
|
end if;
|
|
else
|
|
Text_Out.Put_At (R, Col, Color => 30, Item => ' ');
|
|
end if;
|
|
delay 0.020 * Del;
|
|
exit Outer_Loop when not Running;
|
|
end loop;
|
|
end loop;
|
|
end loop Outer_Loop;
|
|
end Rainer;
|
|
|
|
Dummy : Character;
|
|
Rainers : array (1 .. 50) of Rainer;
|
|
begin
|
|
Put (ESC & "[?25l"); -- Hide the cursor
|
|
Put (ESC & "[40m"); -- Black background
|
|
Put (ESC & "[2J"); -- Clear Terminal
|
|
|
|
Get_Immediate (Dummy);
|
|
Running := False;
|
|
delay 0.200;
|
|
|
|
Put (ESC & "[?25h"); -- Restore the cursor
|
|
Put (ESC & "[0;0H"); -- Place cursor
|
|
Put (ESC & "[39m"); -- Default foreground
|
|
Put (ESC & "[49m"); -- Default backgound
|
|
Put (ESC & "[2J"); -- Clear Terminal
|
|
end Digital_Rain;
|