/*
JOGO DA MEMORIA - COM ARDUINO E SERIAL
Mirian Bronzati RM555041
Nicollas Guedes RM556850
inspirado em: http://jeknowledge.github.io/academy-articles/jogo-da-memoria
*/
// Variáveis Globais
String recebido;
String sequenciaNumerica = "";
int ordemLeds[50]; // Armazena a sequência gerada
int pontuacoes[10]; // Armazena as últimas 10 pontuações
int maiorPontuacao = 0;
int indicePontuacao = 0;
const int LED_PINS[] = {11, 10, 9, 8}; // Pino dos leds
const int BUTTON_PINS[] = {5, 4, 3, 2}; // Pino dos botões
const int BUZZER_PIN = 6; // Pino do buzzer
const long SERIAL_TIMEOUT = 5000;
const int NUM_LEDS = sizeof(LED_PINS) / sizeof(LED_PINS[0]);
const int NUM_BUTTONS = sizeof(BUTTON_PINS) / sizeof(BUTTON_PINS[0]);
int sequencia;
int nivel = 1;
int velocidade = 1000;
enum GameState {
START_GAME,
LEVEL,
GAME_OVER,
PLAY_AGAIN
};
GameState stateGame = START_GAME;
void setup() {
Serial.begin(9600);
for(int i = 0; i < NUM_LEDS; i++){
pinMode(LED_PINS[i], OUTPUT);
}
for(int i = 0; i < NUM_BUTTONS; i++){
pinMode(BUTTON_PINS[i], INPUT_PULLUP);
}
pinMode(BUZZER_PIN, OUTPUT);
randomSeed(analogRead(0));
}
void loop() {
switch (stateGame) {
case START_GAME:
Serial.println("* INICIO *");
Serial.println("Sua maior pontuação atual é de: " + String(maiorPontuacao));
Serial.println("Escolha a dificuldade: (f) Fácil, (m) Médio, (d) Difícil");
leserial();
if (recebido.equalsIgnoreCase("f")) {
velocidade = 1000;
sequencia = 1;
} else if (recebido.equalsIgnoreCase("m")) {
velocidade = 500;
sequencia = 2;
} else if (recebido.equalsIgnoreCase("d")) {
velocidade = 300;
sequencia = 3;
} else {
Serial.println("Opção inválida, tente novamente.");
return;
}
Serial.println("Jogo começando...");
piscaled(500, 2);
gerarNovaSequencia();
stateGame = LEVEL;
break;
case LEVEL:
Serial.println("* Nível " + String(nivel) + " *");
exibirSequencia(velocidade, sequencia);
leserial();
if (recebido.equals(sequenciaNumerica)) {
Serial.println("Parabéns! Próximo nível.");
piscaled(500, 2);
sequencia++;
nivel++;
} else {
stateGame = GAME_OVER;
Serial.println("Errooooo!!!");
piscaled(300, 5);
}
break;
case GAME_OVER:
pontuacoes[indicePontuacao] = nivel;
if (nivel > maiorPontuacao) {
maiorPontuacao = nivel;
}
indicePontuacao = (indicePontuacao + 1) % 10;
Serial.println("Game Over");
Serial.println("Sua maior pontuação atual é: " + String(maiorPontuacao));
piscaled(100, 5);
stateGame = PLAY_AGAIN;
break;
case PLAY_AGAIN:
Serial.println("Jogar novamente? (s/n)");
leserial();
if (recebido.equalsIgnoreCase("s")){
stateGame = START_GAME;
nivel = 1;
} else {
Serial.println("Jogo encerrado.");
while(true);
}
break;
}
}
void leserial(){
Serial.println("* Insira sua resposta *");
recebido = "";
long startTime = millis();
while (millis() - startTime < SERIAL_TIMEOUT) {
if (Serial.available()) {
recebido = Serial.readString();
recebido.trim();
Serial.println(recebido);
return;
}
for (int i = 0; i < NUM_BUTTONS; i++) {
if (digitalRead(BUTTON_PINS[i]) == LOW) {
tocarSom(i);
recebido += String(i + 1);
Serial.println("Botão " + String(i + 1) + " pressionado");
delay(300);
}
}
}
if (recebido == "") {
Serial.println("Timeout! Resposta não recebida.");
}
}
void piscaled(int tempo, int vezes){
for(int i = 0; i < vezes; i++){
for(int j = 0; j < NUM_LEDS; j++){
digitalWrite(LED_PINS[j], HIGH);
tocarSom(j);
}
delay(tempo);
for(int j = 0; j < NUM_LEDS; j++){
digitalWrite(LED_PINS[j], LOW);
}
delay(tempo);
}
}
void gerarNovaSequencia() {
for (int i = 0; i < 50; i++) {
ordemLeds[i] = random(1, NUM_LEDS + 1);
}
}
void exibirSequencia(int tempo, int tamanho){
sequenciaNumerica = "";
for (int j = 0; j < tamanho; j++){
int ledIndex = ordemLeds[j] - 1;
digitalWrite(LED_PINS[ledIndex], HIGH);
tocarSom(ledIndex);
delay(tempo);
digitalWrite(LED_PINS[ledIndex], LOW);
delay(tempo);
sequenciaNumerica += String(ordemLeds[j]);
}
}
void tocarSom(int ledIndex) {
int frequencias[] = {262, 330, 392, 523}; // Notas para cada LED/botão
tone(BUZZER_PIN, frequencias[ledIndex], 200);
}