Created
July 5, 2021 02:22
-
-
Save ScienceElectronicsFun/aa84ac095d66a1f6e114c0cbc9aa4a58 to your computer and use it in GitHub Desktop.
BrickOBlox v0.2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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