Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Thursday, February 26, 2009


Thanks to the original author of the code (google m7tr1x)..

I had some great fun looking at the code, understanding how this effect works, and refactoring.

The original code is below.. I suggest scrolling down, and looking at the refactored code and pictures describing how the effect works.

Enjoy!

#define readkey

using System;

namespace m7tr1x
{
    class Program
    {
        static void Main(string[ ] args)
        {
            Console.Title = "tH3 M7tr1x 3ff3<t";
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WindowLeft = Console.WindowTop = 0;
            Console.WindowHeight = Console.BufferHeight = Console.LargestWindowHeight;
            Console.WindowWidth = Console.BufferWidth = Console.LargestWindowWidth;
#if readkey
            Console.WriteLine("H1T 7NY K3Y T0 C0NT1NU3 =/");
            Console.ReadKey();
#endif
            Console.CursorVisible = false;
            int width, height;
            int[ ] y;
            int[ ] l;
            Initialize(out width, out height, out y, out l);
            int ms;
            while ( true )
            {
                DateTime t1 = DateTime.Now;
                MatrixStep(width, height, y, l);
                ms = 10 - (int)( (TimeSpan)( DateTime.Now - t1 ) ).TotalMilliseconds;
                if ( ms > 0 )
                    System.Threading.Thread.Sleep(ms);
                if ( Console.KeyAvailable )
                    if ( Console.ReadKey().Key == ConsoleKey.F5 )
                        Initialize(out width, out height, out y, out l);
            }
        }

        static bool thistime = false;

        private static void MatrixStep(int width, int height, int[ ] y, int[ ] l)
        {
            int x;
            thistime = !thistime;
            for ( x = 0 ; x < width ; ++x )
            {
                if ( x % 11 == 10 )
                {
                    if ( !thistime )
                        continue;
                    Console.ForegroundColor = ConsoleColor.White;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    Console.SetCursorPosition(x, inBoxY(y[x] - 2 - ( l[x] / 40 * 2 ), height));
                    Console.Write(R);
                    Console.ForegroundColor = ConsoleColor.Green;
                }
                Console.SetCursorPosition(x, y[x]);
                Console.Write(R);
                y[x] = inBoxY(y[x] + 1, height);
                Console.SetCursorPosition(x, inBoxY(y[x] - l[x], height));
                Console.Write(' ');
            }
        }

        private static void Initialize(out int width, out int height, out int[ ] y, out int[ ] l)
        {
            int h1;
            int h2 = ( h1 = ( height = Console.WindowHeight ) / 2 ) / 2;
            width = Console.WindowWidth - 1;
            y = new int[width];
            l = new int[width];
            int x;
            Console.Clear();
            for ( x = 0 ; x < width ; ++x )
            {
                y[x] = r.Next(height);
                l[x] = r.Next(h2 * ( ( x % 11 != 10 ) ? 2 : 1 ), h1 * ( ( x % 11 != 10 ) ? 2 : 1 ));
            }
        }

        static Random r = new Random();
        static char R
        {
            get
            {
                int t = r.Next(10);
                if ( t <= 2 )
                    return (char)( '0' + r.Next(10) );
                else if ( t <= 4 )
                    return (char)( 'a' + r.Next(27) );
                else if ( t <= 6 )
                    return (char)( 'A' + r.Next(27) );
                else
                    return (char)( r.Next(32, 255) );
            }
        }

        public static int inBoxY(int n, int height)
        {
            n = n % height;
            if ( n < 0 )
                return n + height;
            else
                return n;
        }
    }
}
Here is the refactored code:
using System;

namespace matrix
{
    class Program
    {
        // fields
        static Random rand = new Random();
        
        // properties
        static char AsciiCharacter
        {
            get
            {
                int t = rand.Next(10);
                if (t <= 2)
                    // returns a number
                    return (char)('0' + rand.Next(10));
                else if (t <= 4)
                    // small letter
                    return (char)('a' + rand.Next(27));
                else if (t <= 6)
                    // capital letter
                    return (char)('A' + rand.Next(27));
                else
                    // any ascii character
                    return (char)(rand.Next(32, 255));
            }
        }

        // methods
        static void Main()
        {
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.WindowLeft = Console.WindowTop = 0;
            Console.WindowHeight = Console.BufferHeight = Console.LargestWindowHeight;
            Console.WindowWidth = Console.BufferWidth = Console.LargestWindowWidth;
            Console.WriteLine("Hit Any Key To Continue");
            Console.ReadKey();
            Console.CursorVisible = false;
            
            int width, height;
            // setup array of starting y values
            int[] y;

            // width was 209, height was 81
            // setup the screen and initial conditions of y
            Initialize(out width, out height, out y);

            // do the Matrix effect
            // every loop all y's get incremented by 1
            while ( true )
                UpdateAllColumns(width, height, y);
        }

        
        private static void UpdateAllColumns(int width, int height, int[] y)
        {
            int x;
            // draws 3 characters in each x column each time... 
            // a dark green, light green, and a space

            // y is the position on the screen
            // y[x] increments 1 each time so each loop does the same thing but down 1 y value
            for ( x = 0 ; x < width ; ++x )
            {
                // the bright green character
                Console.ForegroundColor = ConsoleColor.Green;
                Console.SetCursorPosition(x, y[x]);
                Console.Write(AsciiCharacter);

                // the dark green character -  2 positions above the bright green character
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                int temp = y[x] - 2;
                Console.SetCursorPosition(x, inScreenYPosition(temp, height));
                Console.Write(AsciiCharacter);

                // the 'space' - 20 positions above the bright green character
                int temp1 = y[x] - 20;
                Console.SetCursorPosition(x, inScreenYPosition(temp1, height));
                Console.Write(' ');

                // increment y
                y[x] = inScreenYPosition(y[x] + 1, height);
            }

            // F5 to reset, F11 to pause and unpause
            if (Console.KeyAvailable)
            {
                if (Console.ReadKey().Key == ConsoleKey.F5)
                    Initialize(out width, out height, out y);
                if (Console.ReadKey().Key == ConsoleKey.F11)
                    System.Threading.Thread.Sleep(1);
            }

        }

        // Deals with what happens when y position is off screen
        public static int inScreenYPosition(int yPosition, int height)
        {
            if (yPosition < 0)
                return yPosition + height;
            else if (yPosition < height)
                return yPosition;
            else
                return 0;
        }

        // only called once at the start
        private static void Initialize(out int width, out int height, out int[] y)
        {
            height = Console.WindowHeight;
            width = Console.WindowWidth - 1;

            // 209 for me.. starting y positions of bright green characters
            y = new int[width];
            
            Console.Clear();
            // loops 209 times for me
            for ( int x = 0 ; x < width ; ++x )
            {
                // gets random number between 0 and 81
                y[x] = rand.Next(height);
            }
        }
    }
}

how it works:

The screen draws each column.. my screen is 208 wide.. so it loops 208 times, each time drawing a bright green character, dark green character, and a space.



The second loop.. the y value has been incremented by 1.



The 3rd loop



Enjoy!