Ximon78-simon
2020-12-19 15:30:00
Simon.ino
#include <LedControl.h> // LED
#define PLAYER_WAIT_TIME 2000 // The time allowed between button presses - 2s
byte sequence[100]; // Storage for the light sequence
byte curLen = 0; // Current length of the sequence
byte inputCount = 0; // The number of times that the player has pressed a (correct) button in a given turn
byte lastInput = 0; // Last input from the player
byte expRd = 0; // The LED that's suppose to be lit by the player
bool btnDwn = false; // Used to check if a button is pressed
bool wait = false; // Is the program waiting for the user to press a button
bool resetFlag = false; // Used to indicate to the program that once the player lost
byte noPins = 4; // Number of buttons/LEDs (While working on this, I was using only 2 LEDs)
byte soundPin = 5; // Speaker output
byte pins[] = {A1, A2, A3, A4}; // Button input pins and LED ouput pins - change these vaules if you wwant to connect yourbuttons to other pins
long inputTime = 0; // Timer variable for the delay between user inputs
const int DIN_PIN = 4; // LED
const int CS_PIN = 3; // LED
const int CLK_PIN = 2; // LED
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN); // LED
const uint64_t NUMBERS[] = {
0x6699999966000000,
0x4649496946000000, 0xe629e989e6000000, 0xe689e989e6000000, 0x8689e9a9a6000000, 0xe689e929e6000000, 0xe6a9e929e6000000, 0x86898989e6000000, 0xe6a9e9a9e6000000, 0xe689e9a9e6000000, 0x6494949664000000,
0x2424243624000000, 0xe424e486e4000000, 0xe484e486e4000000, 0x8484e4a6a4000000, 0xe484e426e4000000, 0xe4a4e426e4000000, 0x84848486e4000000, 0xe4a4e4a6e4000000, 0xe484e4a6e4000000, 0x6791979467000000,
0x4741476447000000, 0xe721e784e7000000, 0xe781e784e7000000, 0x8781e7a4a7000000, 0xe781e724e7000000, 0xe7a1e724e7000000, 0x87818784e7000000, 0xe7a1e7a4e7000000, 0xe781e7a4e7000000, 0x6794979467000000,
0x4744476447000000, 0xe724e784e7000000, 0xe784e784e7000000, 0x8784e7a4a7000000, 0xe784e724e7000000, 0xe7a4e724e7000000, 0x87848784e7000000, 0xe7a4e7a4e7000000, 0x8784e7a4e7000000, 0x6494979565000000,
0x4444476545000000, 0xe424e785e5000000, 0xe484e785e5000000, 0x8484e7a5a5000000, 0xe484e725e5000000, 0xe4a4e725e5000000, 0x84848785e5000000, 0xe4a4e7a5e5000000, 0x8484e7a5e5000000, 0x6794979167000000,
0x4744476147000000, 0xe724e781e7000000, 0xe784e781e7000000, 0x8784e7a1a7000000, 0xe784e721e7000000, 0xe7a4e721e7000000, 0x87848781e7000000, 0xe7a4e7a1e7000000, 0x8784e7a1e7000000, 0x6795979167000000,
0x4745476147000000, 0xe725e781e7000000, 0xe785e781e7000000, 0x8785e7a1a7000000, 0xe785e721e7000000, 0xe7a5e721e7000000, 0x87858781e7000000, 0xe7a5e7a1e7000000, 0x8785e7a1e7000000, 0x6494949467000000,
0x2424243427000000, 0xe424e484e7000000, 0xe484e484e7000000, 0x8484e4a4a7000000, 0xe484e424e7000000, 0xe4a4e424e7000000, 0x84848484e7000000, 0xe4a4e4a4e7000000, 0x8484e4a4e7000000, 0x6795979567000000,
0x4745476547000000, 0xe725e785e7000000, 0xe785e785e7000000, 0x8785e7a5a7000000, 0xe785e725e7000000, 0xe7a5e725e7000000, 0x87858785e7000000, 0xe7a5e7a5e7000000, 0x8785e7a5e7000000, 0x6494979567000000,
0x2424273527000000, 0xe424e785e7000000, 0xe484e785e7000000, 0x8484e7a5a7000000, 0xe484e725e7000000, 0xe4a4e725e7000000, 0x84848785e7000000, 0xe4a4e7a5e7000000, 0x8484e7a5e7000000, 0xa5a542a5a5000000
};
const uint64_t LOADER[] = {
0x0000000008000000, 0x0000000018000000, 0x0000001018000000, 0x0000001818000000, 0x0000001c18000000, 0x0000001c1c000000,
0x0000001c1c040000, 0x0000001c1c0c0000, 0x0000001c1c1c0000, 0x0000001c1c3c0000, 0x0000001c3c3c0000, 0x0000003c3c3c0000,
0x0000203c3c3c0000, 0x0000303c3c3c0000, 0x0000383c3c3c0000, 0x00003c3c3c3c0000, 0x00003e3c3c3c0000, 0x00003e3e3c3c0000,
0x00003e3e3e3c0000, 0x00003e3e3e3e0000, 0x00003e3e3e3e0200, 0x00003e3e3e3e0600, 0x00003e3e3e3e0e00, 0x00003e3e3e3e1e00,
0x00003e3e3e3e3e00, 0x00003e3e3e3e7e00, 0x00003e3e3e7e7e00, 0x00003e3e7e7e7e00, 0x00003e7e7e7e7e00, 0x00007e7e7e7e7e00,
0x00407e7e7e7e7e00, 0x00607e7e7e7e7e00, 0x00707e7e7e7e7e00, 0x00787e7e7e7e7e00, 0x007c7e7e7e7e7e00, 0x007e7e7e7e7e7e00,
0x007f7e7e7e7e7e00, 0x007f7f7e7e7e7e00, 0x007f7f7f7e7e7e00, 0x007f7f7f7f7e7e00, 0x007f7f7f7f7f7e00, 0x007f7f7f7f7f7f00,
0x007f7f7f7f7f7f01, 0x007f7f7f7f7f7f03, 0x007f7f7f7f7f7f07, 0x007f7f7f7f7f7f0f, 0x007f7f7f7f7f7f1f, 0x007f7f7f7f7f7f3f,
0x007f7f7f7f7f7f7f, 0x007f7f7f7f7f7fff, 0x007f7f7f7f7fffff, 0x007f7f7f7fffffff, 0x007f7f7fffffffff, 0x007f7fffffffffff,
0x007fffffffffffff, 0x00ffffffffffffff, 0x80ffffffffffffff, 0xc0ffffffffffffff, 0xe0ffffffffffffff, 0xf0ffffffffffffff,
0xf8ffffffffffffff, 0xfcffffffffffffff, 0xfeffffffffffffff, 0xffffffffffffffff
};
void setup() {
Serial.begin(9600); // Start Serial monitor. This can be removed too as long as you remove all references to Serial below
reset();
display.clearDisplay(0); // LED
display.shutdown(0, false); // LED
display.setIntensity(0, 10); // LED
showLoader();
}
void showLoader() {
for (int i = 0; i <= 63; i++) {
displayImage(LOADER[i]);
delay(100);
}
}
// Sets all the pins as either INPUT or OUTPUT based on the value of 'dir'
void setPinDirection(byte dir) {
for(byte i = 0; i < noPins; i++) {
pinMode(pins[i], dir);
}
}
// send the same value to all the LED pins
void writeAllPins(byte val) {
for(byte i = 0; i < noPins; i++) {
digitalWrite(pins[i], val);
}
}
// makes beep sound
void beep(byte freq) {
analogWrite(soundPin, 2);
delay(freq);
analogWrite(soundPin, 0);
delay(freq);
}
// flashes all the LEDs together (freq is the blink speed - small number -> fast | big number -> slow)
void flash(short freq) {
setPinDirection(OUTPUT); /// We're activating the LEDS now
for(int i = 0; i < 5; i++) {
writeAllPins(HIGH);
beep(50);
delay(freq);
writeAllPins(LOW);
delay(freq);
}
}
// this function resets all the game variables to their default values
void reset() {
//flash(500);
curLen = 0;
inputCount = 0;
lastInput = 0;
expRd = 0;
btnDwn = false;
wait = false;
resetFlag = false;
}
// user lost
void lose() {
flash(50);
}
// the arduino shows the user what must be memorized (also called after losing to show you what you last sequence was)
void playSequence() {
// loop through the stored sequence and light the appropriate LEDs in turn
for(int i = 0; i < curLen; i++) {
Serial.print("Seq: ");
Serial.print(i);
Serial.print("Pin: ");
Serial.println(sequence[i]);
digitalWrite(sequence[i], HIGH);
delay(500);
digitalWrite(sequence[i], LOW);
delay(250);
}
}
/// the events that occur upon a loss
void doLoseProcess() {
lose(); // flash all the LEDS quickly (see Lose function)
delay(1000);
//playSequence(); // shows the user the last sequence - So you can count remember your best score - Mine's 22 by the way :)
//delay(1000);
reset(); // reset everything for a new game
displayImage(NUMBERS[0]); // LED
}
/// where the magic happens
void loop() {
if(!wait) {
// arduino's turn
setPinDirection(OUTPUT); // We're using the LEDs
randomSeed(analogRead(A0)); // https://www.arduino.cc/en/Reference/RandomSeed
sequence[curLen] = pins[random(0,noPins)]; // Put a new random value in the next position in the sequence - https://www.arduino.cc/en/Reference/random
curLen++; // Set the new Current length of the sequence
playSequence(); // Show the sequence to the player
beep(50); // Make a beep for the player to be aware
wait = true; // Set Wait to true as it's now going to be the turn of the player
inputTime = millis(); // Store the time to measure the player's response time
} else {
// player's turn
displayImage(NUMBERS[curLen]); // LED
setPinDirection(INPUT); // we're using the buttons
if(millis() - inputTime > PLAYER_WAIT_TIME){ // If the player takes more than the allowed time,
doLoseProcess(); // All is lost :(
return;
}
if(!btnDwn) {
expRd = sequence[inputCount]; // Find the value we expect from the player
Serial.print("Expected: "); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
Serial.println(expRd); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
for(int i = 0; i < noPins; i++) { // Loop through the all the pins
if(pins[i]==expRd)
continue; // Ignore the correct pin
if(digitalRead(pins[i]) == HIGH) { // Is the buttong pressed
lastInput = pins[i];
resetFlag = true; // Set the resetFlag - this means you lost
btnDwn = true; // This will prevent the program from doing the same thing over and over again
Serial.print("Read: "); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
Serial.println(lastInput); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
}
}
}
if(digitalRead(expRd) == 1 && !btnDwn) { // The player pressed the right button
inputTime = millis();
lastInput = expRd;
inputCount++; // The user pressed a (correct) button again
btnDwn = true; // This will prevent the program from doing the same thing over and over again
Serial.print("Read: "); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
Serial.println(lastInput); // Serial Monitor Output - Should be removed if you removed the Serial.begin above
} else {
if(btnDwn && digitalRead(lastInput) == LOW) { // Check if the player released the button
btnDwn = false;
delay(20);
if(resetFlag) { // If this was set to true up above, you lost
doLoseProcess(); // So we do the losing sequence of events
} else {
if(inputCount == curLen) { // Has the player finished repeating the sequence
wait = false; // If so, this will make the next turn the program's turn
inputCount = 0; // Reset the number of times that the player has pressed a button
delay(1500);
}
}
}
}
}
}
void displayImage(uint64_t image) { // LED
for (int i = 0; i < 8; i++) { // LED
byte row = (image >> i * 8) & 0xFF; // LED
for (int j = 0; j < 8; j++) { // LED
display.setLed(0, i, j, bitRead(row, j)); // LED
} // LED
} // LED
} // LED