/*
Project: Mole Hammer Game
Name: Kevin Hessel, Marian Helwig
Date: 29.11.2023
Libraries: LiquidCrystal_I2C
___________________________________________________________
*/
#include <Arduino.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define NOTE_C4 262
#define NOTE_G3 196
#define NOTE_A3 220
#define NOTE_B3 247
const byte SHCP = 13;
const byte STCP = 12;
const byte DS = 11;
const byte LED6Pin = 10;
const byte LED9Pin = 8;
//BUtton 1-6 -> Pin 8-13
const int Buttons[9] = {A2, A1, A0, 7, 6, 5, 4, 3, 2};
// saves Pin number of the glowing ed
byte randomLedPinNr = 0;
//Player Points
int points = 0;
//difficulty level
byte difficulty = 1;
//condition for the Powerup
int powerUpCounter = 0;
//variable if the powerup is active
bool powerUpActive = false;
//variable for the time the powerup is active
unsigned long powerUpTimer = 0;
void setup() {
//pinmode OUTPUT for LEDS
for(int i=13; i>=8; --i){
pinMode(i, OUTPUT);
}
//pinmode INPUT for Buttons
for(int i=0; i<=8; ++i){
pinMode(Buttons[i], INPUT);
}
lcd.init();
lcd.backlight();
Serial.begin(9600);
}
void loop() {
menu();
unsigned long currentTime = millis();
while(millis() - currentTime < 60000){
randomGenerator();
moleHitTime();
ledRegister(6);
ledPinsOff();
randomLedPinNr = 0;
}
//resets the game stats
powerUpActive = false;
powerUpCounter = 0;
//shows stats for 3 seconds an then jumps back to the menu
while(millis() - currentTime < 63000){
playEndMelody();
}
points = 0;
}
// Controls the 6 LEDs on the shift register
void ledRegister(int LEDNr){
int stateLight[7] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00};
digitalWrite(STCP, LOW);
shiftOut(DS, SHCP, MSBFIRST, stateLight[LEDNr]);
digitalWrite(STCP, HIGH);
}
void ledPinsOn(int LEDNr){
int LEDsPins[3] = {10, 9, 8};
digitalWrite(LEDsPins[LEDNr], HIGH);
}
void ledPinsOff(){
int LEDsPins[3] = {10, 9, 8};
for(int i=0; i <= 2; ++i){
digitalWrite(LEDsPins[i], LOW);
}
}
//random generator turns on random LED
void randomGenerator(){
randomLedPinNr = random(8);
if(randomLedPinNr <= 5){
ledRegister(randomLedPinNr);
}
else{
ledPinsOn(randomLedPinNr-6);
}
}
//delay with loop feature
//timerLength -> time each mole shows his heade to be hit
void moleHitTime() {
int Test = 10;
//diefferent difficulties
int difficultyTimer[3] = {2000, 1500, 1000};
// variable to calculate timer length
int timerLength = difficultyTimer[difficulty];
unsigned long timer = millis();
while (millis() - timer <= timerLength) {
Test = checkButtons();
Serial.print("randomLedPinNr: ");
Serial.println(randomLedPinNr);
Serial.print("Test: ");
Serial.println(Test);
//safes Value of the button which was pressed or 0 if no button was pressed
if(randomLedPinNr == Test){
addPoint();
++powerUpCounter;
showPoints();
break;
}
}
if (randomLedPinNr != Test && powerUpActive == false) {
//resets the counter for a powerUp if we miss a mole:
powerUpCounter = 0;
}
powerUp();
}
//prints the powerup on the LCD
void printPowerUp() {
lcd.setCursor(0, 0);
lcd.print("Power: double Points");
}
//safes condition for the powerup to be given
void addPointToPowerUp() {
++powerUpCounter;
if (powerUpCounter > 4) {
points += 5;
}
}
//controls the PowerUp
void powerUp(){
//Serial.print("powerUpCounter: ");
//Serial.println(powerUpCounter);
//Serial.println("Time: ");
//Serial.println(millis() - powerUpTimer);
if(powerUpCounter == 5 && powerUpActive == false){
powerUpActive = true;
powerUpTimer = millis();
}
else if(powerUpActive == true && millis() - powerUpTimer >= 10000){
powerUpActive = false;
powerUpCounter = 0;
}
}
// adds a Point to the score
void addPoint() {
if(powerUpActive == true){
points += 2;
}
else{
points += 1;
}
}
//prints the score on the lcd display:
void showPoints() {
lcd.clear();
if (powerUpCounter > 4) {
printPowerUp();
}
lcd.setCursor(0, 1);
lcd.print("Points: ");
lcd.print(points);
delay(500);
}
//reads all buttons and returns the Buttons Pin number if a button is Pressed or 0 when no button is Pressed
byte checkButtons(){
for(byte i=0; i<=8; ++i){
if(digitalRead(Buttons[i]) == HIGH){
return i;
}
}
}
//Plays a Melody on the Buzzer
void playEndMelody() {
//notes in the melody
int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3};
//note durations: 4 = quarter note, 8 =eight note, etc.:
int noteDurations[] = {4 ,8 ,8 ,4 ,4 ,4 ,4};
for (int thisNote = 0; thisNote < 7; thisNote++) {
//to calculate the note duration, take one second divided by our 'noteDurations'
//e.g. quarter note = 1000/4, eight note = 1000/8
int noteDuration = 1000 / noteDurations[thisNote];
tone(1, melody[thisNote], noteDuration);
//to distinguish the notes, set a minimum time between the played notes
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
//stop the tone playing:
noTone(1);
}
}