Toggle Navigation
Hatchery
Eggs
Tetris
tetris.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
tetris.py
raw
Content
import time, urandom, system, orientation, display, buttons orientation.portrait() display.drawFill(0x000000) display.flush() display.drawFill(0xFFFFFF) display.flush() display.drawFill(0x000000) display.flush() display.drawFill(0xFFFFFF) display.flush() class Tetris: def __init__(self): self.font = "roboto_regular18" self.game_step_time = 500 # nr of unique rotations per piece self.piece_rotations = [1, 2, 2, 2, 4, 4, 4] # Piece data: [piece_nr * 32 + rot_nr * 8 + brick_nr * 2 + j] # with rot_nr between 0 and 4 # with the brick number between 0 and 4 # and j == 0 for X coord, j == 1 for Y coord self.piece_data = [ # square block 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # line block 0, 0, -2, 0, -1, 0, 1, 0, 0, 0, 0, 1, 0, -1, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # S-block 0, 0, -1, -1, 0, -1, 1, 0, 0, 0, 0, 1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # Z-block 0, 0, -1, 0, 0, -1, 1, -1, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, # L-block 0, 0, -1, 0, -1, -1, 1, 0, 0, 0, 0, 1, 0, -1, 1, -1, 0, 0, -1, 0, 1, 0, 1, 1, 0, 0, -1, 1, 0, 1, 0, -1, # J-block 0, 0, -1, 0, 1, 0, 1, -1, 0, 0, 0, 1, 0, -1, 1, 1, 0, 0, -1, 1, -1, 0, 1, 0, 0, 0, 0, 1, 0, -1, -1, -1, # T-block 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0, -1, 1, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, 0, -1, 0, 0, 1, 0, -1 ] display.drawFill(0xFFFFFF) self.draw_field_lines() display.flush() buttons.attach(buttons.BTN_UP,lambda pressed: self.btn_up(pressed)) buttons.attach(buttons.BTN_DOWN,lambda pressed: self.btn_down(pressed)) buttons.attach(buttons.BTN_LEFT,lambda pressed: self.btn_left(pressed)) buttons.attach(buttons.BTN_RIGHT,lambda pressed: self.btn_right(pressed)) buttons.attach(buttons.BTN_SELECT,lambda pressed: self.btn_select(pressed)) buttons.attach(buttons.BTN_START,lambda pressed: self.btn_start(pressed)) buttons.attach(buttons.BTN_A,lambda pressed: self.btn_a(pressed)) buttons.attach(buttons.BTN_B,lambda pressed: self.btn_b(pressed)) self.game_init() self.draw_updated_score() while True: self.game_update() self.draw() def game_init(self): # Init game state self.spawn_new_piece() self.field = [[0 for i in range(10)] for j in range(20)] self.last_update = time.ticks_ms() self.score = 0 def spawn_new_piece(self): self.piece_type = urandom.getrandbits(8) % 7 self.piece_x = 4 self.piece_y = 0 self.piece_rot = 0 def game_update(self): cur_ticks = time.ticks_ms() if cur_ticks - self.last_update > self.game_step_time: # Move piece down self.lower_piece() self.last_update = cur_ticks def rotate_piece(self): self.piece_rot += 1 if self.piece_rot >= self.piece_rotations[self.piece_type]: self.piece_rot = 0 def is_side_collision(self): for square in range(4): x_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 0] y_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 1] abs_x = self.piece_x + x_off abs_y = self.piece_y + y_off # collision with walls if abs_x < 0 or abs_x >= 10: return True # collision with field blocks if self.field[abs_y][abs_x]: return True return False def move_left(self): self.piece_x -= 1 # check collision with walls if self.is_side_collision(): self.piece_x += 1 def move_right(self): self.piece_x += 1 # check collision with walls if self.is_side_collision(): self.piece_x -= 1 def lower_piece(self): self.piece_y += 1 # check for collisions collision = False for square in range(4): x_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 0] y_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 1] abs_x = self.piece_x + x_off abs_y = self.piece_y + y_off try: if abs_y >= 20 or self.field[abs_y][abs_x]: collision = True break except: print("Out-of-bounds?!") pass if collision: # if at the top, game over if self.piece_y == 1: self.draw_game_over() time.sleep(10) self.game_init() # add to field self.piece_y -= 1 for square in range(4): x_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 0] y_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 1] abs_x = self.piece_x + x_off abs_y = self.piece_y + y_off self.field[abs_y][abs_x] = True # check for line clears self.check_for_filled_lines() # Spawn new piece self.spawn_new_piece() def check_for_filled_lines(self): for row in range(20): fill_count = 0 for column in range(10): fill_count += self.field[row][column] if fill_count == 10: # Increase score self.score += 1 self.draw_updated_score() # Remove line for row2 in range(row, 0, -1): for column2 in range(10): self.field[row2][column2] = self.field[row2-1][column2] def draw(self): self.draw_field() self.draw_current_piece() display.flush(display.FLAG_LUT_FASTEST) def draw_updated_score(self): display.drawRect(0, display.height()-20, display.width(), 20, True, 0xFFFFFF) display.drawText(10, display.height()-20, "Score: {:04d}".format(self.score), 0x000000, self.font) def draw_game_over(self): display.drawFill(0xFFFFFF) display.drawText(0, 0, "GAME OVER :(") display.flush() def draw_field_lines(self): display.drawRect(10, 10, 100, 200, False, 0x000000) #for column in range(10): # display.drawLine(10 + 10 * column, 10, 10 + 10 * column, 210, 0x000000) #for row in range(20): # display.drawLine(10, 10 + 10 * row, 110, 10 + 10 * row, 0x000000) def draw_field(self): for column in range(10): for row in range(20): self.draw_square(row, column, self.field[row][column]) self.draw_field_lines() def draw_current_piece(self): for square in range(4): # [piece_nr * 32 + rot_nr * 8 + brick_nr * 2 + j] x_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 0] y_off = self.piece_data[self.piece_type * 32 + self.piece_rot * 8 + square * 2 + 1] abs_x = self.piece_x + x_off abs_y = self.piece_y + y_off self.draw_square(abs_y, abs_x, True) def draw_square(self, row, column, filled=True): if row < 0 or column < 0 or row >= 20 or column >= 10: return display.drawRect(10 + 10 * column, 200 - 10 * (19-row), 10, 10, False, 0x000000 if filled else 0xFFFFFF) def btn_a(self,pressed): if pressed: print("Rotating piece") self.rotate_piece() def btn_b(self,pressed): if pressed: print("Rotating piece") self.rotate_piece() def btn_left(self,pressed): if pressed: print("Moving piece left") self.move_left() def btn_right(self,pressed): if pressed: print("Moving piece right") self.move_right() def btn_down(self,pressed): if pressed: print("Moving piece down") self.lower_piece() def btn_up(self,pressed): if pressed: print("Rotating piece") self.rotate_piece() def btn_start(self,pressed): if pressed: print("Returning to homescreen") system.home() def btn_select(self,pressed): if pressed: print("Resetting game") self.game_init() tetris = Tetris()