# J-Trix

Recreating the famous falling bit effect from Matrix using python and curses.
The individual bit strips are separate entities, falling to the bottom and then being moved up again with a different x value. They also get a random speed between one and five deciseconds.

``````# Python 2.7.7 Code
# Jonathan Frech 7th of September, 2016
#         edited 8th of September, 2016
#         edited 9th of September, 2016``````

``````# import
import curses, random, time

# set the cursor's visibility (sometimes does not work on Mac OS)
def curs_set(bool):
try:
curses.curs_set(bool)
except:
pass

# add a string at (y, x) with color on scr without any errors
def addstr(scr, y, x, string, color = 0):
my, mx = scr.getmaxyx()
if y >= 0 and x >= 0 and y < my and x < mx and not (x == mx-1 and y == my-1):

# init
def init():
global scr, t, my, mx

# screen
scr = curses.initscr()
scr.nodelay(True)

# curses
curses.noecho()
curses.cbreak()
curs_set(False)
curses.start_color()
curses.use_default_colors()

# color used
#curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK)
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)

# screen size
my, mx = scr.getmaxyx()

# ticks
t = 0

# run
def run():
global scr, seed, t, my, mx

# init
init()

# strips
strips = [strip() for _ in range(0, 100)]

# while loop
while True:
# render strips
for s in strips:
s.render()

# new strip
if s.out:
strips.remove(s)
strips.append(strip(top = True))

# get char (nodelay mode!)
c = scr.getch()

# quit
if c == curses.KEY_F12:
break

# sleep
time.sleep(.1)

# handle resizement
if curses.is_term_resized(my, mx):
# update screen size
my, mx = scr.getmaxyx()

# reset
strips = [strip() for _ in range(0, 100)]

# clear
scr.clear()

# one more tick
t += 1

# cleanup
cleanup()

# cleanup
def cleanup():
curses.echo()
curses.nocbreak()
curs_set(True)
curses.endwin()

# get a random character (string with lengh one)
def char():
#s = "+-*%/&"
s = "01"
return s[random.randint(0, len(s)-1)]

# strip class
class strip():
# init
def __init__(self, top = False):
global scr

# defin pos, length and speed
my, mx = scr.getmaxyx()
self.pos = [random.randint(0, my-2), random.randint(0, mx-1)]
self.length = random.randint(3, 10)
if top:
self.pos[0] = -self.length
self.speed = random.randint(1, 5)

# outside screen?
self.out = False

# render
def render(self):
global scr

# render individual chars
for Y in range(-1, self.length):
y, x = self.pos[0]+Y, self.pos[1]
addstr(scr, y, x, [char(), " "][Y == -1], curses.color_pair(1))

# screen size
my, mx = scr.getmaxyx()

# move down
if t % self.speed == 0:
self.pos[0] += 1
if self.pos[0] > my or self.pos[1] > mx:
self.out = True

# move cursor
scr.move(my-1, mx-1)

# run animation
run()``````