// Random Sticks are Falling Down...
// https://forum.arduino.cc/t/i-need-your-help-with-an-urgent-matter-friends/1425296/
// ==================================================
// LEVEL - edit game level below to 1, 2, or 3
// ==================================================
int level = 1; // current level
// ==================================================
#include <Adafruit_NeoPixel.h> // https://github.com/adafruit/Adafruit_NeoPixel
#define NUM_LEDS 30 // assuming WS2812
#define PIN_LEDS 11
Adafruit_NeoPixel strip_pin11 = Adafruit_NeoPixel(NUM_LEDS, PIN_LEDS, NEO_GRB + NEO_KHZ800);
#define BRIGHT 255 // set brightness for your hardware (and eyes)
// button
bool lastButtonRead, currentButtonState; // states
unsigned long timer, timeout = 50; // timers
#define BUTTON_PIN A0 // DIO 14
// magnets
int magnetPin[] = {10, 9, 8, 7, 6, 5, 4, 3};
int random_time, random_stick, stick[8]; // stick stuff
int levelStartDelay[] = {1000, 1000, 500}; // start for levels 1, 2, 3
int levelDuration[] = {4000, 3000, 5000}; // duration for levels 1, 2, 3
bool start = 0; // start flag 0 = "do not start"
bool doNotExit = 1; // level 2/3 exit flag, 1 = "do not exit"
void setup() {
Serial.begin(115200);
randomSeed(analogRead(A3));
pinMode(BUTTON_PIN, INPUT_PULLUP);
for (int i = 0; i < 8; i++) {
digitalWrite(i + 3, LOW); // set magnet pins "OFF"
pinMode(i + 3, OUTPUT); // set magnet pins direction
stick[i] = true; // set all sticks to "inserted"
}
strip_pin11.begin();
strip_pin11.clear();
strip_pin11.show();
endgame(); // LED flurish
startgame();
}
void loop() {
readButton();
if (start) { // start flag set when button is pressed
doNotExit = 1; // level 2/3. for exiting while() loop after all sticks have dropped
Serial.print(" Level ");
Serial.print(level);
Serial.print(" started!");
start = 0; // reset start state to "do not start"
switch (level) {
case (1): level1(); break;
case (2): // level 2 and 3 use same function with different delay start and duration.
case (3): level23(); break;
default: break;
}
Serial.print(" Level ");
Serial.print(level);
Serial.println(" complete!");
endgame(); // end game
startgame(); // restart game
}
}
// ==================================================
// LEVEL
// ==================================================
void level1() {
int levelOrder[] = {5, 9, 6, 3, 7, 10, 4, 8}; // pseudo-random order of magnet pins
for (int i = 0; i < 8; i++) {
random_time = random(levelStartDelay[level - 1], levelDuration[level - 1]);
delay(random_time ); // level 1 delay
light((levelOrder[i] - 3) * 4, BRIGHT, 0, 0); // find LED from levelOrder (magnetPin)
magnet((levelOrder[i] - 3), 0); // find magnetPin from levelOrder
}
}
void level23() {
while (doNotExit) { // flag set (1) to stay in while() loop until all sticks are dropped
random_stick = random(8); // pick a stick
if (stick[random_stick] == true) { // if stick state is "inserted"
stick[random_stick] = false; // make stick fall
random_time = random(levelStartDelay[level - 1], levelDuration[level - 1]);
delay(random_time); // this level's duration
light(random_stick * 4, BRIGHT, 0, 0); // light LED pairs start every 4th LED
magnet(random_stick, 0); // release random_stick magnet
}
if (!stick[0] && !stick[1] && !stick[2] && !stick[3] && !stick[4] && !stick[5] && !stick[6] && !stick[7]) {
doNotExit = 0; // exit this level
}
}
for (int i = 0; i < 8; i++) // reset all stick flags to "inserted"
stick[i] = true; // I'll try not to delete this part while testing again.
}
// ==================================================
// STARTUP
// ==================================================
void startgame() {
subprogram1(); // red
subprogram0(); // grn
setMagnets(1); // energized
Serial.print("Level ");
Serial.print(level);
Serial.print(". Insert sticks, press START button.");
}
void subprogram0() {
delay(1000);
for (int i = 0; i < NUM_LEDS; i += 4) {
light(i, 0, BRIGHT, 0); // GRN
}
}
void subprogram1() {
delay(1000);
for (int i = 0; i < NUM_LEDS; i += 4) {
light(i, BRIGHT, 0, 0); // RED
}
}
void endgame() {
delay(1000);
for (int i = 0; i < 20; i++) {
for (int j = 0; j < NUM_LEDS; j++) { // setting colors to primary and secondary only: RGBCYM
strip_pin11.setPixelColor(j, 255 * random(2), 255 * random(2), 255 * random(2));
strip_pin11.show();
delay(5);
}
}
strip_pin11.clear();
strip_pin11.show();
}
// ==================================================
// UTILITY
// ==================================================
void clearLEDs() { // Adafruit recognizes a broken strip.clear() method
delay(1000);
for (int i = 0; i < NUM_LEDS; i += 2) {
light(i, 0, 0, 0);
}
}
void light(int firstLED, int red, int grn, int blu) {
strip_pin11.setPixelColor(firstLED + 0, red, grn, blu );
strip_pin11.setPixelColor(firstLED + 1, red, grn, blu );
strip_pin11.show();
}
void setMagnets(bool state) { // on = 1, off = 0
delay(1000);
for (int i = 0; i < 8; i++) {
magnet(i, state);
}
}
void magnet(int pinElement, bool state) { // magnet, on = 1, off = 0
digitalWrite(magnetPin[pinElement], state);
}
void readButton() {
bool currentButtonRead = digitalRead(BUTTON_PIN); // read button pin
if (currentButtonRead != lastButtonRead) { // if button pin changes...
timer = millis(); // ...start a timer
lastButtonRead = currentButtonRead; // ... and store current state
}
if ((millis() - timer) > timeout) { // if button change was longer than debounce timeout
if (currentButtonState == HIGH && lastButtonRead == LOW) { // ... and State is "RELEASED" while Button Read was "PRESSED"
start = 1; // start flag. button pressed and released
}
currentButtonState = currentButtonRead; // update button state
}
}