master
1#!/usr/bin/env python
2
3import RPi.GPIO as GPIO
4import opc
5import time
6import random
7
8# Define channel numbers for red, blue and green buttons
9# Uses GPIO.BOARD numbering
10GPIO.setmode(GPIO.BOARD)
11BUTTON_RED = 11
12BUTTON_GREEN = 12
13BUTTON_BLUE = 13
14
15# Define info for Fadecandy
16LED_STRING_LEN = 192
17FLASH_CHANNELS = [0]
18
19# Setup GPIO
20for button in [BUTTON_RED, BUTTON_BLUE, BUTTON_GREEN]:
21 GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
22
23pixels = [(0, 0, 0)] * LED_STRING_LEN
24
25leds = opc.Client('localhost:7890')
26
27RED = (35,0,0)
28GREEN = (0,35,0)
29BLUE = (0,0,35)
30
31LIFESPAN = 500
32
33d = (8,24)
34
35def zero_matrix():
36 return [(0, 0, 0)] * LED_STRING_LEN
37
38def max_matrix():
39 return [(100, 100, 100)] * LED_STRING_LEN
40
41def color_matrix(color):
42 color = tuple(2*x for x in color)
43 return [color] * LED_STRING_LEN
44
45
46def board_to_array(dimensions,board,color):
47 p = [(0, 0, 0)] * LED_STRING_LEN
48 for i in board:
49 index = (dimensions[0]*i[0])+i[1]
50 p[index] = color
51
52 return p
53
54def random_board(dimensions):
55 i,j = 0,0
56 board = set([])
57 for i in xrange(0,dimensions[1]):
58 for j in xrange(0,dimensions[0]):
59 if random.randint(0,1):
60 board.add((i,j))
61 return board
62
63def neighbors(dimensions,cell):
64 x, y = cell
65 yield (x - 1) % dimensions[1], (y - 1) % dimensions[0]
66 yield x % dimensions[1], (y - 1) % dimensions[0]
67 yield (x + 1) % dimensions[1], (y - 1) % dimensions[0]
68 yield (x - 1) % dimensions[1], y % dimensions[0]
69 yield (x + 1) % dimensions[1], y % dimensions[0]
70 yield (x - 1) % dimensions[1], (y + 1) % dimensions[0]
71 yield x % dimensions[1], (y + 1) % dimensions[0]
72 yield (x + 1) % dimensions[1], (y + 1) % dimensions[0]
73
74def apply_iteration(dimensions, board):
75 new_board = set([])
76 candidates = board.union(set(n for cell in board for n in neighbors(dimensions,cell)))
77 for cell in candidates:
78 count = sum((n in board) for n in neighbors(dimensions,cell))
79 if count == 3 or (count == 2 and cell in board):
80 new_board.add((cell[0]%dimensions[1],cell[1]%dimensions[0]))
81 return new_board
82
83def add_arrays(alpha,beta):
84 return [(a[0]+b[0], a[1]+b[1], a[2]+b[2]) for a,b in zip(alpha,beta)]
85
86
87display_boards = []
88glider = {(0,1), (1,2), (2,0), (2,1), (2,2)}
89display_boards.append((glider,(100,100,100),1000000))
90display_boards.append((random_board(d),RED,150))
91display_boards.append((random_board(d),GREEN,300))
92display_boards.append((random_board(d),BLUE,LIFESPAN))
93while True:
94 if random.randint(0,40) == 1:
95 spawn = random.randint(0,2)
96 if spawn == 0: display_boards.append((random_board(d),RED,LIFESPAN))
97 if spawn == 1: display_boards.append((random_board(d),GREEN,LIFESPAN))
98 if spawn == 2: display_boards.append((random_board(d),BLUE,LIFESPAN))
99
100 # Note that buttons are inverted: GPIO.input() returns 1 if the button
101 # is not pressed, 0 if it is pressed
102 if GPIO.input(BUTTON_RED) == 0:
103 display_boards.append((random_board(d),RED,LIFESPAN))
104 if GPIO.input(BUTTON_GREEN) == 0:
105 display_boards.append((random_board(d),GREEN,LIFESPAN))
106 if GPIO.input(BUTTON_BLUE) == 0:
107 display_boards.append((random_board(d),BLUE,LIFESPAN))
108 if GPIO.input(BUTTON_RED) == 0 and GPIO.input(BUTTON_BLUE) == 0 and GPIO.input(BUTTON_GREEN) == 0:
109 print "all pressed, resetting"
110 display_boards = []
111 display_boards.append((glider,(100,100,100),1000000))
112
113 display_array = zero_matrix()
114 i = 0
115 for db in display_boards:
116 if db[2] < 0:
117 display_boards.pop(i)
118 continue
119 if not bool(db[0]):
120 display_boards.pop(i)
121 continue
122 display_array = add_arrays(display_array,board_to_array(d,db[0],db[1]))
123 display_boards[i] = (apply_iteration(d,db[0]), db[1], db[2]-1)
124 i+=1
125 leds.put_pixels(display_array,0)
126 time.sleep(.2)