#include <LiquidCrystal.h> // -------------------...

Criado em: 3 de dezembro de 2025

Respondido usando GPT-5.1 Thinking por Chat01

Pergunta

#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 / 1.60) {
dinoRow = 0;
} else {
dinoRow = 1;
}

text
if (jumpPhase >= JUMP_FASES) { dinoJumping = false; jumpPhase = 0; // --- AQUI ESTÁ A ALTERAÇÃO --- // Antes estava = 2. Mude para 0 para liberar o pulo imediatamente. jumpCooldownFrames = 0; // ----------------------------- }

} 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 = 250;
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
}

o jogo do labirinto não deu certo, quero que mude ele para o jogo ponte de cristal da serie round six, onde existe duas pontes formadas por blocos de vridro, onde alguns quebram ao pisar e outras não, faça um codigo para arduino pensando nesse jogo, considere todos os limites do arduino e faça com que seja totalmente funcional pensando no meu codigo, pense que o personagem não pode andar na diagonal então pense em uma maneira de fazer com que esse problema não cause erros no código

Pensamento

Proposing new code for 'Crystal Bridge' game

The user wants to replace the labyrinth game with the "Crystal Bridge" game from Squid Game, keeping everything else intact. I’ll need to design the game mechanics to fit the 16x2 LCD and prevent diagonal button presses from causing errors. I'll focus on providing code snippets specifically for the bridge game, making sure everything integrates smoothly with the existing setup.

Designing Crystal Bridge game for hardware constraints

I need to keep the hardware constraints in mind, especially memory usage, whether for the UNO or the MEGA. The game should fit into the available space. For the Crystal Bridge, I’ll represent the bridge columns horizontally on the 16x2 LCD. Each step will involve a choice between two panels, one safe, one deadly, displayed across two rows. The player’s choice will be shown as "S" or "P", with underscores for empty spaces. I could make this simpler by treating the game as steps from 0 to N.

Mapping inputs and controls for Crystal Bridge game

For each step, there will be one safe panel (top or bottom), and the player needs to choose by pressing "up" (bt1, upper glass) or "down" (bt2, lower glass). If correct, they progress; if wrong, the game ends. I’ll disable diagonal moves, ensuring that if both buttons are pressed, only one input is considered. I also need to handle the restart mechanism, though the menu already handles restarts after the game ends.

Handling diagonal movement and code constraints

The user is concerned about diagonal movement, likely due to the 2D labyrinth. To avoid errors, I can design the logic to only allow one button press for each step. If both buttons are pressed simultaneously, it will beep and wait for a valid input. I'll also limit the array size to 12-14 steps for performance.

Designing Crystal Bridge Game and Menu Adjustments

I’ll be reflecting the change from "Game Maze" to "Ponte Cristal" by tweaking the menu strings and adjusting the game flow. I'll set up constants like MAX_PASSOS_PONTE for the bridge steps and use random values to generate safe steps. The game logic will show the player's progress, check valid inputs, and employ helper functions already in use, such as beeps for success or failure.

Implementing Direct Input Logic and Game Modifications

The function lerEscolhaPonte() avoids diagonal movement by ensuring only one button press is accepted at a time, with error handling for simultaneous inputs. I'll replace the labyrinth game constants and functions with the new ones for the "Ponte de Cristal" game, update the code accordingly, and optionally rename the game in the menu. I'll provide the user with the full, updated sketch to easily copy-paste.

Providing updated Arduino code for the new game

I’ll show a short summary of changes and the new code for “Ponte de Cristal”, focusing on the labyrinth replacement, menu update, and new switch-case. Instead of repeating unchanged code, I’ll give a patch-style answer, noting where the changes go. Also, I’ll ensure everything follows Arduino limits and avoid adding complexity.

Designing the bridge game display

I’ll simplify the display by using "Ponte" for the top row and minimal steps for the bottom, showing only relevant details like "Etapa" and "Escolha". Since we’re under the 16-character limit, I can easily fit things like "1=Cima 2=Baixo". This approach balances clarity and memory efficiency—perfect for the Arduino.

Designing the bridge game flow

I’ve designed a simple 1D bridge game where the player chooses between two panels, and if they are correct, they advance. When they fall, we display that they've failed. I wonder if they want to add an element of left/right movement for more complexity, though! For now, the current setup works well with limited inputs.

Thought for 2m 8s

Resposta

Beleza, dá pra trocar o labirinto por um jogo da “ponte de cristal” sim 😄
Vou manter tudo que você já tem (menu, outros jogos, pinos, etc.) e só substituir o Jogo 4.

Ideia do jogo “Ponte de Cristal”

  • A ponte tem N passos (por exemplo, 12).
  • Em cada passo existe um vidro seguro (cima ou baixo) e o outro quebra.
  • O Arduino sorteia esse caminho no começo da partida.
  • Em cada etapa você escolhe:
    • bt1 → vidro de CIMA
    • bt2 → vidro de BAIXO
  • Se escolher o vidro errado: ele “quebra” (som de erro), você cai e o jogo acaba.
  • Se acertar todos os passos, você “sobreviveu à ponte”.

Sobre o problema de “andar na diagonal”

No nosso jogo novo não existe movimento em grade 2D, só a escolha CIMA ou BAIXO.
Mesmo assim, para evitar qualquer bug se o jogador apertar dois botões ao mesmo tempo, a função de leitura:

  • só aceita a escolha quando apenas um botão (bt1 ou bt2) estiver pressionado;
  • se os dois forem pressionados, toca um beep de erro, espera soltar e ignora (não anda “diagonal”).

1) Substitua o bloco “JOGO 4 – LABIRINTO 16x2” por este:

cpp
// ----------------------------- // JOGO 4 - PONTE DE CRISTAL // (inspirado em Round 6) // ----------------------------- // Quantidade de passos da ponte (ajuste se quiser mais/menos) const int MAX_PASSOS_PONTE = 12; // 0 = vidro de cima é seguro // 1 = vidro de baixo é seguro int ponteSegura[MAX_PASSOS_PONTE]; // Gera aleatoriamente qual lado é seguro em cada passo void gerarPonteCristal() { for (int i = 0; i < MAX_PASSOS_PONTE; i++) { ponteSegura[i] = random(0, 2); // 0 ou 1 } } // Lê escolha do jogador garantindo que NÃO existam "diagonais" // bt1 = cima, bt2 = baixo // retorna 0 (cima) ou 1 (baixo) int lerEscolhaPonte() { while (true) { bool cima = botaoAtivo(bt1); bool baixo = botaoAtivo(bt2); // Somente cima if (cima && !baixo) { esperaSoltarBotoes(); return 0; } // Somente baixo if (baixo && !cima) { esperaSoltarBotoes(); return 1; } // Os dois ao mesmo tempo -> não aceita (evita "diagonal") if (cima && baixo) { beepErro(80); // feedback de erro esperaSoltarBotoes(); // espera soltar antes de continuar } delay(10); } } // Desenha o estado atual da ponte no LCD // Mostra qual etapa o jogador está void desenhaPonteCristal(int passoAtual) { lcd.clear(); // Linha de cima: etapa atual / total lcd.setCursor(0, 0); lcd.print("Etapa "); if (passoAtual + 1 < 10) lcd.print("0"); lcd.print(passoAtual + 1); lcd.print("/"); if (MAX_PASSOS_PONTE < 10) lcd.print("0"); lcd.print(MAX_PASSOS_PONTE); // Linha de baixo: instrucoes de escolha lcd.setCursor(0, 1); lcd.print("1=Cima 2=Baixo"); } // Início do jogo da ponte void iniciarPonteCristal() { gerarPonteCristal(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("PONTE DE CRISTAL"); lcd.setCursor(0, 1); lcd.print("1=Cima 2=Baixo"); delay(2000); int passoAtual = 0; bool vivo = true; while (vivo && passoAtual < MAX_PASSOS_PONTE) { // Mostra etapa atual desenhaPonteCristal(passoAtual); // Lê escolha do jogador (0 = cima, 1 = baixo) int escolha = lerEscolhaPonte(); int correto = ponteSegura[passoAtual]; // Mostra o que o jogador escolheu lcd.clear(); lcd.setCursor(0, 0); lcd.print("Voce pisou no:"); lcd.setCursor(0, 1); if (escolha == 0) { lcd.print("Vidro de CIMA"); } else { lcd.print("Vidro de BAIXO"); } delay(600); // Verifica se o vidro era o seguro if (escolha == correto) { // Vidro seguro beepOk(200); passoAtual++; delay(400); } else { // Vidro que quebra -> game over vivo = false; lcd.clear(); lcd.setCursor(0, 0); lcd.print("VIDRO QUEBROU!"); lcd.setCursor(0, 1); lcd.print("Voce caiu..."); for (int i = 0; i < 3; i++) { beepErro(250); delay(250); } } } // Fim de jogo lcd.clear(); if (vivo) { lcd.setCursor(0, 0); lcd.print("VOCE SOBREVIVEU"); lcd.setCursor(0, 1); lcd.print("a ponte de vidro!"); for (int i = 0; i < 3; i++) { beepOk(250); delay(250); } } else { lcd.setCursor(0, 0); lcd.print("FIM DA PONTE"); lcd.setCursor(0, 1); lcd.print("Tente outra vez"); } delay(3000); }

2) Ajuste o menu (opcional, mas recomendado)

Trocar o texto que aparece no menu para indicar o novo jogo no lugar do labirinto.

No seu código atual:

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

Mude a segunda linha para algo tipo:

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

3) Mude a chamada do jogo 4 no loop()

Lá no final do código, onde você tem:

cpp
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 }

Troque apenas a função do caso 4:

cpp
case GAME_MAZE: iniciarPonteCristal(); break;

Se quiser, você também pode renomear o enum GAME_MAZE para GAME_PONTE,
mas isso é só estético – do jeito acima já funciona 100%.


Se você quiser depois deixar a ponte mais longa, com tempo limite ou mostrar o caminho correto ao final, dá pra incrementar fácil em cima desse esqueleto. Se colar esse pedaço no lugar do labirinto já deve compilar e rodar direto no seu Mega.

Compartilhar esta Q&A