#include <LedControl.h>
// Pines de la matriz LED
const int DIN_PIN = 11;
const int CS_PIN = 10;
const int CLK_PIN = 13;
LedControl lc = LedControl(DIN_PIN, CLK_PIN, CS_PIN, 1);
// Pines de los botones
const int BTN_LEFT = 2;
const int BTN_RIGHT = 3;
const int BTN_ROT = 4;
const int BTN_DOWN = 5;
// Variables de estado de botones para evitar rebotes (debounce)
bool lastLeft = HIGH, lastRight = HIGH, lastRot = HIGH, lastDown = HIGH;
// Tablero de 8x8 (0 = vacío, 1 = ocupado)
byte board[8] = {0,0,0,0,0,0,0,0};
// Definición de piezas básicas (Simplificadas para 8x8)
// 0: Cuadrado (O), 1: Línea (I), 2: L, 3: T
const byte pieces[4][4][2] = {
{{0x03, 0x03}, {0x03, 0x03}, {0x03, 0x03}, {0x03, 0x03}}, // Cuadrado
{{0x0F, 0x00}, {0x01, 0x01}, {0x0F, 0x00}, {0x01, 0x01}}, // Línea (horizontal/vertical)
{{0x07, 0x01}, {0x03, 0x02}, {0x04, 0x07}, {0x01, 0x03}}, // L
{{0x07, 0x02}, {0x02, 0x03}, {0x02, 0x07}, {0x03, 0x02}} // T
};
int currentPiece;
int currentRot;
int pieceX, pieceY;
unsigned long lastDropTime = 0;
int dropSpeed = 500; // Velocidad de caída en ms
void setup() {
lc.shutdown(0, false); // Despertar la matriz
lc.setIntensity(0, 8); // Brillo medio
lc.clearDisplay(0);
pinMode(BTN_LEFT, INPUT_PULLUP);
pinMode(BTN_RIGHT, INPUT_PULLUP);
pinMode(BTN_ROT, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
randomSeed(analogRead(0));
spawnPiece();
}
void loop() {
handleInput();
if (millis() - lastDropTime > dropSpeed) {
if (!movePiece(0, 1)) {
lockPiece();
checkLines();
spawnPiece();
}
lastDropTime = millis();
}
drawBoard();
}
void spawnPiece() {
currentPiece = random(0, 4);
currentRot = 0;
pieceX = 3;
pieceY = 0;
// Si colisiona al nacer, el juego termina (reiniciamos)
if (checkCollision(pieceX, pieceY, currentRot)) {
memset(board, 0, sizeof(board)); // Limpia el tablero
lc.clearDisplay(0);
delay(500);
}
}
void handleInput() {
bool left = digitalRead(BTN_LEFT);
bool right = digitalRead(BTN_RIGHT);
bool rot = digitalRead(BTN_ROT);
bool down = digitalRead(BTN_DOWN);
if (left == LOW && lastLeft == HIGH) movePiece(-1, 0);
if (right == LOW && lastRight == HIGH) movePiece(1, 0);
if (rot == LOW && lastRot == HIGH) {
int nextRot = (currentRot + 1) % 4;
if (!checkCollision(pieceX, pieceY, nextRot)) {
currentRot = nextRot;
}
}
if (down == LOW && lastDown == HIGH) movePiece(0, 1);
lastLeft = left;
lastRight = right;
lastRot = rot;
lastDown = down;
delay(50); // Pequeño delay para el debounce
}
bool movePiece(int dx, int dy) {
if (!checkCollision(pieceX + dx, pieceY + dy, currentRot)) {
pieceX += dx;
pieceY += dy;
return true;
}
return false;
}
bool checkCollision(int x, int y, int rot) {
for (int row = 0; row < 2; row++) {
byte pRow = pieces[currentPiece][rot][row];
for (int col = 0; col < 4; col++) {
if (pRow & (1 << col)) { // Si hay un bloque en la pieza
int boardX = x + col;
int boardY = y + row;
// Choca con los bordes
if (boardX < 0 || boardX >= 8 || boardY >= 8) return true;
// Choca con piezas fijas
if (boardY >= 0 && (board[boardY] & (1 << (7 - boardX)))) return true;
}
}
}
return false;
}
void lockPiece() {
for (int row = 0; row < 2; row++) {
byte pRow = pieces[currentPiece][currentRot][row];
for (int col = 0; col < 4; col++) {
if (pRow & (1 << col)) {
int boardX = pieceX + col;
int boardY = pieceY + row;
if (boardY >= 0) {
board[boardY] |= (1 << (7 - boardX));
}
}
}
}
}
void checkLines() {
for (int i = 7; i >= 0; i--) {
if (board[i] == 0xFF) { // Fila llena
// Bajar todas las filas de arriba
for (int j = i; j > 0; j--) {
board[j] = board[j-1];
}
board[0] = 0;
i++; // Volver a revisar la misma fila por si bajó otra llena
delay(100); // Efecto visual simple
}
}
}
void drawBoard() {
byte display[8];
for (int i = 0; i < 8; i++) display[i] = board[i];
// Dibujar la pieza cayendo
for (int row = 0; row < 2; row++) {
byte pRow = pieces[currentPiece][currentRot][row];
for (int col = 0; col < 4; col++) {
if (pRow & (1 << col)) {
int boardX = pieceX + col;
int boardY = pieceY + row;
if (boardY >= 0 && boardY < 8) {
display[boardY] |= (1 << (7 - boardX));
}
}
}
}
// Enviar a la matriz
for (int i = 0; i < 8; i++) {
lc.setRow(0, i, display[i]);
}
}