// https://forum.arduino.cc/t/toggle-switch-puzzle-but-sequential/1091460/48
// https://wokwi.com/projects/358275335864559617
# define PSIZE 7 // puzzle size
# include <Adafruit_NeoPixel.h>
# define LED_PIN A2
# define LED_COUNT PSIZE
Adafruit_NeoPixel disaply(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
unsigned char combo[PSIZE];
# define redLED A1 // bad
# define greenLED A0 // good
# define NOKEY 99
const byte inputPin[PSIZE] = {2, 3, 4, 5, 6, 7, 8, };
void setup() {
Serial.begin(115200); Serial.println("HE LL O!\n");
for (unsigned char ii = 0; ii < PSIZE; ii++)
pinMode(inputPin[ii], INPUT_PULLUP);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
disaply.begin();
disaply.show();
reset();
// newCombo();
resetComboMachine();
}
unsigned char nIn = 0; // number of correct steps taken sofa
void loop() {
unsigned char pKey = scanKeys();
random();
if (pKey == NOKEY)
return;
// presst a key, all key are valid so
if (combo[nIn] == 0xff) {
combo[nIn] = doleNext();
Serial.print(nIn);
Serial.print(" has been set to ");
Serial.println(combo[nIn]);
}
// obsly remove this
printCurrentCombo();
if (pKey == combo[nIn]) {
nIn++;
displayDisplay();
goodFlash();
if (nIn == PSIZE) {
nIn = 0;
reward();
resetComboMachine();
reset();
displayDisplay();
}
}
else {
badFlash();
reset();
displayDisplay();
}
}
void goodFlash()
{
digitalWrite(A1, HIGH);
delay(100);
digitalWrite(A1, LOW);
displayDisplay();
Serial.println(" GOOD!");}
void badFlash()
{
digitalWrite(A0, HIGH);
delay(50);
digitalWrite(A0, LOW);
delay(50);
digitalWrite(A0, HIGH);
delay(50);
digitalWrite(A0, LOW);
delay(50);
digitalWrite(A0, HIGH);
delay(50);
digitalWrite(A0, LOW);
displayDisplay();
Serial.println(" BZZZT!");
}
void reward()
{
nIn = 0; displayDisplay();
digitalWrite(A1, HIGH);
delay(600);
nIn = PSIZE; displayDisplay();
digitalWrite(A1, LOW);
delay(600);
nIn = 0; displayDisplay();
digitalWrite(A1, HIGH);
delay(600);
nIn = PSIZE; displayDisplay();
digitalWrite(A1, LOW);
delay(600);
nIn = 0; displayDisplay();
digitalWrite(A1, HIGH);
delay(600);
nIn = PSIZE; displayDisplay();
digitalWrite(A1, LOW);
delay(600);
nIn = 0; displayDisplay();
Serial.println("You are in!");
}
void reset()
{
nIn = 0;
}
void displayDisplay()
{
for (unsigned char tt = 0; tt < PSIZE; tt++)
disaply.setPixelColor(tt, tt >= nIn ? 0x001010 : 0x00ff00);
disaply.show();
}
unsigned char scanKeys()
{
// printf("scan keys ");
unsigned char newKeyQ = NOKEY;
static unsigned long lastTime;
static unsigned char wasPressed = 0;
char isPressed = 0;
unsigned char currentKey = NOKEY;
unsigned long now = millis();
if (now - lastTime < 40)
return currentKey;
for (unsigned char ii = 0; ii < PSIZE; ii++) {
if (!digitalRead(inputPin[ii])) {
newKeyQ = ii;
isPressed = 1;
}
}
if (isPressed != wasPressed) {
lastTime = now;
if (isPressed)
currentKey = newKeyQ;
wasPressed = isPressed;
}
return currentKey;
}
// print error and die
void errorStop(char *msg)
{
Serial.print("\nError: ");
Serial.println(msg);
Serial.flush();
for (; ; );
}
static unsigned char doleFrom[PSIZE] = {0, 2, 4, 6, 1, 3, 5,};
static unsigned char nLeft;
void resetComboMachine()
{
nLeft = PSIZE;
for (unsigned char ii = 0; ii < PSIZE; ii++)
combo[ii] = 0xff;
}
unsigned char doleNext()
{
unsigned char next;
unsigned char rx;
if (nLeft == 0) errorStop("no keys left to dole");
rx = random(0, nLeft);
next = doleFrom[rx];
nLeft--;
doleFrom[rx] = doleFrom[nLeft];
doleFrom[nLeft] = next;
return next;
}
unsigned char doleNext0()
{
unsigned char next;
unsigned char rx;
if (nLeft == 0) errorStop("no keys left to dole");
rx = random(0, nLeft);
next = doleFrom[rx];
nLeft--;
doleFrom[rx] = doleFrom[nLeft];
return next;
}
void printCurrentCombo()
{
for (unsigned char ii = 0; ii < PSIZE; ii++) {
Serial.print(combo[ii] != 0xff ? combo[ii] : 99);
Serial.print(" ");
}
Serial.println();
}
/*
void newCombo()
{
for (unsigned char ii = 0; ii < PSIZE; ii++)
combo[ii] = ii;
for (int ii = 0; ii < 5000; ii++) {
unsigned char tt = random(PSIZE);
unsigned char ss = random(PSIZE);
unsigned char temp;
temp = combo[tt];
combo[tt] = combo[ss];
combo[ss] = temp;
}
}
*/