uint8_t buttons_pin[4] = { 9, 5, 10, 4 };
uint8_t leds_pin[4] = { 11, 3, 12, 2 };
uint16_t buttons_tone[4] = { 440.00, 392.00, 349.23, 329.63 };
uint16_t game_over_tone[4] = { 261.63, 246.96, 233.08, 220.00 };
#define MAX_LEVEL 50
uint8_t level = 0;
int8_t life = 4;
uint8_t input_id = 0;
uint8_t task[MAX_LEVEL];
void setup() {
Serial.begin(115200);
Serial.println("Game start!");
for(int8_t i = 0; i < 4; i++)
{
pinMode(buttons_pin[i], INPUT_PULLUP);
pinMode(leds_pin[i], OUTPUT);
digitalWrite(leds_pin[i], LOW);
}
}
void PlayLedsIntro()
{
for(uint8_t ii = 0; ii < 3; ii++)
{
const uint8_t time = 100;
LedOn(0, time, 20);
LedOn(1, time, 20);
LedOn(3, time, 20);
LedOn(2, time, 20);
}
}
void LedOn(const uint8_t led_id, const uint16_t time_on, const uint16_t time_wait_off)
{
digitalWrite(leds_pin[led_id], HIGH);
delay(time_on);
digitalWrite(leds_pin[led_id], LOW);
delay(time_wait_off);
}
void PlayLedsTask()
{
const uint8_t time_out = (level * 5) < 120 ? 200 - (level * 5) : 80;
for (uint8_t i = 0; i <= level; i++)
{
tone(13, buttons_tone[task[i]], 200);
LedOn(task[i], 200, time_out);
}
}
void PlayLedsLoss()
{
for (uint8_t ii = 0; ii < 3; ii++)
{
for (uint8_t i = 0; i < life; i++)
{
digitalWrite(leds_pin[i], HIGH);
}
tone(13, game_over_tone[0], 200);
delay(200);
for (uint8_t i = 0; i < 4; i++)
{
digitalWrite(leds_pin[i], LOW);
}
delay(200);
}
}
void GameOver()
{
for(uint8_t ii = 0; ii < 5; ii++)
{
const uint8_t time = 100;
LedOn(0, time, 20);
LedOn(2, time, 20);
LedOn(3, time, 20);
LedOn(1, time, 20);
}
for (uint8_t i = 0; i < 4; i++)
{
tone(13, game_over_tone[i], 500);
for(int8_t i = 0; i < 4; i++)
{
digitalWrite(leds_pin[i], HIGH);
}
delay(250);
for(int8_t i = 0; i < 4; i++)
{
digitalWrite(leds_pin[i], LOW);
}
delay(250);
}
input_id = 0;
level = 0;
life = 4;
}
void loop() {
PlayLedsIntro();
delay(1000);
PlayLedsTask();
for (;;)
{
for (uint8_t id = 0; id < 4; id++)
{
if (digitalRead(buttons_pin[id]) != LOW)
continue;
tone(13, buttons_tone[id], 200);
LedOn(id, 100, 100);
if (id == task[input_id])
{
input_id++;
if (input_id > level)
{
level++;
if( level >= MAX_LEVEL)
{
GameOver();
return;
}
task[level] = random(0, 4);
input_id = 0;
delay(1000);
PlayLedsTask();
}
}
else
{
if (life > 0)
{
delay(200);
PlayLedsLoss();
input_id = 0;
life --;
delay(1000);
PlayLedsTask();
break;
}
else
{
GameOver();
return;
}
}
}
}
}