Skip to content

Instantly share code, notes, and snippets.

@illmat
Last active February 13, 2023 14:35
Show Gist options
  • Save illmat/09cfbf8acef30c2b4e4a32c8c4cfb7b7 to your computer and use it in GitHub Desktop.
Save illmat/09cfbf8acef30c2b4e4a32c8c4cfb7b7 to your computer and use it in GitHub Desktop.
An Arduino-based game where you have to represent random decimal numbers in binary within a certain time by using switches. The original idea came from the user keebie81 (https://www.instructables.com/Binary-Game/). Differences to keebie81's version: code rewritten, no easy/hard mode button, timer + scores
#include <LiquidCrystal.h>
#include <Bounce2.h>
#define PIN_0 A0
#define PIN_1 A1
#define PIN_2 A2
#define PIN_3 A3
#define PIN_4 3
#define PIN_5 4
#define PIN_6 5
#define PIN_7 6
#define PIN_BUZZER 13
#define PIN_START_BUTTON 2
#define PIN_UNUSED_ANALOG 5
#define BASE_MIN_NUMBER 1
#define BASE_MAX_NUMBER 4
#define DELAY 50
#define MAX_TIME 120000
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
Bounce2::Button startButton = Bounce2::Button();
byte currentNumber = 0;
byte targetNumber = 0;
int score = 0;
int minNumber = BASE_MIN_NUMBER;
int maxNumber = BASE_MAX_NUMBER;
unsigned long startTime = 0;
enum GameState {
Start,
Running
};
GameState gameState = Start;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(PIN_0, INPUT_PULLUP);
pinMode(PIN_1, INPUT_PULLUP);
pinMode(PIN_2, INPUT_PULLUP);
pinMode(PIN_3, INPUT_PULLUP);
pinMode(PIN_4, INPUT_PULLUP);
pinMode(PIN_5, INPUT_PULLUP);
pinMode(PIN_6, INPUT_PULLUP);
pinMode(PIN_7, INPUT_PULLUP);
pinMode(PIN_BUZZER, OUTPUT);
startButton.attach(PIN_START_BUTTON, INPUT_PULLUP);
startButton.interval(100);
startButton.setPressedState(LOW);
randomSeed(analogRead(PIN_UNUSED_ANALOG));
}
void loop() {
updateInputs();
delay(10);
switch (gameState) {
case Start:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Final score: ");
lcd.print(score);
lcd.setCursor(0, 1);
lcd.print("Press start");
if (startButton.pressed()) {
startTime = millis();
delay(10);
score = 0;
minNumber = BASE_MIN_NUMBER;
maxNumber = BASE_MAX_NUMBER;
targetNumber = random(minNumber, maxNumber);
printDebugInfo();
gameState = Running;
break;
}
break;
case Running:
if ((millis() - startTime) > MAX_TIME) {
gameState = Start;
break;
}
// end game on long press
if (startButton.isPressed() && startButton.currentDuration() > 2000) {
gameState = Start;
break;
}
if (currentNumber == targetNumber) {
score++;
if (score <= 6) {
minNumber = pow(2, score + 1) + 1; // +1 because we want to skip the first bit
maxNumber = pow(2, score + 2) + 1;
}
targetNumber = random(minNumber, maxNumber);
printDebugInfo();
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T ");
lcd.print((MAX_TIME - (millis() - startTime)) / 1000);
lcd.setCursor(7, 0);
lcd.print("Score ");
lcd.print(score);
lcd.setCursor(0, 1);
lcd.print(targetNumber);
lcd.setCursor(8, 1);
lcd.print(byteToString(currentNumber));
break;
}
}
void printDebugInfo() {
Serial.print("min: ");
Serial.print(minNumber);
Serial.print(" ## max: ");
Serial.print(maxNumber);
Serial.print(" ## current: ");
Serial.print(currentNumber);
Serial.print(" ## target: ");
Serial.println(targetNumber);
}
void updateInputs() {
startButton.update();
bitWrite(currentNumber, 0, digitalRead(PIN_0) == HIGH);
bitWrite(currentNumber, 1, digitalRead(PIN_1) == HIGH);
bitWrite(currentNumber, 2, digitalRead(PIN_2) == HIGH);
bitWrite(currentNumber, 3, digitalRead(PIN_3) == HIGH);
bitWrite(currentNumber, 4, digitalRead(PIN_4) == HIGH);
bitWrite(currentNumber, 5, digitalRead(PIN_5) == HIGH);
bitWrite(currentNumber, 6, digitalRead(PIN_6) == HIGH);
bitWrite(currentNumber, 7, digitalRead(PIN_7) == HIGH);
}
String byteToString(byte input) {
String ret = "00000000";
int x = 0;
for (int i = 128; i > 0; i /= 2) {
ret[x++] = input & i ? '1' : '0';
}
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment