Como Fazer o Jogo do Genius no Arduino: A Importância da Memória e seu Contexto Educacional

 

Como Fazer o Jogo do Genius no Arduino: A Importância da Memória e seu Contexto Educacional

Introdução

Genius é um jogo clássico de memória que desafia os jogadores a repetir sequências de cores e sons. Recriá-lo usando o Arduino é uma ótima maneira de aprender sobre programação, eletrônica e, principalmente, o funcionamento da memória em sistemas embarcados.

Neste artigo, vamos ensinar passo a passo como montar o jogo do Genius com Arduino, destacando a importância da memória no projeto e como esse conhecimento pode ser aplicado no contexto escolar para o desenvolvimento de habilidades cognitivas e técnicas.


Materiais Necessários

  • Placa Arduino (Uno, Nano ou similar)

  • 4 LEDs (vermelho, verde, amarelo e azul)

  • 4 Resistores (220Ω)

  • 4 Botões (push-button)

  • Buzzer (para os sons)

  • Protoboard e jumpers


Montagem do Circuito




Programação no Arduino

O código do Genius deve:

  1. Gerar uma sequência aleatória de LEDs e armazená-la na memória (array).

  2. Reproduzir a sequência acendendo LEDs e emitindo sons.

  3. Ler os botões e verificar se o jogador acertou a ordem.

  4. Aumentar a dificuldade adicionando mais itens à sequência.

Trecho do Código (Exemplo Simplificado)

cpp
Copy
Download
//Vamos começar definindo as notas para os sons
#define NOTE_D4  294
#define NOTE_G4  392
#define NOTE_A4  440
#define NOTE_A5  880
 
// criando o array para os 4 sons para sortear um som
int tons[4] = { NOTE_A5, NOTE_A4, NOTE_G4, NOTE_D4 };
// Nossa sequência de até 100 itens vai começar vazia.
int sequencia[100] = {};
// Indica a rodada atual que o jogo se encontra.
int rodada_atual = 0;
// Indica o passo atual dentro da sequência, é usado enquanto a sequência
// está sendo reproduzida.
int passo_atual_na_sequencia = 0;
 
/*
 * Indica o pino de áudio, leds e botões.
 * Os pinos de leds e botões estão em ordem, relacionados uns aos outros, ou
 * seja, o primeiro led está relacionado ao primeiro botão. A ordem destas
 * sequências também estão relacionadas a ordem dos tons.
 */
int pinoAudio = 12;
int pinosLeds[4] = { 2, 4, 6, 8 };
int pinosBotoes[4] = { 3, 5, 7, 9 };
 
// Indica se um botão foi pressionado durante o loop principal.
int botao_pressionado = 0;
// Flag indicando se o jogo acabou.
int perdeu_o_jogo = false;
 
void setup() {
  // Definindo o modo dos pinos dos Leds como saída.
  for (int i = 0; i <= 3; i++) {
    pinMode(pinosLeds[i], OUTPUT);
  }
 
  // Definindo o modo dos pinos dos Botões como pullup interno.
  for (int i = 0; i <= 3; i++) {
    pinMode(pinosBotoes[i], INPUT_PULLUP);
  }
 
  // Definindo o modo do pino de Áudio como saída.
  pinMode(pinoAudio, OUTPUT);
 
  // Inicializando o random através de uma leitura da porta analógica.
  // Esta leitura gera um valor variável entre 0 e 1023.
  randomSeed(analogRead(0));
}
 
void loop() {
  // Se perdeu o jogo reinicializamos todas as variáveis.
  if (perdeu_o_jogo) {
    int sequencia[100] = {};
    rodada_atual = 0;
    passo_atual_na_sequencia = 0;
    perdeu_o_jogo = false;
  }
 
  // Toca um som de início para anúnicar que o jogo está começando quando é a primeira rodada.
  if (rodada_atual == 0) {
    tocarSomDeInicio();
    delay(500);
  }

// Chama a função que inicializa a próxima rodada.
  proximaRodada();
  // Reproduz a sequência atual.
  reproduzirSequencia();
  // Aguarda os botões serem pressionados pelo jogador.
  aguardarJogador();
 
  // Aguarda 1 segundo entre cada jogada.
  delay(1000);
}
 
// Sorteia um novo item e adiciona na sequência.
void proximaRodada() {
  int numero_sorteado = random(0, 4);
  sequencia[rodada_atual++] = numero_sorteado;
}
 
// Reproduz a sequência para ser memorizada.
void reproduzirSequencia() {
  for (int i = 0; i < rodada_atual; i++) {
    tone(pinoAudio, tons[sequencia[i]]);
    digitalWrite(pinosLeds[sequencia[i]], HIGH);
    delay(500);
    noTone(pinoAudio);
    digitalWrite(pinosLeds[sequencia[i]], LOW);
    delay(100);
  }
  noTone(pinoAudio);
}
 
// Aguarda o jogador iniciar sua jogada.
void aguardarJogador() {
  for (int i = 0; i < rodada_atual; i++) {
    aguardarJogada();
   
  // verifica a jogada  
  if (sequencia[passo_atual_na_sequencia] != botao_pressionado) {
      gameOver(); // perdeu
   }
   
   // para o jogo se perdeu
    if (perdeu_o_jogo) {
      break;
    }
     passo_atual_na_sequencia++;
  }
 
  // Redefine a variável para 0.
  passo_atual_na_sequencia = 0;
}
 
void aguardarJogada() {
  boolean jogada_efetuada = false;
  while (!jogada_efetuada) {
    for (int i = 0; i <= 3; i++) {
      if (!digitalRead(pinosBotoes[i])) {
        // Dizendo qual foi o botao pressionado.
        botao_pressionado = i;
 
        tone(pinoAudio, tons[i]);
        digitalWrite(pinosLeds[i], HIGH);
        delay(300);
        digitalWrite(pinosLeds[i], LOW);
        noTone(pinoAudio);
 
        jogada_efetuada = true;
      }
    }
    delay(10);
  }
}
 
void gameOver() {
    // GAME OVER.
    for (int i = 0; i <= 3; i++) {
      tone(pinoAudio, tons[i]);
      digitalWrite(pinosLeds[i], HIGH);
      delay(200);
      digitalWrite(pinosLeds[i], LOW);
      noTone(pinoAudio);
    }
 
    tone(pinoAudio, tons[3]);
    for (int i = 0; i <= 3; i++) {
      digitalWrite(pinosLeds[0], HIGH);
      digitalWrite(pinosLeds[1], HIGH);
      digitalWrite(pinosLeds[2], HIGH);
      digitalWrite(pinosLeds[3], HIGH);
      delay(100);
      digitalWrite(pinosLeds[0], LOW);
      digitalWrite(pinosLeds[1], LOW);
      digitalWrite(pinosLeds[2], LOW);
      digitalWrite(pinosLeds[3], LOW);
      delay(100);
    }
    noTone(pinoAudio);
 
    perdeu_o_jogo = true;  
}
 
void tocarSomDeInicio() {
  tone(pinoAudio, tons[0]);
  digitalWrite(pinosLeds[0], HIGH);
  digitalWrite(pinosLeds[1], HIGH);
  digitalWrite(pinosLeds[2], HIGH);
  digitalWrite(pinosLeds[3], HIGH);
  delay(500);
  digitalWrite(pinosLeds[0], LOW);
  digitalWrite(pinosLeds[1], LOW);
  digitalWrite(pinosLeds[2], LOW);
  digitalWrite(pinosLeds[3], LOW);
  delay(500);
  noTone(pinoAudio);
} 

A Importância da Memória no Projeto

  1. Armazenamento da Sequência

    • O Arduino possui memória SRAM (volátil) e Flash (para o programa).

    • array sequencia[100] ocupa espaço na SRAM, então é importante otimizar seu uso para evitar estouro.

  2. Eficiência no Uso de Recursos

    • Sistemas embarcados têm memória limitada, então é crucial usar estruturas de dados eficientes.

    • Se a sequência fosse armazenada em uma EEPROM, ela persistiria mesmo após desligar o Arduino.

  3. Processamento em Tempo Real

    • O jogo precisa lembrar a sequência enquanto aguarda a resposta do jogador, demonstrando como a memória de trabalho (RAM) é essencial para aplicações interativas.


Aplicações no Contexto Escolar

  1. Desenvolvimento do Raciocínio Lógico

    • A programação do Genius estimula o pensamento algorítmico e a resolução de problemas.

  2. Aprendizado sobre Eletrônica e Computação

    • Os alunos entendem como a memória funciona em dispositivos reais, conectando teoria à prática.

  3. Interdisciplinaridade

    • Pode ser usado em aulas de Matemática (sequências lógicas), Física (circuitos elétricos) e Psicologia (testes de memória).

  4. Preparação para a Indústria 4.0

    • Conhecimento em Arduino e memória é útil em robóticaIoT e automação, áreas em alta no mercado.


Conclusão

Criar o jogo do Genius com Arduino é um projeto divertido e educativo que ensina programação, eletrônica e gerenciamento de memória. No ambiente escolar, esse tipo de atividade promove o pensamento computacional e prepara os alunos para desafios tecnológicos futuros.

Experimente montar seu próprio Genius e explore diferentes variações, como aumentar a velocidade ou adicionar mais LEDs!

🔹 Dica para professores: Use esse projeto em oficinas de robótica e mostre como a tecnologia está presente no cotidiano!

Gostou? Compartilhe e comente suas experiências! 🚀

Comentários

Postagens mais visitadas