From f306ca33c033c876c9b9e1806068c3b4f365ee81 Mon Sep 17 00:00:00 2001
From: Malte Schmitz <malte@schmitz-sh.de>
Date: Sun, 29 May 2022 17:19:08 +0200
Subject: [PATCH] Add green and levels

---
 src/main.cpp | 148 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 119 insertions(+), 29 deletions(-)

diff --git a/src/main.cpp b/src/main.cpp
index a222598..f5e556b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,6 +21,14 @@ void handleButton();
 Task taskButton(TASK_IMMEDIATE, TASK_FOREVER, &handleButton);
 void handleStep();
 Task taskStep(25, TASK_FOREVER, &handleStep);
+void handleInternalLostAnimation();
+Task taskInternalLostAnimation(10, 100, &handleInternalLostAnimation);
+void handleExternalLostAnimation();
+Task taskExternalLostAnimation(10, 100, &handleExternalLostAnimation);
+
+void doneLostAnimation();
+void internalMissed();
+void externalMissed();
 
 void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
@@ -39,6 +47,10 @@ void setup() {
   taskButton.enable();
   scheduler.addTask(taskStep);
   taskStep.enable();
+  scheduler.addTask(taskExternalLostAnimation);
+  taskExternalLostAnimation.setOnDisable(&doneLostAnimation);
+  scheduler.addTask(taskInternalLostAnimation);
+  taskInternalLostAnimation.setOnDisable(&doneLostAnimation);
 }
 
 void loop() {
@@ -46,78 +58,156 @@ void loop() {
 }
 
 int position = 0;
-int last_internal_button_state = HIGH;
-int last_external_button_state = HIGH;
-unsigned long last_internal_button_pressed = 0;
-unsigned long last_external_button_pressed = 0;
+int greenLength = 10;
 
 #define STATE_PAUSE 0
 #define STATE_FORWARD 1
 #define STATE_BACKWARD 2
+#define STATE_LOST 3;
 int state = STATE_PAUSE;
 
 void show() {
   for (int i = 0; i < NEOPIXEL_LEN; i++) {
     pixels.setPixelColor(i, 0);
   }
-  if (state > STATE_PAUSE) {
+  if (state == STATE_FORWARD || state == STATE_BACKWARD) {
+    for (int i = 0; i < greenLength; i++) {
+      pixels.setPixelColor(i, 0x00FF00);
+    }
+    for (int i = NEOPIXEL_LEN - greenLength - 1; i < NEOPIXEL_LEN; i++) {
+      pixels.setPixelColor(i, 0x00FF00);
+    }
     pixels.setPixelColor(position, 0xFFFFFF);
   }
   pixels.show();
 }
 
+int currentRound = 0;
+#define MAX_LEVEL 10
+int greenLengths[] =  {10,10, 9, 8, 7, 6, 5, 5, 4, 4, 3};
+int stepIntervals[] = {25,25,20,18,16,14,12,10,10,10,10};
+
+void setRound(int newRound) {
+  currentRound = newRound;
+  int level = min(currentRound / 2, MAX_LEVEL);
+  greenLength = greenLengths[level];
+  taskStep.setInterval(stepIntervals[level]);
+}
+
+void nextRound() {
+  setRound(currentRound + 1);
+}
+
+void firstRound() {
+  setRound(0);
+}
+
+void internalButtonPressed() {
+  if (state == STATE_PAUSE) {
+    state = STATE_FORWARD;
+    position = 0;
+    firstRound();
+  } else if (state == STATE_BACKWARD) {
+    if (position < greenLength) {
+      state = STATE_FORWARD;
+      nextRound();
+    } else {
+      internalMissed();
+    }
+  }
+}
+
+void externalButtonPressed() {
+  if (state == STATE_PAUSE) {
+    state = STATE_BACKWARD;
+    position = NEOPIXEL_LEN - 1;
+    firstRound();
+  } else if (state == STATE_FORWARD) {
+    if (position >= NEOPIXEL_LEN - greenLength) {
+      state = STATE_BACKWARD;
+      nextRound();
+    } else {
+      externalMissed();
+    }
+  }
+}
+
+int last_internal_button_state = HIGH;
+int last_external_button_state = HIGH;
+
 void handleButton() {
   int current_internal_button_state = digitalRead(INTERNAL_BUTTON_PIN_B);
   int current_external_button_state = digitalRead(EXTERNAL_BUTTON_PIN_B);
 
   if (last_internal_button_state == HIGH && current_internal_button_state == LOW) {
-    last_internal_button_pressed = millis();
+    internalButtonPressed();
   }
 
   if (last_external_button_state == HIGH && current_external_button_state == LOW) {
-    last_external_button_pressed = millis();
+    externalButtonPressed();
   }
 
   last_internal_button_state = current_internal_button_state;
   last_external_button_state = current_external_button_state;
 }
 
+void handleExternalLostAnimation() {
+    int step = (100 - taskExternalLostAnimation.getIterations()) % 25;
+    for (int i = 0; i < NEOPIXEL_LEN; i++) {
+      pixels.setPixelColor(i, 0);
+    }
+    for (int i = NEOPIXEL_LEN - 1 - 25; i < NEOPIXEL_LEN - 25 + step; i++) {
+      pixels.setPixelColor(i, 0xFF0000);
+    }
+    pixels.show();
+}
+
+void handleInternalLostAnimation() {
+    int step = (100 - taskInternalLostAnimation.getIterations()) % 25;
+    for (int i = 0; i < NEOPIXEL_LEN; i++) {
+      pixels.setPixelColor(i, 0);
+    }
+    for (int i = 25 - step; i < 25; i++) {
+      pixels.setPixelColor(i, 0xFF0000);
+    }
+    pixels.show();
+}
+
+void externalMissed() {
+  state = STATE_LOST;
+  taskExternalLostAnimation.restart();
+}
+
+void internalMissed() {
+  state = STATE_LOST;
+  taskInternalLostAnimation.restart();
+}
+
+void doneLostAnimation() {
+  state = STATE_PAUSE;
+}
+
 void handleStep() {
   unsigned long now = millis();
   switch (state) {
     case STATE_PAUSE:
-      if (now - last_internal_button_pressed < 100) {
-        position = 0;
-        state = STATE_FORWARD;
-      }
-      if (now - last_external_button_pressed < 100) {
-        position = NEOPIXEL_LEN - 1;
-        state = STATE_BACKWARD;
-      }
+      show();
       break;
     case STATE_FORWARD:
       position = position + 1;
       if (position > NEOPIXEL_LEN - 1) {
-        if (now - last_external_button_pressed < 100) {
-          position = position - 2;
-          state = STATE_BACKWARD;
-        } else {
-          state = STATE_PAUSE;
-        }
+        externalMissed();
+      } else {
+        show();
       }
       break;
     case STATE_BACKWARD:
       position = position - 1;
       if (position < 0) {
-        if (now - last_internal_button_pressed < 100) {
-          position = 1;
-          state = STATE_FORWARD;
-        } else {
-          state = STATE_PAUSE;
-        }
+        internalMissed();
+      } else {
+        show();
       }
       break;
   }
-
-  show();
 }
-- 
GitLab