from machine import Pin, I2C
import ssd1306
import time
import framebuf
import random
i2c= I2C(0, scl=Pin(1), sda= Pin(0))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
button_left = Pin(27, Pin.IN, Pin.PULL_DOWN)
button_right = Pin(26, Pin.IN, Pin.PULL_DOWN)
button_rotate = Pin(22, Pin.IN, Pin.PULL_DOWN)
button_down = Pin(21, Pin.IN, Pin.PULL_DOWN)
WIDTH = 10
HEIGHT = 20
BLOCK_SIZE = 3 # Tamaño del bloque en píxeles
pieces = [
[[1, 1, 1, 1]], # Línea
[[1, 1, 0], [0, 1, 1]], # Z
[[0, 1, 1], [1, 1, 0]], # S
[[1, 1], [1, 1]], # Cuadrado
[[1, 1, 1], [0, 1, 0]], # T
[[1, 1, 1], [1, 0, 0]], # L
[[1, 1, 1], [0, 0, 1]], # J
]
# Estado inicial del juego
board = [[0] * WIDTH for _ in range(HEIGHT)]
current_piece = random.choice(pieces)
piece_x, piece_y = 3, 0 # Posición inicial de la pieza
def draw_board():
oled.fill(0)
for y in range(HEIGHT):
for x in range(WIDTH):
if board[y][x]:
oled.fill_rect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, 1)
draw_piece(piece_x, piece_y, current_piece)
oled.show()
def draw_piece(px, py, piece):
for y, row in enumerate(piece):
for x, cell in enumerate(row):
if cell:
oled.fill_rect((px + x) * BLOCK_SIZE, (py + y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, 1)
def rotate_piece(piece):
return [list(row) for row in zip(*piece[::-1])]
def can_move(px, py, piece):
for y, row in enumerate(piece):
for x, cell in enumerate(row):
if cell:
new_x = px + x
new_y = py + y
if new_x < 0 or new_x >= WIDTH or new_y >= HEIGHT:
return False
if new_y >= 0 and board[new_y][new_x]:
return False
return True
def merge_piece(px, py, piece):
for y, row in enumerate(piece):
for x, cell in enumerate(row):
if cell:
board[py + y][px + x] = 1
def clear_lines():
global board
board = [row for row in board if any(cell == 0 for cell in row)]
lines_cleared = HEIGHT - len(board)
board = [[0] * WIDTH for _ in range(lines_cleared)] + board
def game_loop():
global piece_x, piece_y, current_piece
last_drop_time = time.ticks_ms()
drop_interval = 1000 # Intervalo de caída de la pieza en milisegundos
while True:
# Mover pieza lateralmente
if button_left.value() and can_move(piece_x - 1, piece_y, current_piece):
piece_x -= 1
elif button_right.value() and can_move(piece_x + 1, piece_y, current_piece):
piece_x += 1
# Rotar la pieza
if button_rotate.value():
rotated_piece = rotate_piece(current_piece)
if can_move(piece_x, piece_y, rotated_piece):
current_piece = rotated_piece
# Acelerar la caída con el botón abajo
if button_down.value():
drop_interval = 100
else:
drop_interval = 500
# Control de caída automática de la pieza
if time.ticks_diff(time.ticks_ms(), last_drop_time) > drop_interval:
if can_move(piece_x, piece_y + 1, current_piece):
piece_y += 1
else:
merge_piece(piece_x, piece_y, current_piece)
clear_lines()
piece_x, piece_y = 3, 0
current_piece = random.choice(pieces)
if not can_move(piece_x, piece_y, current_piece):
oled.fill(0)
oled.text("Game Over", 20, 30)
oled.show()
break
last_drop_time = time.ticks_ms()
# Dibujar el tablero y la pieza
draw_board()
time.sleep(0.1)
game_loop()