#include <Wire.h> #include <LiquidCrystal_I2C.h> ...

創建於:2025年11月20日

使用 GPT-5.1 Thinking 回答 Chat01

問題

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Endereço padrão do display I2C (pode variar, normalmente é 0x27 ou 0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Pinos dos componentes
int led1 = 10;
int led2 = 3;
int led3 = 4;
int led4 = 2;
int bt4 = 7;
int bt2 = 6;
int bt3 = 5;
int bt1 = 9;
int bz = 8;

int padraoLed[50];
int rodadaAtual = 1;

void setup() {
// Inicializa comunicação serial
Serial.begin(9600);

// Inicializa o LCD
lcd.init();
lcd.setBacklight(HIGH);

randomSeed(analogRead(A0));

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);

pinMode(bt1, INPUT);
pinMode(bt2, INPUT);
pinMode(bt3, INPUT);
pinMode(bt4, INPUT);

pinMode(bz, OUTPUT);

lcd.setCursor(0, 0);
lcd.print("Genius!");
delay(1500);
}

void loop() {

MostraSequencia(rodadaAtual);

bool acertou = LerJogador(rodadaAtual);

if (acertou) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Acertou! Prox.");
rodadaAtual++; // Aumenta o nível
delay(1500);
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ERROU! Fim Jogo");
tone(bz, 150, 1000);
delay(2000);
lcd.clear();
lcd.print("Rodada: ");
lcd.print(rodadaAtual - 1);
delay(3000);
rodadaAtual = 1;
}
}

void MostraSequencia(int nRodada) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Observe...");

// Adiciona um novo passo aleatório à sequência (se for a primeira vez nesta rodada)
// Nota: Esta lógica é para um Genius que adiciona um passo a cada rodada.
// Se você quiser uma sequência nova a cada 3 rodadas, a lógica do loop() precisa mudar.
// Vou assumir que você quer que a sequência cresça.

padraoLed[nRodada - 1] = random(1, 5);
for (int i = 0; i < nRodada; i++) {
delay(400); // Pausa entre as luzes

text
switch (padraoLed[i]) { case 1: digitalWrite(led1, HIGH); tone(bz, 262, 200); // Dó delay(500); digitalWrite(led1, LOW); break; case 2: digitalWrite(led2, HIGH); tone(bz, 294, 200); // Ré delay(500); digitalWrite(led2, LOW); break; case 3: digitalWrite(led3, HIGH); tone(bz, 330, 200); // Mi delay(500); digitalWrite(led3, LOW); break; case 4: digitalWrite(led4, HIGH); tone(bz, 349, 200); // Fá delay(500); digitalWrite(led4, LOW); break; }

}

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sua vez!");
}

// Esta função LÊ a resposta do jogador e retorna 'true' (acertou) ou 'false' (errou)
bool LerJogador(int nRodada) {
int passoAtual = 0; // Qual passo da sequência o jogador está

while (passoAtual < nRodada) {
int botaoPressionado = 0;

text
// Fica em loop ESPERANDO o jogador apertar um botão while (botaoPressionado == 0) { if (digitalRead(bt1) == HIGH) { botaoPressionado = 1; digitalWrite(led1, HIGH); // Acende o LED correspondente tone(bz, 262, 150); delay(250); // Debounce (evita leitura dupla) digitalWrite(led1, LOW); } else if (digitalRead(bt2) == HIGH) { botaoPressionado = 2; digitalWrite(led2, HIGH); tone(bz, 294, 150); delay(250); digitalWrite(led2, LOW); } else if (digitalRead(bt3) == HIGH) { botaoPressionado = 3; digitalWrite(led3, HIGH); tone(bz, 330, 150); delay(250); digitalWrite(led3, LOW); } else if (digitalRead(bt4) == HIGH) { botaoPressionado = 4; digitalWrite(led4, HIGH); tone(bz, 349, 150); delay(250); digitalWrite(led4, LOW); } } // Fim do while (espera) // Agora que o botão foi pressionado, compara com a sequência if (botaoPressionado == padraoLed[passoAtual]) { // Acertou este passo, vamos para o próximo passoAtual++; } else { // Errou! return false; // Retorna 'false' (errou) e sai da função } delay(100); // Pequena pausa antes de ler o próximo botão

}

// Se o loop 'while (passoAtual < nRodada)' terminar, é porque o jogador acertou todos
return true; // Retorna 'true' (acertou tudo)

quero que baseado em todas as capacidades e limitações desse codigo e sistema de arduino, crie 4 jogos que serão escolhidos quando o arduino iniciar, um em cada botao, o primeiro jogo é o que ja esta presenet nesse codigo, o segundo quero que adapte uma especie de jogo do dinossauro do google, para o lcd 16/2 de forma simplificada, porem totalmente funcional, respeitando as limitações que o sistema fisico possui, o terceiro e quarto ficam por seu criterio, quero algo extremamente criativo, não quero copias dos jogos ja implementados, e sim algo novo e criativo, nada como um simples teclado que faz som ao clicar no respectivo botao, e sim algo maior e mais fucnional, lembre que o jogo do dinossauro qdeve seguir regras para tornalo cada vez mais dificil e não fazer com que ele pule infinitamente por ex, emfim use quantas linhas de codigo conseguir quanto mais melhor
}

思考

Verifying the code structure and readiness for explanation

Okay, I've double-checked the braces, functions, and variable types. I made sure the prototypes for MostraSequenciaGenius were declared before use. The reference arguments for encontrarInicioLabirinto were fine too, and everything seems to be in place for compiling with C++. I'll move on to providing the code and briefly explaining it to the user.

Thought for 4m 22s

回答

Segue um arcade completo com 4 jogos usando exatamente o teu hardware (4 botões, 4 LEDs, buzzer e LCD 16x2 I2C).

  • Jogo 1 (bt1) → Genius clássico (o teu jogo original, reorganizado).
  • Jogo 2 (bt2) → “Dino Runner” estilo dinossauro do Google, adaptado para LCD 16x2.
  • Jogo 3 (bt3) → “Reflex Master”: teste de reflexo com LEDs e botões.
  • Jogo 4 (bt4) → “Labirinto 16x2”: mini labirinto no LCD, você se move com os 4 botões.

Quando o Arduino liga, aparece um menu; cada botão escolhe um jogo.


Código completo (pode colar direto na IDE)

cpp
#include <Wire.h> #include <LiquidCrystal_I2C.h> // ----------------------------- // DEFINIÇÕES GERAIS // ----------------------------- LiquidCrystal_I2C lcd(0x27, 16, 2); // Pinos dos componentes (iguais ao seu código) const int led1 = 10; const int led2 = 3; const int led3 = 4; const int led4 = 2; const int bt4 = 7; const int bt2 = 6; const int bt3 = 5; const int bt1 = 9; const int bz = 8; // Estados de jogo enum GameId { GAME_MENU = 0, GAME_GENIUS = 1, GAME_DINO = 2, GAME_REFLEX = 3, GAME_MAZE = 4 }; int jogoAtual = GAME_MENU; // ----------------------------- // FUNÇÕES AUXILIARES GERAIS // ----------------------------- void apagaLeds() { digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); } void beepOk(int duracao = 120) { tone(bz, 800, duracao); } void beepErro(int duracao = 200) { tone(bz, 200, duracao); } bool botaoAtivo(int pin) { return digitalRead(pin) == HIGH; } // Espera TODOS os botões soltarem (evita cliques duplos) void esperaSoltarBotoes() { bool algumPressionado = true; while (algumPressionado) { algumPressionado = botaoAtivo(bt1) || botaoAtivo(bt2) || botaoAtivo(bt3) || botaoAtivo(bt4); delay(10); } } // Retorna 1..4 de acordo com o botão pressionado int lerBotaoJogo() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } delay(5); } } // ----------------------------- // JOGO 1 - GENIUS CLÁSSICO // ----------------------------- const int TAM_PADRAO = 50; int padraoLed[TAM_PADRAO]; void MostraSequenciaGenius(int nRodada); bool LerJogadorGenius(int nRodada); void iniciarGenius() { // Limpa padrão for (int i = 0; i < TAM_PADRAO; i++) { padraoLed[i] = 0; } int rodadaAtual = 1; bool jogando = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("GENIUS"); lcd.setCursor(0, 1); lcd.print("Boa sorte!"); delay(1500); while (jogando) { MostraSequenciaGenius(rodadaAtual); bool acertou = LerJogadorGenius(rodadaAtual); if (acertou) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Acertou a seq!"); lcd.setCursor(0, 1); lcd.print("Rodada: "); lcd.print(rodadaAtual); beepOk(); delay(1500); rodadaAtual++; if (rodadaAtual > TAM_PADRAO) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("VOCE ZEROU!"); lcd.setCursor(0, 1); lcd.print("Impressionante!"); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } delay(2500); jogando = false; } } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("ERROU! Fim Jogo"); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(rodadaAtual - 1); for (int i = 0; i < 3; i++) { beepErro(250); delay(250); } delay(3000); jogando = false; } } } void MostraSequenciaGenius(int nRodada) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Observe..."); // Adiciona um novo passo à sequência padraoLed[nRodada - 1] = random(1, 5); delay(1000); for (int i = 0; i < nRodada; i++) { delay(200); int passo = padraoLed[i]; int ledPin = led1; int freq = 262; // Do switch (passo) { case 1: ledPin = led1; freq = 262; break; // Do case 2: ledPin = led2; freq = 294; break; // Re case 3: ledPin = led3; freq = 330; break; // Mi case 4: ledPin = led4; freq = 349; break; // Fa } digitalWrite(ledPin, HIGH); tone(bz, freq, 200); delay(500); digitalWrite(ledPin, LOW); } lcd.clear(); lcd.setCursor(0, 0); lcd.print("Sua vez!"); } bool LerJogadorGenius(int nRodada) { int passoAtual = 0; while (passoAtual < nRodada) { int botaoPressionado = 0; while (botaoPressionado == 0) { if (botaoAtivo(bt1)) { botaoPressionado = 1; digitalWrite(led1, HIGH); tone(bz, 262, 150); delay(250); digitalWrite(led1, LOW); } else if (botaoAtivo(bt2)) { botaoPressionado = 2; digitalWrite(led2, HIGH); tone(bz, 294, 150); delay(250); digitalWrite(led2, LOW); } else if (botaoAtivo(bt3)) { botaoPressionado = 3; digitalWrite(led3, HIGH); tone(bz, 330, 150); delay(250); digitalWrite(led3, LOW); } else if (botaoAtivo(bt4)) { botaoPressionado = 4; digitalWrite(led4, HIGH); tone(bz, 349, 150); delay(250); digitalWrite(led4, LOW); } delay(5); } if (botaoPressionado == padraoLed[passoAtual]) { passoAtual++; } else { return false; } delay(100); } return true; } // ----------------------------- // JOGO 2 - DINO DO GOOGLE (LCD 16x2) // ----------------------------- // Mundo bem simples: dino em uma coluna fixa, obstáculos vindo da direita const int DINO_COL = 3; // Coluna fixa do dino const int MAX_OBSTACULOS = 5; // Quantos obstáculos simultâneos int obstCol[MAX_OBSTACULOS]; // Colunas dos obstáculos (0..15 ou -1) bool obstAtivo[MAX_OBSTACULOS]; bool dinoJumping = false; int dinoRow = 1; // 0 = linha de cima, 1 = linha de baixo int jumpPhase = 0; const int JUMP_FASES = 6; // Total de "frames" do pulo int jumpCooldownFrames = 0; // Quantos frames precisa ficar no chão antes de pular de novo bool bt1PrevState = false; void resetDinoEstado() { for (int i = 0; i < MAX_OBSTACULOS; i++) { obstCol[i] = -1; obstAtivo[i] = false; } dinoRow = 1; dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 0; bt1PrevState = false; } void spawnObstaculo() { // Só cria se houver algum slot livre for (int i = 0; i < MAX_OBSTACULOS; i++) { if (!obstAtivo[i]) { obstAtivo[i] = true; obstCol[i] = 15; // nasce na direita break; } } } void atualizaDinoPulo() { if (dinoJumping) { jumpPhase++; if (jumpPhase < JUMP_FASES / 2) { dinoRow = 0; // metade do pulo para cima } else { dinoRow = 1; // metade final já caindo } if (jumpPhase >= JUMP_FASES) { dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 2; // precisa de alguns frames no chão } } else { // dino no chão dinoRow = 1; if (jumpCooldownFrames > 0) { jumpCooldownFrames--; } } } bool checaColisaoDino() { for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] == DINO_COL && dinoRow == 1) { return true; } } return false; } void desenhaCenarioDino() { char linha0[17]; char linha1[17]; for (int i = 0; i < 16; i++) { linha0[i] = ' '; linha1[i] = '_'; // chão } // Obstáculos embaixo for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] >= 0 && obstCol[i] < 16) { linha1[obstCol[i]] = '|'; } } // Dino if (dinoRow == 0) { linha0[DINO_COL] = 'D'; } else { linha1[DINO_COL] = 'D'; } linha0[16] = '\0'; linha1[16] = '\0'; lcd.setCursor(0, 0); lcd.print(linha0); lcd.setCursor(0, 1); lcd.print(linha1); } void iniciarDino() { resetDinoEstado(); unsigned long ultimoFrame = millis(); int delayFrame = 180; // começa mais lento int nivelDificuldade = 1; int obstaculosCriados = 0; bool jogoRodando = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("DINO RUN LCD"); lcd.setCursor(0, 1); lcd.print("BT1 = PULAR"); delay(2000); lcd.clear(); while (jogoRodando) { // Leitura de botão de pulo (borda de subida) bool bt1Now = botaoAtivo(bt1); if (bt1Now && !bt1PrevState && !dinoJumping && jumpCooldownFrames == 0) { dinoJumping = true; jumpPhase = 0; tone(bz, 700, 80); } bt1PrevState = bt1Now; // Atualiza a cada "frame" if (millis() - ultimoFrame >= (unsigned long)delayFrame) { ultimoFrame = millis(); atualizaDinoPulo(); // Move obstáculos for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { obstCol[i]--; if (obstCol[i] < 0) { obstAtivo[i] = false; } } } // Criar novo obstáculo com probabilidade crescente, // mas garantindo distância mínima do último bool podeCriar = true; int distanciaMinima = 4; for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { if (obstCol[i] > 10) { // bem perto da borda direita ainda podeCriar = false; } } } int chance = 20 + nivelDificuldade * 3; // aumenta a chance com a dificuldade if (chance > 70) chance = 70; if (podeCriar && random(0, 100) < chance) { spawnObstaculo(); obstaculosCriados++; if (obstaculosCriados % 5 == 0) { nivelDificuldade++; if (delayFrame > 60) delayFrame -= 10; // vai acelerando } } // Redesenha tudo desenhaCenarioDino(); // Checa colisão if (checaColisaoDino()) { beepErro(400); jogoRodando = false; } } } // Tela de fim de jogo lcd.clear(); lcd.setCursor(0, 0); lcd.print("GAME OVER DINO"); lcd.setCursor(0, 1); lcd.print("Obst.: "); lcd.print(obstaculosCriados); // Pequena animação sonora for (int i = 0; i < 3; i++) { beepErro(200); delay(250); } delay(3000); } // ----------------------------- // JOGO 3 - REFLEX MASTER // ----------------------------- long melhorPontuacaoReflex = 0; void iniciarReflex() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("REFLEX MASTER"); lcd.setCursor(0, 1); lcd.print("Aperte certo!"); delay(2000); long pontuacao = 0; bool jogando = true; while (jogando) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Pontos: "); lcd.print(pontuacao); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(melhorPontuacaoReflex); delay(800); // Escolhe um LED aleatório (1..4) int alvo = random(1, 5); int ledAlvoPin = led1; switch (alvo) { case 1: ledAlvoPin = led1; break; case 2: ledAlvoPin = led2; break; case 3: ledAlvoPin = led3; break; case 4: ledAlvoPin = led4; break; } // Tempo máximo permitido diminui com a pontuação unsigned long tempoMax = 1500; if (pontuacao < 10) { tempoMax = 1500 - pontuacao * 80; } else { tempoMax = 700; } if (tempoMax < 350) tempoMax = 350; digitalWrite(ledAlvoPin, HIGH); tone(bz, 600, 80); unsigned long inicio = millis(); bool respondeu = false; int botao = 0; while (millis() - inicio < tempoMax && !respondeu) { if (botaoAtivo(bt1)) { botao = 1; respondeu = true; } else if (botaoAtivo(bt2)) { botao = 2; respondeu = true; } else if (botaoAtivo(bt3)) { botao = 3; respondeu = true; } else if (botaoAtivo(bt4)) { botao = 4; respondeu = true; } if (respondeu) { esperaSoltarBotoes(); } delay(2); } digitalWrite(ledAlvoPin, LOW); if (!respondeu) { // Não respondeu a tempo lcd.clear(); lcd.setCursor(0, 0); lcd.print("Muito lento!"); beepErro(300); jogando = false; } else if (botao != alvo) { // Errou o botão lcd.clear(); lcd.setCursor(0, 0); lcd.print("Botao errado!"); beepErro(300); jogando = false; } else { // Acertou pontuacao++; beepOk(150); delay(300); } } if (pontuacao > melhorPontuacaoReflex) { melhorPontuacaoReflex = pontuacao; } lcd.clear(); lcd.setCursor(0, 0); lcd.print("FIM REFLEX!"); lcd.setCursor(0, 1); lcd.print("Score: "); lcd.print(pontuacao); delay(3000); } // ----------------------------- // JOGO 4 - LABIRINTO 16x2 // ----------------------------- // Labirinto fixo 16x2 // 'S' = início; 'F' = fim; '#' = parede; ' ' = caminho const char lab1_row0[] = "S # # F"; const char lab1_row1[] = "## # #######"; char labirinto[2][17]; void carregaLabirinto1() { for (int c = 0; c < 16; c++) { labirinto[0][c] = lab1_row0[c]; labirinto[1][c] = lab1_row1[c]; } labirinto[0][16] = '\0'; labirinto[1][16] = '\0'; } void desenhaLabirinto(int jogadorLinha, int jogadorColuna) { for (int linha = 0; linha < 2; linha++) { lcd.setCursor(0, linha); for (int col = 0; col < 16; col++) { if (linha == jogadorLinha && col == jogadorColuna) { lcd.print("@"); // jogador } else { lcd.print(labirinto[linha][col]); } } } } void encontrarInicioLabirinto(int &linha, int &coluna) { linha = 0; coluna = 0; for (int l = 0; l < 2; l++) { for (int c = 0; c < 16; c++) { if (labirinto[l][c] == 'S') { linha = l; coluna = c; return; } } } } bool ehParede(int linha, int coluna) { if (linha < 0 || linha > 1 || coluna < 0 || coluna > 15) return true; return labirinto[linha][coluna] == '#'; } bool ehSaida(int linha, int coluna) { return labirinto[linha][coluna] == 'F'; } // Lê direção usando 4 botões: // bt1 = cima, bt2 = baixo, bt3 = esquerda, bt4 = direita int lerDirecaoLabirinto() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } // cima if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } // baixo if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } // esquerda if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } // direita delay(10); } } void iniciarLabirinto() { carregaLabirinto1(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("LABIRINTO 16x2"); lcd.setCursor(0, 1); lcd.print("Use 4 botoes"); delay(2000); int jogadorLinha = 0; int jogadorColuna = 0; encontrarInicioLabirinto(jogadorLinha, jogadorColuna); unsigned long inicioJogo = millis(); const unsigned long tempoLimite = 60000; // 60s int passos = 0; bool venceu = false; bool acabouTempo = false; while (!venceu && !acabouTempo) { unsigned long agora = millis(); if (agora - inicioJogo > tempoLimite) { acabouTempo = true; break; } desenhaLabirinto(jogadorLinha, jogadorColuna); lcd.setCursor(0, 0); lcd.print("LAB "); lcd.print((tempoLimite - (agora - inicioJogo)) / 1000); lcd.print("s "); // limpar resto da linha // Ler direção int direcao = lerDirecaoLabirinto(); int novaLinha = jogadorLinha; int novaColuna = jogadorColuna; if (direcao == 1) novaLinha--; // cima else if (direcao == 2) novaLinha++; // baixo else if (direcao == 3) novaColuna--;// esquerda else if (direcao == 4) novaColuna++;// direita if (ehParede(novaLinha, novaColuna)) { // Bateu na parede beepErro(150); // Não conta passo se bateu } else { jogadorLinha = novaLinha; jogadorColuna = novaColuna; passos++; beepOk(60); if (ehSaida(jogadorLinha, jogadorColuna)) { venceu = true; } } delay(100); } lcd.clear(); if (venceu) { lcd.setCursor(0, 0); lcd.print("Saiu do lab!"); lcd.setCursor(0, 1); lcd.print("Passos: "); lcd.print(passos); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } } else if (acabouTempo) { lcd.setCursor(0, 0); lcd.print("Tempo esgotou"); lcd.setCursor(0, 1); lcd.print("Quase la..."); for (int i = 0; i < 3; i++) { beepErro(200); delay(200); } } delay(3000); } // ----------------------------- // MENU INICIAL // ----------------------------- void mostraMenu() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("1:Genius 2:Dino"); lcd.setCursor(0, 1); lcd.print("3:Reflex 4:Lab"); } int escolherJogo() { mostraMenu(); while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return GAME_GENIUS; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return GAME_DINO; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return GAME_REFLEX; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return GAME_MAZE; } delay(10); } } // ----------------------------- // SETUP E LOOP PRINCIPAL // ----------------------------- void setup() { Serial.begin(9600); lcd.init(); lcd.setBacklight(HIGH); randomSeed(analogRead(A0)); pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(bt1, INPUT); pinMode(bt2, INPUT); pinMode(bt3, INPUT); pinMode(bt4, INPUT); pinMode(bz, OUTPUT); lcd.setCursor(0, 0); lcd.print("Arcade Arduino"); lcd.setCursor(0, 1); lcd.print("Iniciando..."); delay(2000); } void loop() { jogoAtual = escolherJogo(); switch (jogoAtual) { case GAME_GENIUS: iniciarGenius(); break; case GAME_DINO: iniciarDino(); break; case GAME_REFLEX: iniciarReflex(); break; case GAME_MAZE: iniciarLabirinto(); break; } // Depois de cada jogo, volta ao menu automaticamente }

Como cada jogo funciona (resumão)

Jogo 1 – Genius (botão 1)

  • Mesma ideia do teu código original.
  • Cada rodada adiciona um passo à sequência (até 50 passos).
  • Se errar, mostra a rodada que você chegou.
  • Se chegar no máximo, faz uma pequena “celebração” no buzzer.

Jogo 2 – Dino Runner (botão 2)

  • Dino fica em uma posição fixa na tela (coluna 3).
  • Obstáculos (|) aparecem na linha de baixo vindo da direita.
  • Pulo: botão 1 (bt1).
    • O pulo tem fases (subida/descida).
    • Enquanto está no ar, não pode iniciar outro pulo.
    • Ainda tem um cooldown depois de cair → não rola ficar pulando infinito.
  • Dificuldade aumenta:
    • Obstáculos aparecem com probabilidade maior ao longo do tempo.
    • Intervalo entre frames vai diminuindo (o jogo fica mais rápido).
  • Quando colide (obstáculo na mesma coluna que o dino embaixo), acaba a partida e mostra quantos obstáculos foram gerados.

Jogo 3 – Reflex Master (botão 3)

  • Um LED acende aleatoriamente.
  • Você precisa apertar o botão correspondente ao LED antes do tempo acabar.
  • O tempo permitido vai diminuindo conforme a pontuação aumenta.
  • Se:
    • apertar o botão errado → game over;
    • não apertar nada a tempo → game over.
  • Mostra Pontos e Recorde no LCD.
  • Guarda o melhor score na variável melhorPontuacaoReflex.

Jogo 4 – Labirinto 16x2 (botão 4)

  • O LCD mostra um mini labirinto de 16x2:
    • S = start;
    • F = saída;
    • # = parede;
    • espaço = caminho.
  • Você é o caractere @.
  • Controles:
    • bt1 = cima
    • bt2 = baixo
    • bt3 = esquerda
    • bt4 = direita
  • Não pode atravessar paredes (#), se tentar, toca som de erro.
  • Tem 60 segundos para achar a saída.
  • Ao vencer:
    • Mostra quantos passos você deu.
  • Se o tempo acabar:
    • Mensagem de tempo esgotado + sons de erro.

Se quiser, na próxima posso:

  • criar mais labirintos e alternar entre fases,
  • deixar o Dino com sprites personalizados (caractere custom do LCD),
  • ou adicionar modo “hardcore” em qualquer um dos jogos.

問題

#include <LiquidCrystal.h>

// --- DEFINIÇÃO DOS PINOS DO LCD ---
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Pinos dos componentes
int led1 = 26;
int led2 = 24;
int led3 = 22;
int led4 = 36;
int bt1 = 34;
int bt2 = 32;
int bt3 = 30;
int bt4 = 28;
int bz = 8;

// Variáveis Globais
int padraoLed[100]; // Aumentei um pouco o limite
int rodadaAtual = 1;
int modoJogo = 0; // 0 = Menu, 1 = Normal, 2 = Turbo, 3 = Silencioso, 4 = Piano

void setup() {
Serial.begin(9600);
lcd.begin(16, 2);

// Configuração dos pinos
pinMode(led1, OUTPUT); pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT); pinMode(led4, OUTPUT);
pinMode(bt1, INPUT); pinMode(bt2, INPUT);
pinMode(bt3, INPUT); pinMode(bt4, INPUT);
pinMode(bz, OUTPUT);

// Mensagem de boas vindas rápida
lcd.setCursor(0, 0);
lcd.print("Genius System");
lcd.setCursor(0, 1);
lcd.print("Iniciando...");
delay(1500);
}

void loop() {
// SE O MODO FOR 0, RODAMOS O MENU
if (modoJogo == 0) {
MenuInicial();
}
// SE O MODO FOR 4, É O MODO PIANO (LIVRE)
else if (modoJogo == 4) {
ModoPiano();
}
// CASO CONTRÁRIO, É O JOGO GENIUS (MODOS 1, 2 e 3)
else {
JogarGenius();
}
}

// --- FUNÇÃO DO MENU ---
void MenuInicial() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1:Norm 2:Turbo");
lcd.setCursor(0, 1);
lcd.print("3:Mudo 4:Piano");

// Loop infinito esperando escolha
// Pisca os LEDs aleatoriamente enquanto espera (visual do menu)
while (modoJogo == 0) {

text
// Efeito visual simples enquanto espera int ledDemo = random(1, 5); switch(ledDemo) { case 1: digitalWrite(led1, HIGH); break; case 2: digitalWrite(led2, HIGH); break; case 3: digitalWrite(led3, HIGH); break; case 4: digitalWrite(led4, HIGH); break; } delay(100); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); // Verificação dos botões para selecionar o modo if (digitalRead(bt1) == HIGH) { modoJogo = 1; lcd.clear(); lcd.print("Modo: NORMAL"); } if (digitalRead(bt2) == HIGH) { modoJogo = 2; lcd.clear(); lcd.print("Modo: TURBO"); } if (digitalRead(bt3) == HIGH) { modoJogo = 3; lcd.clear(); lcd.print("Modo: MUDO"); } if (digitalRead(bt4) == HIGH) { modoJogo = 4; lcd.clear(); lcd.print("Modo: PIANO"); } // Se escolheu algum, define a semente aleatória e espera um pouco if (modoJogo != 0) { randomSeed(micros()); // Garante aleatoriedade baseada no tempo de resposta delay(2000); rodadaAtual = 1; // Reseta o jogo lcd.clear(); }

}
}

// --- FUNÇÃO PRINCIPAL DO JOGO (MODOS 1, 2, 3) ---
void JogarGenius() {
MostraSequencia(rodadaAtual);

bool acertou = LerJogador(rodadaAtual);

if (acertou) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Acertou! Prox.");
rodadaAtual++;
delay(1500);
} else {
// GAME OVER
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ERROU! Fim Jogo");

text
// Só toca som de erro se não estiver no modo mudo if (modoJogo != 3) tone(bz, 100, 1000); // Pisca todos os leds para indicar erro for(int i=0; i<3; i++){ digitalWrite(led1, HIGH); digitalWrite(led2, HIGH); digitalWrite(led3, HIGH); digitalWrite(led4, HIGH); delay(200); digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); delay(200); } delay(1000); lcd.clear(); lcd.print("Fase Max: "); lcd.print(rodadaAtual - 1); delay(3000); // --- VOLTA PARA O MENU --- modoJogo = 0; rodadaAtual = 1;

}
}

// --- LÓGICA PARA MOSTRAR A SEQUÊNCIA ---
void MostraSequencia(int nRodada) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Observe...");

// Define a velocidade baseada no modo
int tempoLed = 500;
int tempoPausa = 500;

if (modoJogo == 2) { // MODO TURBO
tempoLed = 200; // Muito mais rápido
tempoPausa = 200;
}

padraoLed[nRodada - 1] = random(1, 5);

for (int i = 0; i < nRodada; i++) {
delay(400); // Pausa entre LEDs

text
switch (padraoLed[i]) { case 1: digitalWrite(led1, HIGH); if (modoJogo != 3) tone(bz, 262, tempoLed/2); // Mudo no modo 3 delay(tempoLed); digitalWrite(led1, LOW); break; case 2: digitalWrite(led2, HIGH); if (modoJogo != 3) tone(bz, 294, tempoLed/2); delay(tempoLed); digitalWrite(led2, LOW); break; case 3: digitalWrite(led3, HIGH); if (modoJogo != 3) tone(bz, 330, tempoLed/2); delay(tempoLed); digitalWrite(led3, LOW); break; case 4: digitalWrite(led4, HIGH); if (modoJogo != 3) tone(bz, 349, tempoLed/2); delay(tempoLed); digitalWrite(led4, LOW); break; }

}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Sua vez!");
}

// --- LÓGICA PARA LER O JOGADOR ---
bool LerJogador(int nRodada) {
int passoAtual = 0;

while (passoAtual < nRodada) {
int botaoPressionado = 0;

text
// Aguarda até apertar algum botão while (botaoPressionado == 0) { if (digitalRead(bt1) == HIGH) { botaoPressionado = 1; digitalWrite(led1, HIGH); if (modoJogo != 3) tone(bz, 262, 150); delay(250); digitalWrite(led1, LOW); } else if (digitalRead(bt2) == HIGH) { botaoPressionado = 2; digitalWrite(led2, HIGH); if (modoJogo != 3) tone(bz, 294, 150); delay(250); digitalWrite(led2, LOW); } else if (digitalRead(bt3) == HIGH) { botaoPressionado = 3; digitalWrite(led3, HIGH); if (modoJogo != 3) tone(bz, 330, 150); delay(250); digitalWrite(led3, LOW); } else if (digitalRead(bt4) == HIGH) { botaoPressionado = 4; digitalWrite(led4, HIGH); if (modoJogo != 3) tone(bz, 349, 150); delay(250); digitalWrite(led4, LOW); } } if (botaoPressionado == padraoLed[passoAtual]) { passoAtual++; } else { return false; } delay(100);

}
return true;
}

// --- MODO 4: PIANO LIVRE ---
void ModoPiano() {
lcd.clear();
lcd.print("Piano Livre");
lcd.setCursor(0,1);
lcd.print("Reset p/ Menu");

// Fica aqui para sempre até reiniciar o Arduino
while (true) {
if (digitalRead(bt1) == HIGH) {
digitalWrite(led1, HIGH); tone(bz, 262);
while(digitalRead(bt1) == HIGH); // Mantém som enquanto aperta
digitalWrite(led1, LOW); noTone(bz);
}
if (digitalRead(bt2) == HIGH) {
digitalWrite(led2, HIGH); tone(bz, 294);
while(digitalRead(bt2) == HIGH);
digitalWrite(led2, LOW); noTone(bz);
}
if (digitalRead(bt3) == HIGH) {
digitalWrite(led3, HIGH); tone(bz, 330);
while(digitalRead(bt3) == HIGH);
digitalWrite(led3, LOW); noTone(bz);
}
if (digitalRead(bt4) == HIGH) {
digitalWrite(led4, HIGH); tone(bz, 349);
while(digitalRead(bt4) == HIGH);
digitalWrite(led4, LOW); noTone(bz);
}
}
}

mandei o codigo errado, porem as diferenças não são tantas, quero que adapte para esse codigo, ele muda principalmente o lcd mas se atente para os outros aspectos como as portas

思考

code = r''' #include <LiquidCrystal.h>

// ----------------------------- // DEFINIÇÕES DO LCD E PINOS // -----------------------------

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Pinos dos componentes (Arduino MEGA) const int led1 = 26; const int led2 = 24; const int led3 = 22; const int led4 = 36;

const int bt1 = 34; const int bt2 = 32; const int bt3 = 30; const int bt4 = 28;

const int bz = 8;

// ----------------------------- // ESTADOS / JOGOS // -----------------------------

enum GameId { GAME_MENU = 0, GAME_GENIUS = 1, GAME_DINO = 2, GAME_REFLEX = 3, GAME_MAZE = 4 };

int jogoAtual = GAME_MENU;

// ----------------------------- // FUNÇÕES AUXILIARES GERAIS // -----------------------------

void apagaLeds() { digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); }

void beepOk(int duracao) { tone(bz, 800, duracao); }

void beepOk() { beepOk(120); }

void beepErro(int duracao) { tone(bz, 200, duracao); }

void beepErro() { beepErro(200); }

bool botaoAtivo(int pin) { return digitalRead(pin) == HIGH; }

// Espera TODOS os botões soltarem (evita cliques duplos) void esperaSoltarBotoes() { bool algumPressionado = true; while (algumPressionado) { algumPressionado = botaoAtivo(bt1) || botaoAtivo(bt2) || botaoAtivo(bt3) || botaoAtivo(bt4); delay(10); } }

// Retorna 1..4 de acordo com o botão pressionado int lerBotaoJogo() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } delay(5); } }

// ----------------------------- // JOGO 1 - GENIUS CLÁSSICO // -----------------------------

const int TAM_PADRAO = 50; int padraoLed[TAM_PADRAO];

void MostraSequenciaGenius(int nRodada); bool LerJogadorGenius(int nRodada);

void iniciarGenius() { for (int i = 0; i < TAM_PADRAO; i++) { padraoLed[i] = 0; }

int rodadaAtual = 1; bool jogando = true;

lcd.clear(); lcd.setCursor(0, 0); lcd.print("GENIUS"); lcd.setCursor(0, 1); lcd.print("Boa sorte!"); delay(1500);

while (jogando) { MostraSequenciaGenius(rodadaAtual);

text
bool acertou = LerJogadorGenius(rodadaAtual); if (acertou) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Acertou a seq!"); lcd.setCursor(0, 1); lcd.print("Rodada: "); lcd.print(rodadaAtual); beepOk(); delay(1500); rodadaAtual++; if (rodadaAtual > TAM_PADRAO) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("VOCE ZEROU!"); lcd.setCursor(0, 1); lcd.print("Impressionante!"); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } delay(2500); jogando = false; } } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("ERROU! Fim Jogo"); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(rodadaAtual - 1); for (int i = 0; i < 3; i++) { beepErro(250); delay(250); } delay(3000); jogando = false; }

} }

void MostraSequenciaGenius(int nRodada) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Observe...");

// Adiciona um novo passo à sequência padraoLed[nRodada - 1] = random(1, 5);

delay(1000); for (int i = 0; i < nRodada; i++) { delay(200);

text
int passo = padraoLed[i]; int ledPin = led1; int freq = 262; // Do switch (passo) { case 1: ledPin = led1; freq = 262; break; case 2: ledPin = led2; freq = 294; break; case 3: ledPin = led3; freq = 330; break; case 4: ledPin = led4; freq = 349; break; } digitalWrite(ledPin, HIGH); tone(bz, freq, 200); delay(500); digitalWrite(ledPin, LOW);

}

lcd.clear(); lcd.setCursor(0, 0); lcd.print("Sua vez!"); }

bool LerJogadorGenius(int nRodada) { int passoAtual = 0;

while (passoAtual < nRodada) { int botaoPressionado = 0;

text
while (botaoPressionado == 0) { if (botaoAtivo(bt1)) { botaoPressionado = 1; digitalWrite(led1, HIGH); tone(bz, 262, 150); delay(250); digitalWrite(led1, LOW); } else if (botaoAtivo(bt2)) { botaoPressionado = 2; digitalWrite(led2, HIGH); tone(bz, 294, 150); delay(250); digitalWrite(led2, LOW); } else if (botaoAtivo(bt3)) { botaoPressionado = 3; digitalWrite(led3, HIGH); tone(bz, 330, 150); delay(250); digitalWrite(led3, LOW); } else if (botaoAtivo(bt4)) { botaoPressionado = 4; digitalWrite(led4, HIGH); tone(bz, 349, 150); delay(250); digitalWrite(led4, LOW); } delay(5); } if (botaoPressionado == padraoLed[passoAtual]) { passoAtual++; } else { return false; } delay(100);

}

return true; }

// ----------------------------- // JOGO 2 - DINO RUNNER 16x2 // -----------------------------

const int DINO_COL = 3; const int MAX_OBSTACULOS = 5; int obstCol[MAX_OBSTACULOS]; bool obstAtivo[MAX_OBSTACULOS];

bool dinoJumping = false; int dinoRow = 1; int jumpPhase = 0; const int JUMP_FASES = 6; int jumpCooldownFrames = 0;

bool bt1PrevState = false;

void resetDinoEstado() { for (int i = 0; i < MAX_OBSTACULOS; i++) { obstCol[i] = -1; obstAtivo[i] = false; } dinoRow = 1; dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 0; bt1PrevState = false; }

void spawnObstaculo() { for (int i = 0; i < MAX_OBSTACULOS; i++) { if (!obstAtivo[i]) { obstAtivo[i] = true; obstCol[i] = 15; break; } } }

void atualizaDinoPulo() { if (dinoJumping) { jumpPhase++; if (jumpPhase < JUMP_FASES / 2) { dinoRow = 0; } else { dinoRow = 1; }

text
if (jumpPhase >= JUMP_FASES) { dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 2; }

} else { dinoRow = 1; if (jumpCooldownFrames > 0) { jumpCooldownFrames--; } } }

bool checaColisaoDino() { for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] == DINO_COL && dinoRow == 1) { return true; } } return false; }

void desenhaCenarioDino() { char linha0[17]; char linha1[17];

for (int i = 0; i < 16; i++) { linha0[i] = ' '; linha1[i] = '_'; }

for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] >= 0 && obstCol[i] < 16) { linha1[obstCol[i]] = '|'; } }

if (dinoRow == 0) { linha0[DINO_COL] = 'D'; } else { linha1[DINO_COL] = 'D'; }

linha0[16] = '\0'; linha1[16] = '\0';

lcd.setCursor(0, 0); lcd.print(linha0); lcd.setCursor(0, 1); lcd.print(linha1); }

void iniciarDino() { resetDinoEstado();

unsigned long ultimoFrame = millis(); int delayFrame = 180; int nivelDificuldade = 1; int obstaculosCriados = 0; bool jogoRodando = true;

lcd.clear(); lcd.setCursor(0, 0); lcd.print("DINO RUN LCD"); lcd.setCursor(0, 1); lcd.print("BT1 = PULAR"); delay(2000);

lcd.clear();

while (jogoRodando) { bool bt1Now = botaoAtivo(bt1); if (bt1Now && !bt1PrevState && !dinoJumping && jumpCooldownFrames == 0) { dinoJumping = true; jumpPhase = 0; tone(bz, 700, 80); } bt1PrevState = bt1Now;

text
if (millis() - ultimoFrame >= (unsigned long)delayFrame) { ultimoFrame = millis(); atualizaDinoPulo(); for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { obstCol[i]--; if (obstCol[i] < 0) { obstAtivo[i] = false; } } } bool podeCriar = true; int chance = 20 + nivelDificuldade * 3; if (chance > 70) chance = 70; for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { if (obstCol[i] > 10) { podeCriar = false; } } } if (podeCriar && random(0, 100) < chance) { spawnObstaculo(); obstaculosCriados++; if (obstaculosCriados % 5 == 0) { nivelDificuldade++; if (delayFrame > 60) delayFrame -= 10; } } desenhaCenarioDino(); if (checaColisaoDino()) { beepErro(400); jogoRodando = false; } }

}

lcd.clear(); lcd.setCursor(0, 0); lcd.print("GAME OVER DINO"); lcd.setCursor(0, 1); lcd.print("Obst.: "); lcd.print(obstaculosCriados);

for (int i = 0; i < 3; i++) { beepErro(200); delay(250); }

delay(3000); }

// ----------------------------- // JOGO 3 - REFLEX MASTER // -----------------------------

long melhorPontuacaoReflex = 0;

void iniciarReflex() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("REFLEX MASTER"); lcd.setCursor(0, 1); lcd.print("Aperte certo!"); delay(2000);

long pontuacao = 0; bool jogando = true;

while (jogando) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Pontos: "); lcd.print(pontuacao); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(melhorPontuacaoReflex);

text
delay(800); int alvo = random(1, 5); int ledAlvoPin = led1; switch (alvo) { case 1: ledAlvoPin = led1; break; case 2: ledAlvoPin = led2; break; case 3: ledAlvoPin = led3; break; case 4: ledAlvoPin = led4; break; } unsigned long tempoMax = 1500; if (pontuacao < 10) { tempoMax = 1500 - pontuacao * 80; } else { tempoMax = 700; } if (tempoMax < 350) tempoMax = 350; digitalWrite(ledAlvoPin, HIGH); tone(bz, 600, 80); unsigned long inicio = millis(); bool respondeu = false; int botao = 0; while (millis() - inicio < tempoMax && !respondeu) { if (botaoAtivo(bt1)) { botao = 1; respondeu = true; } else if (botaoAtivo(bt2)) { botao = 2; respondeu = true; } else if (botaoAtivo(bt3)) { botao = 3; respondeu = true; } else if (botaoAtivo(bt4)) { botao = 4; respondeu = true; } if (respondeu) { esperaSoltarBotoes(); } delay(2); } digitalWrite(ledAlvoPin, LOW); if (!respondeu) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Muito lento!"); beepErro(300); jogando = false; } else if (botao != alvo) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Botao errado!"); beepErro(300); jogando = false; } else { pontuacao++; beepOk(150); delay(300); }

}

if (pontuacao > melhorPontuacaoReflex) { melhorPontuacaoReflex = pontuacao; }

lcd.clear(); lcd.setCursor(0, 0); lcd.print("FIM REFLEX!"); lcd.setCursor(0, 1); lcd.print("Score: "); lcd.print(pontuacao); delay(3000); }

// ----------------------------- // JOGO 4 - LABIRINTO 16x2 // -----------------------------

const char lab1_row0[] = "S # # F"; const char lab1_row1[] = "## # #######";

char labirinto[2][17];

void carregaLabirinto1() { for (int c = 0; c < 16; c++) { labirinto[0][c] = lab1_row0[c]; labirinto[1][c] = lab1_row1[c]; } labirinto[0][16] = '\0'; labirinto[1][16] = '\0'; }

void desenhaLabirinto(int jogadorLinha, int jogadorColuna) { for (int linha = 0; linha < 2; linha++) { lcd.setCursor(0, linha); for (int col = 0; col < 16; col++) { if (linha == jogadorLinha && col == jogadorColuna) { lcd.print("@"); } else { lcd.print(labirinto[linha][col]); } } } }

void encontrarInicioLabirinto(int &linha, int &coluna) { linha = 0; coluna = 0; for (int l = 0; l < 2; l++) { for (int c = 0; c < 16; c++) { if (labirinto[l][c] == 'S') { linha = l; coluna = c; return; } } } }

bool ehParede(int linha, int coluna) { if (linha < 0 || linha > 1 || coluna < 0 || coluna > 15) return true; return labirinto[linha][coluna] == '#'; }

bool ehSaida(int linha, int coluna) { return labirinto[linha][coluna] == 'F'; }

// bt1 = cima, bt2 = baixo, bt3 = esquerda, bt4 = direita int lerDirecaoLabirinto() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } delay(10); } }

void iniciarLabirinto() { carregaLabirinto1();

lcd.clear(); lcd.setCursor(0, 0); lcd.print("LABIRINTO 16x2"); lcd.setCursor(0, 1); lcd.print("Use 4 botoes"); delay(2000);

int jogadorLinha = 0; int jogadorColuna = 0; encontrarInicioLabirinto(jogadorLinha, jogadorColuna);

unsigned long inicioJogo = millis(); const unsigned long tempoLimite = 60000; int passos = 0; bool venceu = false; bool acabouTempo = false;

while (!venceu && !acabouTempo) { unsigned long agora = millis(); if (agora - inicioJogo > tempoLimite) { acabouTempo = true; break; }

text
desenhaLabirinto(jogadorLinha, jogadorColuna); // Mostra tempo restante no canto superior direito int segundosRest = (tempoLimite - (agora - inicioJogo)) / 1000; if (segundosRest < 0) segundosRest = 0; lcd.setCursor(10, 0); if (segundosRest < 10) { lcd.print(" "); lcd.print(segundosRest); lcd.print("s"); } else { lcd.print(" "); lcd.print(segundosRest); lcd.print("s"); } int direcao = lerDirecaoLabirinto(); int novaLinha = jogadorLinha; int novaColuna = jogadorColuna; if (direcao == 1) novaLinha--; else if (direcao == 2) novaLinha++; else if (direcao == 3) novaColuna--; else if (direcao == 4) novaColuna++; if (ehParede(novaLinha, novaColuna)) { beepErro(150); } else { jogadorLinha = novaLinha; jogadorColuna = novaColuna; passos++; beepOk(60); if (ehSaida(jogadorLinha, jogadorColuna)) { venceu = true; } } delay(100);

}

lcd.clear(); if (venceu) { lcd.setCursor(0, 0); lcd.print("Saiu do lab!"); lcd.setCursor(0, 1); lcd.print("Passos: "); lcd.print(passos); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } } else if (acabouTempo) { lcd.setCursor(0, 0); lcd.print("Tempo esgotou"); lcd.setCursor(0, 1); lcd.print("Quase la..."); for (int i = 0; i < 3; i++) { beepErro(200); delay(200); } }

delay(3000); }

// ----------------------------- // MENU INICIAL // -----------------------------

void mostraMenu() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("1:Genius 2:Dino"); lcd.setCursor(0, 1); lcd.print("3:Reflex 4:Lab"); }

int escolherJogo() { mostraMenu(); while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return GAME_GENIUS; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return GAME_DINO; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return GAME_REFLEX; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return GAME_MAZE; } delay(10); } }

// ----------------------------- // SETUP E LOOP PRINCIPAL // -----------------------------

void setup() { Serial.begin(9600);

lcd.begin(16, 2);

randomSeed(analogRead(A0));

pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT);

pinMode(bt1, INPUT); pinMode(bt2, INPUT); pinMode(bt3, INPUT); pinMode(bt4, INPUT);

pinMode(bz, OUTPUT);

lcd.clear(); lcd.setCursor(0, 0); lcd.print("Arcade Genius"); lcd.setCursor(0, 1); lcd.print("Carregando..."); delay(2000); }

void loop() { jogoAtual = escolherJogo();

switch (jogoAtual) { case GAME_GENIUS: iniciarGenius(); break; case GAME_DINO: iniciarDino(); break; case GAME_REFLEX: iniciarReflex(); break; case GAME_MAZE: iniciarLabirinto(); break; }

// Ao terminar qualquer jogo, volta ao menu } '''

brace check

stack=[] for i,ch in enumerate(code): if ch=='{': stack.append(i) elif ch=='}': if not stack: print("extra } at", i) break stack.pop() len(stack)

Thought for 3m 5s

回答

Perfeito, agora entendi o teu setup “real”:
LCD paralelo com LiquidCrystal, pinos altos do Mega pros LEDs/botões, e buzzer no 8.

Abaixo está o arcade de 4 jogos (Genius, Dino, Reflex e Labirinto) já adaptado para:

  • LiquidCrystal (rs=12, en=11, d4=5, d5=4, d6=3, d7=2)
  • LEDs: 26, 24, 22, 36
  • Botões: 34, 32, 30, 28
  • Buzzer: 8

Quando liga, aparece um menu:

  • BT1 (34) → Jogo 1: Genius
  • BT2 (32) → Jogo 2: Dino Runner
  • BT3 (30) → Jogo 3: Reflex Master
  • BT4 (28) → Jogo 4: Labirinto 16x2

Basta substituir totalmente o seu código atual por este:


cpp
#include <LiquidCrystal.h> // ----------------------------- // DEFINIÇÕES DO LCD E PINOS // ----------------------------- const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // Pinos dos componentes (Arduino MEGA) const int led1 = 26; const int led2 = 24; const int led3 = 22; const int led4 = 36; const int bt1 = 34; const int bt2 = 32; const int bt3 = 30; const int bt4 = 28; const int bz = 8; // ----------------------------- // ESTADOS / JOGOS // ----------------------------- enum GameId { GAME_MENU = 0, GAME_GENIUS = 1, GAME_DINO = 2, GAME_REFLEX = 3, GAME_MAZE = 4 }; int jogoAtual = GAME_MENU; // ----------------------------- // FUNÇÕES AUXILIARES GERAIS // ----------------------------- void apagaLeds() { digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); digitalWrite(led4, LOW); } void beepOk(int duracao) { tone(bz, 800, duracao); } void beepOk() { beepOk(120); } void beepErro(int duracao) { tone(bz, 200, duracao); } void beepErro() { beepErro(200); } bool botaoAtivo(int pin) { return digitalRead(pin) == HIGH; } // Espera TODOS os botões soltarem (evita cliques duplos) void esperaSoltarBotoes() { bool algumPressionado = true; while (algumPressionado) { algumPressionado = botaoAtivo(bt1) || botaoAtivo(bt2) || botaoAtivo(bt3) || botaoAtivo(bt4); delay(10); } } // Retorna 1..4 de acordo com o botão pressionado int lerBotaoJogo() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } delay(5); } } // ----------------------------- // JOGO 1 - GENIUS CLÁSSICO // ----------------------------- const int TAM_PADRAO = 50; int padraoLed[TAM_PADRAO]; void MostraSequenciaGenius(int nRodada); bool LerJogadorGenius(int nRodada); void iniciarGenius() { for (int i = 0; i < TAM_PADRAO; i++) { padraoLed[i] = 0; } int rodadaAtual = 1; bool jogando = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("GENIUS"); lcd.setCursor(0, 1); lcd.print("Boa sorte!"); delay(1500); while (jogando) { MostraSequenciaGenius(rodadaAtual); bool acertou = LerJogadorGenius(rodadaAtual); if (acertou) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Acertou a seq!"); lcd.setCursor(0, 1); lcd.print("Rodada: "); lcd.print(rodadaAtual); beepOk(); delay(1500); rodadaAtual++; if (rodadaAtual > TAM_PADRAO) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("VOCE ZEROU!"); lcd.setCursor(0, 1); lcd.print("Impressionante!"); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } delay(2500); jogando = false; } } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("ERROU! Fim Jogo"); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(rodadaAtual - 1); for (int i = 0; i < 3; i++) { beepErro(250); delay(250); } delay(3000); jogando = false; } } } void MostraSequenciaGenius(int nRodada) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Observe..."); // Adiciona um novo passo à sequência padraoLed[nRodada - 1] = random(1, 5); delay(1000); for (int i = 0; i < nRodada; i++) { delay(200); int passo = padraoLed[i]; int ledPin = led1; int freq = 262; // Do switch (passo) { case 1: ledPin = led1; freq = 262; break; case 2: ledPin = led2; freq = 294; break; case 3: ledPin = led3; freq = 330; break; case 4: ledPin = led4; freq = 349; break; } digitalWrite(ledPin, HIGH); tone(bz, freq, 200); delay(500); digitalWrite(ledPin, LOW); } lcd.clear(); lcd.setCursor(0, 0); lcd.print("Sua vez!"); } bool LerJogadorGenius(int nRodada) { int passoAtual = 0; while (passoAtual < nRodada) { int botaoPressionado = 0; while (botaoPressionado == 0) { if (botaoAtivo(bt1)) { botaoPressionado = 1; digitalWrite(led1, HIGH); tone(bz, 262, 150); delay(250); digitalWrite(led1, LOW); } else if (botaoAtivo(bt2)) { botaoPressionado = 2; digitalWrite(led2, HIGH); tone(bz, 294, 150); delay(250); digitalWrite(led2, LOW); } else if (botaoAtivo(bt3)) { botaoPressionado = 3; digitalWrite(led3, HIGH); tone(bz, 330, 150); delay(250); digitalWrite(led3, LOW); } else if (botaoAtivo(bt4)) { botaoPressionado = 4; digitalWrite(led4, HIGH); tone(bz, 349, 150); delay(250); digitalWrite(led4, LOW); } delay(5); } if (botaoPressionado == padraoLed[passoAtual]) { passoAtual++; } else { return false; } delay(100); } return true; } // ----------------------------- // JOGO 2 - DINO RUNNER 16x2 // ----------------------------- const int DINO_COL = 3; const int MAX_OBSTACULOS = 5; int obstCol[MAX_OBSTACULOS]; bool obstAtivo[MAX_OBSTACULOS]; bool dinoJumping = false; int dinoRow = 1; int jumpPhase = 0; const int JUMP_FASES = 6; int jumpCooldownFrames = 0; bool bt1PrevState = false; void resetDinoEstado() { for (int i = 0; i < MAX_OBSTACULOS; i++) { obstCol[i] = -1; obstAtivo[i] = false; } dinoRow = 1; dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 0; bt1PrevState = false; } void spawnObstaculo() { for (int i = 0; i < MAX_OBSTACULOS; i++) { if (!obstAtivo[i]) { obstAtivo[i] = true; obstCol[i] = 15; break; } } } void atualizaDinoPulo() { if (dinoJumping) { jumpPhase++; if (jumpPhase < JUMP_FASES / 2) { dinoRow = 0; } else { dinoRow = 1; } if (jumpPhase >= JUMP_FASES) { dinoJumping = false; jumpPhase = 0; jumpCooldownFrames = 2; } } else { dinoRow = 1; if (jumpCooldownFrames > 0) { jumpCooldownFrames--; } } } bool checaColisaoDino() { for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] == DINO_COL && dinoRow == 1) { return true; } } return false; } void desenhaCenarioDino() { char linha0[17]; char linha1[17]; for (int i = 0; i < 16; i++) { linha0[i] = ' '; linha1[i] = '_'; } for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i] && obstCol[i] >= 0 && obstCol[i] < 16) { linha1[obstCol[i]] = '|'; } } if (dinoRow == 0) { linha0[DINO_COL] = 'D'; } else { linha1[DINO_COL] = 'D'; } linha0[16] = '\0'; linha1[16] = '\0'; lcd.setCursor(0, 0); lcd.print(linha0); lcd.setCursor(0, 1); lcd.print(linha1); } void iniciarDino() { resetDinoEstado(); unsigned long ultimoFrame = millis(); int delayFrame = 180; int nivelDificuldade = 1; int obstaculosCriados = 0; bool jogoRodando = true; lcd.clear(); lcd.setCursor(0, 0); lcd.print("DINO RUN LCD"); lcd.setCursor(0, 1); lcd.print("BT1 = PULAR"); delay(2000); lcd.clear(); while (jogoRodando) { bool bt1Now = botaoAtivo(bt1); if (bt1Now && !bt1PrevState && !dinoJumping && jumpCooldownFrames == 0) { dinoJumping = true; jumpPhase = 0; tone(bz, 700, 80); } bt1PrevState = bt1Now; if (millis() - ultimoFrame >= (unsigned long)delayFrame) { ultimoFrame = millis(); atualizaDinoPulo(); for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { obstCol[i]--; if (obstCol[i] < 0) { obstAtivo[i] = false; } } } bool podeCriar = true; int chance = 20 + nivelDificuldade * 3; if (chance > 70) chance = 70; for (int i = 0; i < MAX_OBSTACULOS; i++) { if (obstAtivo[i]) { if (obstCol[i] > 10) { podeCriar = false; } } } if (podeCriar && random(0, 100) < chance) { spawnObstaculo(); obstaculosCriados++; if (obstaculosCriados % 5 == 0) { nivelDificuldade++; if (delayFrame > 60) delayFrame -= 10; } } desenhaCenarioDino(); if (checaColisaoDino()) { beepErro(400); jogoRodando = false; } } } lcd.clear(); lcd.setCursor(0, 0); lcd.print("GAME OVER DINO"); lcd.setCursor(0, 1); lcd.print("Obst.: "); lcd.print(obstaculosCriados); for (int i = 0; i < 3; i++) { beepErro(200); delay(250); } delay(3000); } // ----------------------------- // JOGO 3 - REFLEX MASTER // ----------------------------- long melhorPontuacaoReflex = 0; void iniciarReflex() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("REFLEX MASTER"); lcd.setCursor(0, 1); lcd.print("Aperte certo!"); delay(2000); long pontuacao = 0; bool jogando = true; while (jogando) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Pontos: "); lcd.print(pontuacao); lcd.setCursor(0, 1); lcd.print("Recorde: "); lcd.print(melhorPontuacaoReflex); delay(800); int alvo = random(1, 5); int ledAlvoPin = led1; switch (alvo) { case 1: ledAlvoPin = led1; break; case 2: ledAlvoPin = led2; break; case 3: ledAlvoPin = led3; break; case 4: ledAlvoPin = led4; break; } unsigned long tempoMax = 1500; if (pontuacao < 10) { tempoMax = 1500 - pontuacao * 80; } else { tempoMax = 700; } if (tempoMax < 350) tempoMax = 350; digitalWrite(ledAlvoPin, HIGH); tone(bz, 600, 80); unsigned long inicio = millis(); bool respondeu = false; int botao = 0; while (millis() - inicio < tempoMax && !respondeu) { if (botaoAtivo(bt1)) { botao = 1; respondeu = true; } else if (botaoAtivo(bt2)) { botao = 2; respondeu = true; } else if (botaoAtivo(bt3)) { botao = 3; respondeu = true; } else if (botaoAtivo(bt4)) { botao = 4; respondeu = true; } if (respondeu) { esperaSoltarBotoes(); } delay(2); } digitalWrite(ledAlvoPin, LOW); if (!respondeu) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Muito lento!"); beepErro(300); jogando = false; } else if (botao != alvo) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Botao errado!"); beepErro(300); jogando = false; } else { pontuacao++; beepOk(150); delay(300); } } if (pontuacao > melhorPontuacaoReflex) { melhorPontuacaoReflex = pontuacao; } lcd.clear(); lcd.setCursor(0, 0); lcd.print("FIM REFLEX!"); lcd.setCursor(0, 1); lcd.print("Score: "); lcd.print(pontuacao); delay(3000); } // ----------------------------- // JOGO 4 - LABIRINTO 16x2 // ----------------------------- const char lab1_row0[] = "S # # F"; const char lab1_row1[] = "## # #######"; char labirinto[2][17]; void carregaLabirinto1() { for (int c = 0; c < 16; c++) { labirinto[0][c] = lab1_row0[c]; labirinto[1][c] = lab1_row1[c]; } labirinto[0][16] = '\0'; labirinto[1][16] = '\0'; } void desenhaLabirinto(int jogadorLinha, int jogadorColuna) { for (int linha = 0; linha < 2; linha++) { lcd.setCursor(0, linha); for (int col = 0; col < 16; col++) { if (linha == jogadorLinha && col == jogadorColuna) { lcd.print("@"); } else { lcd.print(labirinto[linha][col]); } } } } void encontrarInicioLabirinto(int &linha, int &coluna) { linha = 0; coluna = 0; for (int l = 0; l < 2; l++) { for (int c = 0; c < 16; c++) { if (labirinto[l][c] == 'S') { linha = l; coluna = c; return; } } } } bool ehParede(int linha, int coluna) { if (linha < 0 || linha > 1 || coluna < 0 || coluna > 15) return true; return labirinto[linha][coluna] == '#'; } bool ehSaida(int linha, int coluna) { return labirinto[linha][coluna] == 'F'; } // bt1 = cima, bt2 = baixo, bt3 = esquerda, bt4 = direita int lerDirecaoLabirinto() { while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return 1; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return 2; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return 3; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return 4; } delay(10); } } void iniciarLabirinto() { carregaLabirinto1(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("LABIRINTO 16x2"); lcd.setCursor(0, 1); lcd.print("Use 4 botoes"); delay(2000); int jogadorLinha = 0; int jogadorColuna = 0; encontrarInicioLabirinto(jogadorLinha, jogadorColuna); unsigned long inicioJogo = millis(); const unsigned long tempoLimite = 60000; int passos = 0; bool venceu = false; bool acabouTempo = false; while (!venceu && !acabouTempo) { unsigned long agora = millis(); if (agora - inicioJogo > tempoLimite) { acabouTempo = true; break; } desenhaLabirinto(jogadorLinha, jogadorColuna); // Mostra tempo restante no canto superior direito int segundosRest = (tempoLimite - (agora - inicioJogo)) / 1000; if (segundosRest < 0) segundosRest = 0; lcd.setCursor(10, 0); if (segundosRest < 10) { lcd.print(" "); lcd.print(segundosRest); lcd.print("s"); } else { lcd.print(" "); lcd.print(segundosRest); lcd.print("s"); } int direcao = lerDirecaoLabirinto(); int novaLinha = jogadorLinha; int novaColuna = jogadorColuna; if (direcao == 1) novaLinha--; else if (direcao == 2) novaLinha++; else if (direcao == 3) novaColuna--; else if (direcao == 4) novaColuna++; if (ehParede(novaLinha, novaColuna)) { beepErro(150); } else { jogadorLinha = novaLinha; jogadorColuna = novaColuna; passos++; beepOk(60); if (ehSaida(jogadorLinha, jogadorColuna)) { venceu = true; } } delay(100); } lcd.clear(); if (venceu) { lcd.setCursor(0, 0); lcd.print("Saiu do lab!"); lcd.setCursor(0, 1); lcd.print("Passos: "); lcd.print(passos); for (int i = 0; i < 3; i++) { beepOk(200); delay(200); } } else if (acabouTempo) { lcd.setCursor(0, 0); lcd.print("Tempo esgotou"); lcd.setCursor(0, 1); lcd.print("Quase la..."); for (int i = 0; i < 3; i++) { beepErro(200); delay(200); } } delay(3000); } // ----------------------------- // MENU INICIAL // ----------------------------- void mostraMenu() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("1:Genius 2:Dino"); lcd.setCursor(0, 1); lcd.print("3:Reflex 4:Lab"); } int escolherJogo() { mostraMenu(); while (true) { if (botaoAtivo(bt1)) { esperaSoltarBotoes(); return GAME_GENIUS; } if (botaoAtivo(bt2)) { esperaSoltarBotoes(); return GAME_DINO; } if (botaoAtivo(bt3)) { esperaSoltarBotoes(); return GAME_REFLEX; } if (botaoAtivo(bt4)) { esperaSoltarBotoes(); return GAME_MAZE; } delay(10); } } // ----------------------------- // SETUP E LOOP PRINCIPAL // ----------------------------- void setup() { Serial.begin(9600); lcd.begin(16, 2); randomSeed(analogRead(A0)); pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(bt1, INPUT); pinMode(bt2, INPUT); pinMode(bt3, INPUT); pinMode(bt4, INPUT); pinMode(bz, OUTPUT); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Arcade Genius"); lcd.setCursor(0, 1); lcd.print("Carregando..."); delay(2000); } void loop() { jogoAtual = escolherJogo(); switch (jogoAtual) { case GAME_GENIUS: iniciarGenius(); break; case GAME_DINO: iniciarDino(); break; case GAME_REFLEX: iniciarReflex(); break; case GAME_MAZE: iniciarLabirinto(); break; } // Ao terminar qualquer jogo, volta ao menu }

Se quiser, no próximo passo dá pra:

  • adicionar níveis extras no labirinto,
  • colocar um modo turbo pro Genius como no seu código antigo,
  • ou até um sistema de “vidas” no Dino.

Se algo não compilar de primeira (ex: biblioteca do LCD diferente), me manda o erro exato que eu ajusto.

分享這個問答