Skip to content

Instantly share code, notes, and snippets.

@ScienceElectronicsFun
Created July 5, 2021 02:22
Show Gist options
  • Save ScienceElectronicsFun/aa84ac095d66a1f6e114c0cbc9aa4a58 to your computer and use it in GitHub Desktop.
Save ScienceElectronicsFun/aa84ac095d66a1f6e114c0cbc9aa4a58 to your computer and use it in GitHub Desktop.
BrickOBlox v0.2
#Version 0.2
#Different color bricks now supported.
import random
import serial
import time
u = serial.Serial("COM13", baudrate=9600, timeout=10)
class block():
def __init__(self):
self.generate_block()
self.location = [8, 1]
def generate_block(self):
'''
Generate block of random type and color.
Returns block matrix and color.
'''
self.block_type = random.randint(0,5)
c = random.randint(1,3)
self.color = c
if self.block_type == 0:
self.block = [[c,c,c],
[c,c,c],
[c,c,c]]
self.rotated = self.block
elif self.block_type == 1:
self.block = [[c,0,0],
[c,c,0],
[c,c,c]]
self.rotated = [[c,c,c],
[0,c,c],
[0,0,c]]
elif self.block_type == 2:
self.block = [[c],
[c],
[c]]
self.rotated = [[c,c,c]]
elif self.block_type == 3:
self.block = [[c],
[c],
[c],
[c]]
self.rotated = [[c,c,c,c]]
elif self.block_type == 4:
self.block = [[c,c],
[c,c]]
self.rotated = self.block
elif self.block_type == 5:
self.block = [[c,c,0],
[0,c,c]]
self.rotated = [[0,c],
[c,c],
[c,0]]
def rotate(self):
temp = self.block
self.block = self.rotated
self.rotated = temp
def check_collision(self, m):
'''
Checks to see if the forward face of the block touches an element
of given matrix object 'm'.
'''
collision = False
x = self.location[0]
y = self.location[1]
for i, row in enumerate(self.block):
#print(row)
furthest = 0
#In the block, find the furthest to the right it extends to.
for j, col in enumerate(row):
if self.block[i][j] > 0:
furthest = j
#Furthest is j
#Now, does the matrix have a block in the next position?
if m.data[i+x][furthest+y+1] > 0:
collision = True
break
return collision
def generate_merge(self, m):
'''
Adds the block to the given matrix object 'm' for display purposes.
'''
x = self.location[0]
y = self.location[1]
c = self.color
for i, row in enumerate(self.block):
for j, col in enumerate(row):
if self.block[i][j] > 0:
m.data[x+i][y+j] = c
def subtract(self, m):
'''
Removes the block from the given matrix object 'm'.
This is done prior to moving the block to a new location.
'''
x = self.location[0]
y = self.location[1]
for i, row in enumerate(self.block):
for j, col in enumerate(row):
if self.block[i][j] > 0:
m.data[x+i][y+j] = 0
class matrix():
'''
The matrix class is a 16 (row) x 32 (column) matrix where 0 = off and 1 = on.
The translate function converts to a stream of 256 bytes that can be sent to the '8051 driver
to display the pattern on the RGB LED matrix.
'''
def __init__(self):
r = [0 for i in range(0, 32)]
#self.data initializes to an empty matrix.
self.data = [list(r) for i in range(0, 16)]
self.stream = None
self.bytes = None
self.max = 25
self.color_map = {1:(2, 1),
2:(8, 4),
3:(64, 32)}
def check_for_full_cols(self):
full_col_list = []
for i in range(0, self.max):
if all([x[i] for x in self.data]):
full_col_list.append(i)
for col in full_col_list:
for k in range(0, 16):
for j in range(1,i+1):
self.data[k][j] = self.data[k][j-1]
def translate(self):
#Translates pattern to byte stream to drive the RGB LED matrix.
self.stream = [0 for i in range(0,256)]
#Top half
for k in range(0, 8):
for i, member in enumerate(self.data[k]):
if member > 0:
self.stream[223-i-k*32] += self.color_map[member][0]
#Bottom half
for k in range(8, 16):
for i, member in enumerate(self.data[k]):
if member > 0:
self.stream[223-i-((k-8)*32)] += self.color_map[member][1]
self.bytes = ''
#Convert to hex
for byte in self.stream:
self.bytes += chr(byte)
def dump_matrix(self):
'''
Prints matrix object for debugging.
'''
print()
for row in self.data:
print(''.join([str(x) for x in row]))
print()
def readfile(filename):
'''
Reads a csv file matrix object.
Returns grid which can be loaded into m.data.
'''
file_r = open(filename, 'r')
data = file_r.readlines()
grid = []
for line in data:
newline = [int(x.strip()) for x in line.split(',')]
grid.append(newline)
return grid
def start_game():
m = matrix()
# This sets bottom brick layer
t = 25
for i in range(0,16):
m.data[i][t] = 1
m.translate()
game_running = True
points = 0
while game_running:
m.check_for_full_cols()
#Start new round
round_running = True
b = block()
c = b.check_collision(m)
if c:
game_running = False
round_running = False
while round_running:
#Display the new block
b.generate_merge(m)
m.translate()
u.write('\x10'.encode())
u.write(m.bytes.encode())
time.sleep(0.01)
c = b.check_collision(m)
if c:
round_running = False
if round_running:
b.subtract(m)
#Move the block to the right
b.location[1] = b.location[1] + 1
#If command pending, move
u.write('\x11'.encode())
current = u.read()
if current == bytes(chr(2).encode()):
b.location[0] += 1
if current == bytes(chr(4).encode()):
b.location[0] -= 1
if current == bytes(chr(8).encode()):
b.rotate()
if current == bytes(chr(16).encode()):
b.location[0] -= 2
start_game()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment