#include "pico/stdlib.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define LED1_PIN 0  // LED Vermelho
#define LED2_PIN 1  // LED Azul
#define LED3_PIN 2  // LED Verde
#define LED4_PIN 3  // LED Amarelo

// Botões associados às cores
#define BUTTON1_PIN 4  // Botão associado ao LED vermelho
#define BUTTON2_PIN 5  // Botão associado ao LED azul
#define BUTTON3_PIN 6  // Botão associado ao LED verde
#define BUTTON4_PIN 7  // Botão associado ao LED amarelo

#define BUZZER_PIN 15

// Função para tocar um som com o buzzer
void play_tone(uint pin, uint32_t frequency, uint32_t duration) {
    gpio_put(pin, 1);  // Ativa o buzzer
    sleep_ms(duration);
    gpio_put(pin, 0);  // Desativa o buzzer
}

// Função de início do jogo
void play_start_sound() {
    play_tone(BUZZER_PIN, 1000, 500); // Som de início
}

// Função de som de acerto
void play_success_sound() {
    play_tone(BUZZER_PIN, 1500, 200); // Som de sucesso
}

// Função de som de erro
void play_error_sound() {
    play_tone(BUZZER_PIN, 500, 500); // Som de erro
}

// Função de som do LED correspondente
void play_led_sound(int led_num) {
    switch (led_num) {
        case 0:
            play_tone(BUZZER_PIN, 1000, 200); // Som do LED vermelho
            break;
        case 1:
            play_tone(BUZZER_PIN, 1200, 200); // Som do LED azul
            break;
        case 2:
            play_tone(BUZZER_PIN, 1400, 200); // Som do LED verde
            break;
        case 3:
            play_tone(BUZZER_PIN, 1600, 200); // Som do LED amarelo
            break;
    }
}

// Função para escolher um LED aleatório
int get_random_led() {
    return rand() % 4;  // Gera um número aleatório entre 0 e 3 (4 LEDs)
}

// Função para inicializar os LEDs e garantir que todos os LEDs sejam apagados
void clear_leds() {
    gpio_put(LED1_PIN, 0);
    gpio_put(LED2_PIN, 0);
    gpio_put(LED3_PIN, 0);
    gpio_put(LED4_PIN, 0);
}

// Função para verificar se o jogador acertou toda a sequência
bool check_sequence(int* sequence, int sequence_length, int* player_input, int player_input_length) {
    if (sequence_length != player_input_length) {
        return false;  // Se o tamanho da sequência não for igual ao tamanho da entrada do jogador
    }

    for (int i = 0; i < sequence_length; i++) {
        if (sequence[i] != player_input[i]) {
            return false;  // Se qualquer LED não corresponder, o jogador errou
        }
    }

    return true;  // Se todos os LEDs corresponderem, o jogador acertou a sequência
}

int main() {
    stdio_init_all();

    // Inicializar pinos de LEDs como saída
    gpio_init(LED1_PIN);
    gpio_set_dir(LED1_PIN, GPIO_OUT);
    gpio_init(LED2_PIN);
    gpio_set_dir(LED2_PIN, GPIO_OUT);
    gpio_init(LED3_PIN);
    gpio_set_dir(LED3_PIN, GPIO_OUT);
    gpio_init(LED4_PIN);
    gpio_set_dir(LED4_PIN, GPIO_OUT);

    // Inicializar botões como entrada
    gpio_init(BUTTON1_PIN);
    gpio_set_dir(BUTTON1_PIN, GPIO_IN);
    gpio_init(BUTTON2_PIN);
    gpio_set_dir(BUTTON2_PIN, GPIO_IN);
    gpio_init(BUTTON3_PIN);
    gpio_set_dir(BUTTON3_PIN, GPIO_IN);
    gpio_init(BUTTON4_PIN);
    gpio_set_dir(BUTTON4_PIN, GPIO_IN);

    // Inicializar buzzer
    gpio_init(BUZZER_PIN);
    gpio_set_dir(BUZZER_PIN, GPIO_OUT);

    // Inicializar gerador de números aleatórios
    srand(time(NULL));

    // Sequência de LEDs que o jogador deve seguir
    int sequence[10];  // Sequência com até 10 LEDs
    int sequence_length = 0;
    int player_input[10];  // Armazena as entradas do jogador
    int player_input_length = 0;

    // Jogo principal
    while (true) {
        // Etapa 1: Tocar som de início
        play_start_sound();
        sleep_ms(1000);  // Aguardar o som de início

        // Etapa 2: Gerar a próxima sequência de LEDs
        sequence[sequence_length] = get_random_led();  // Gera um LED aleatório (apenas 4 LEDs possíveis)
        sequence_length++;  // Aumenta o tamanho da sequência

        // Etapa 3: Acender a sequência de LEDs e tocar os sons
        for (int i = 0; i < sequence_length; i++) {
            clear_leds();  // Apaga todos os LEDs antes de acender um novo
            switch (sequence[i]) {
                case 0:
                    gpio_put(LED1_PIN, 1);  // Acende LED vermelho
                    break;
                case 1:
                    gpio_put(LED2_PIN, 1);  // Acende LED azul
                    break;
                case 2:
                    gpio_put(LED3_PIN, 1);  // Acende LED verde
                    break;
                case 3:
                    gpio_put(LED4_PIN, 1);  // Acende LED amarelo
                    break;
            }
            play_led_sound(sequence[i]);  // Toca o som do LED
            sleep_ms(500);  // LED aceso por 500ms
            clear_leds();  // Apagar todos os LEDs
            sleep_ms(250);  // Intervalo entre os LEDs
        }

        // Etapa 4: Espera pela resposta do jogador
        bool correct_sequence = false;
        player_input_length = 0;

        while (!correct_sequence && player_input_length < sequence_length) {
            int button_pressed_index = -1;
            if (gpio_get(BUTTON1_PIN)) {
                button_pressed_index = 0;  // Botão 1 -> LED Vermelho
            } else if (gpio_get(BUTTON2_PIN)) {
                button_pressed_index = 1;  // Botão 2 -> LED Azul
            } else if (gpio_get(BUTTON3_PIN)) {
                button_pressed_index = 2;  // Botão 3 -> LED Verde
            } else if (gpio_get(BUTTON4_PIN)) {
                button_pressed_index = 3;  // Botão 4 -> LED Amarelo
            }

            if (button_pressed_index != -1) {
                // Armazena a entrada do jogador
                player_input[player_input_length] = button_pressed_index;
                player_input_length++;

                // Acende o LED correspondente e toca o som
                clear_leds();
                switch (button_pressed_index) {
                    case 0:
                        gpio_put(LED1_PIN, 1);
                        play_led_sound(0);  // LED Vermelho
                        break;
                    case 1:
                        gpio_put(LED2_PIN, 1);
                        play_led_sound(1);  // LED Azul
                        break;
                    case 2:
                        gpio_put(LED3_PIN, 1);
                        play_led_sound(2);  // LED Verde
                        break;
                    case 3:
                        gpio_put(LED4_PIN, 1);
                        play_led_sound(3);  // LED Amarelo
                        break;
                }

                // Verifica se o jogador acertou a sequência até agora
                correct_sequence = check_sequence(sequence, sequence_length, player_input, player_input_length);

                if (correct_sequence) {
                    // Se o jogador acertou a sequência, toca o som de sucesso
                    play_success_sound();
                    sleep_ms(1000);  // Aguarda para reiniciar o jogo
                } else if (player_input_length == sequence_length) {
                    // Se o jogador errou ao completar a sequência
                    play_error_sound();
                    sleep_ms(1000);  // Aguarda para reiniciar o jogo
                }
            }
        }
    }

    return 0;
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT