#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#define RED_LED_PIN 11
#define GREEN_LED_PIN 2
#define BLUE_LED_PIN 5
#define YELLOW_LED_PIN 3
#define RED_BUTTON_PIN 15
#define GREEN_BUTTON_PIN 27
#define BLUE_BUTTON_PIN 6
#define YELLOW_BUTTON_PIN 1
#define SEQUENCE_LENGTH 10
#define DEBOUNCE_TIME_MS 500
volatile absolute_time_t last_time_pressed_ms = 0;
volatile bool button_pressed = false;
typedef enum {
RED,
GREEN,
BLUE,
YELLOW,
} Color;
volatile Color color_pressed = -1;
void flash_led(Color color) {
switch (color) {
case RED:
gpio_put(RED_LED_PIN, 1);
sleep_ms(500);
gpio_put(RED_LED_PIN, 0);
break;
case GREEN:
gpio_put(GREEN_LED_PIN, 1);
sleep_ms(500);
gpio_put(GREEN_LED_PIN, 0);
break;
case BLUE:
gpio_put(BLUE_LED_PIN, 1);
sleep_ms(500);
gpio_put(BLUE_LED_PIN, 0);
break;
case YELLOW:
gpio_put(YELLOW_LED_PIN, 1);
sleep_ms(500);
gpio_put(YELLOW_LED_PIN, 0);
break;
}
}
void irq_handler(uint gpio, uint32_t events) {
absolute_time_t current_time = get_absolute_time();
if (absolute_time_diff_us(last_time_pressed_ms, current_time) > DEBOUNCE_TIME_MS * 1000) {
last_time_pressed_ms = current_time;
button_pressed = true;
} else {
return;
}
switch (gpio) {
case RED_BUTTON_PIN:
printf("Red button pressed\n");
color_pressed = RED;
break;
case GREEN_BUTTON_PIN:
printf("Green button pressed\n");
color_pressed = GREEN;
break;
case BLUE_BUTTON_PIN:
printf("Blue button pressed\n");
color_pressed = BLUE;
break;
case YELLOW_BUTTON_PIN:
printf("Yellow button pressed\n");
color_pressed = YELLOW;
break;
}
}
Color get_random_color() {
return (Color)(rand() % 4);
}
Color* generate_sequence() {
static Color sequence[SEQUENCE_LENGTH];
for (int i = 0; i < SEQUENCE_LENGTH; i++) {
sequence[i] = get_random_color();
}
return sequence;
}
typedef enum {
PLAYING,
LOST,
WON
} GameState;
typedef struct {
GameState state;
Color* sequence;
int sequence_index;
} Game;
void reset_game(Game* game) {
game->state = PLAYING;
game->sequence = generate_sequence();
game->sequence_index = 0;
}
void play_game(Game* game) {
while (game->state == PLAYING) {
for (int i = 0; i < game->sequence_index; i++) {
flash_led(game->sequence[i]);
sleep_ms(500);
}
for (int i = 0; i < game->sequence_index; i++) {
while (!button_pressed);
printf("Button pressed\n");
button_pressed = false;
if (color_pressed == game->sequence[i]) {
flash_led(color_pressed);
sleep_ms(500);
} else {
game->state = LOST;
printf("You lost!\n");
for (int i = 0; i < 3; i++) {
flash_led(RED);
flash_led(GREEN);
flash_led(BLUE);
flash_led(YELLOW);
}
break;
}
}
game->sequence_index++;
if (game->sequence_index == SEQUENCE_LENGTH) {
printf("You won!\n");
game->state = WON;
}
}
}
void setup() {
stdio_init_all();
gpio_init(RED_LED_PIN);
gpio_set_dir(RED_LED_PIN, GPIO_OUT);
gpio_init(GREEN_LED_PIN);
gpio_set_dir(GREEN_LED_PIN, GPIO_OUT);
gpio_init(BLUE_LED_PIN);
gpio_set_dir(BLUE_LED_PIN, GPIO_OUT);
gpio_init(YELLOW_LED_PIN);
gpio_set_dir(YELLOW_LED_PIN, GPIO_OUT);
gpio_init(RED_BUTTON_PIN);
gpio_set_dir(RED_BUTTON_PIN, GPIO_IN);
gpio_pull_up(RED_BUTTON_PIN);
gpio_init(GREEN_BUTTON_PIN);
gpio_set_dir(GREEN_BUTTON_PIN, GPIO_IN);
gpio_pull_up(GREEN_BUTTON_PIN);
gpio_init(BLUE_BUTTON_PIN);
gpio_set_dir(BLUE_BUTTON_PIN, GPIO_IN);
gpio_pull_up(BLUE_BUTTON_PIN);
gpio_init(YELLOW_BUTTON_PIN);
gpio_set_dir(YELLOW_BUTTON_PIN, GPIO_IN);
gpio_pull_up(YELLOW_BUTTON_PIN);
gpio_set_irq_enabled_with_callback(RED_BUTTON_PIN, GPIO_IRQ_EDGE_RISE, true, irq_handler);
gpio_set_irq_enabled(GREEN_BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true);
gpio_set_irq_enabled(BLUE_BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true);
gpio_set_irq_enabled(YELLOW_BUTTON_PIN, GPIO_IRQ_EDGE_FALL, true);
}
int main()
{
setup();
Game game = {PLAYING, generate_sequence(), 0};
while (true) {
printf("Starting game\n");
reset_game(&game);
play_game(&game);
printf("Game over\n");
}
}