/****** * Champo'Mind * Simon® like Game * Five buttons -> 5 difficulty levels * Mr.DOULCET, Mr.BARBATO & Ugo Penuelas * Lycée Champollion, 2024 */ /******* * Pins mapping def */ #define N 5 // Number of LED and buttons #define LEDSW201 12 // LED 1 (+) on bit 12 (with 220 ohms resistor) #define LEDSW202 10 // LED 2 (+) on bit 10 (with 220 ohms resistor) #define LEDSW203 A4 // LED 3 (+) on bit A4 (with 220 ohms resistor) #define LEDSW204 A3 // LED 4 (+) on bit A3 (with 220 ohms resistor) #define LEDSW205 A1 // LED 5 (+) on bit A1 (with 220 ohms resistor) #define SW201 13 // Button 1 (+) on bit 13 #define SW202 9 // Button 2 (+) on bit 9 #define SW203 A5 // Button 3 (+) on bit A5 #define SW204 A2 // Button 4 (+) on bit A2 #define SW205 A0 // Button 4 (+) on bit A0 #define batState 8 // Batterie State on bit 8 #define speaker 11 // Set speaker on bit 11 (with 100 ohms résistor) /* * Key mapping of game music */ #define K_F3 175 #define K_C4 262 #define K_F4 349 #define K_G4 392 #define K_A4 440 #define LENGTH 400 // Time length of a key by default #define SILENCE 400 // Time length of a silence /****** * Variables */ int notes[N] = {K_F3, K_C4, K_F4, K_G4, K_A4}; // Key values used by music game int kind[] = {4, 5, 3, 1, 2}; // Key table of music game //int Westminster[] = {3, 5, 4, 2, 2, 4, 5, 3}; // Key table of music other game int GameMap[(N+1)*5]; // Memory Game mappe, loaded by random int difficulty = 1; // Difficulty level (1 by default) int LEDmap[N] = {LEDSW201,LEDSW202,LEDSW203,LEDSW204,LEDSW205}; // LED table int BUTmap[N] = {SW201,SW202,SW203,SW204,SW205}; // Button table long attente=120; // 1 minute (120 1/2s) int n=0; // Compteur LED /****** * setup */ void setup() { // Setup pins for (; nN-1) n=0; } else { Serial.println("Battery Level Low..."); digitalWrite(LEDmap[n], HIGH); delay(250); digitalWrite(LEDmap[n], LOW); n--;if (n<0) n=N-1; } // radomize random(1, N); // If so long waitting, restart all system if (attente--<=0) { Serial.println("Attente trop longue... Redémarrage..."); delay(250); asm volatile ("jmp 0"); // Restart } } /****** * play_game */ void play_game() { int roundCount = 0; // Init game int playerTurn = 1; int currentNote; int userInput = 0; int j; bool buttonPress = false; bool loss = false; attente=1000000; // init 1 minute waitting Serial.println("Attendre touche relachée..."); while (digitalRead(BUTmap[difficulty-1])==LOW) { // Faire tourner le tirage au sort random(1, N); }; Serial.println("Start Game"); Serial.print("Difficulty : "); Serial.println(difficulty); // if (difficulty==1) { // Play kind tab start game for (j=0; j < N-1; j++){ play_note(kind[j], 150, 0); } play_note(kind[j], 300, 0); /*} else { for (j=0; j < 7; j++){ play_note(Westminster[j], 150, 0); } play_note(Westminster[j], 300, 0); }*/ delay(700); for (int currentRound=1; (currentRound - 1)<=(difficulty * N); currentRound++) // Number of rounds to play { roundCount += 1; playerTurn = 1; buttonPress = false; userInput = 0; delay(500); for (int j = 1; j != currentRound; j++) { play_note(GameMap[j - 1], LENGTH, SILENCE); // Play current note(s) } while (playerTurn < currentRound) { currentNote = GameMap[playerTurn - 1]; Serial.println(currentNote); while (buttonPress == false) { if (digitalRead(SW201) == LOW) // SW201 Pressed ? { buttonPress = true; userInput = 1; } if (digitalRead(SW202) == LOW) // SW202 Pressed ? { buttonPress = true; userInput = 2; } if (digitalRead(SW203) == LOW) // SW203 Pressed ? { buttonPress = true; userInput = 3; } if (digitalRead(SW204) == LOW) // SW204 Pressed ? { buttonPress = true; userInput = 4; } if (digitalRead(SW205) == LOW) // SW205 Pressed ? { buttonPress = true; userInput = 5; } if (buttonPress == true) // Button pressed ? { attente=1000000; // Reinit attente, 1 minute environ play_note(userInput, LENGTH, SILENCE); // Jouer le son du bouton correspondant if (currentNote == userInput) // Bouton correcte ! { playerTurn++; } else // Mauvais bouton ! :( { game_over(false); } } // Si attente trop longue (attente terminée), Redémarrage if (attente--<=0) { Serial.println("Attente trop longue... Redémarrage..."); delay(250); asm volatile ("jmp 0"); // Restart } // Faire tourner le tirage au sort random(1, N); } buttonPress = false; } } if (loss == false){ Serial.println("Vous avez fait une série correcte !"); game_over(true); } attente=120; // Reinit attente, pour menu principal (loop) 1 minute environ (120 1/2s) } /****** * generate_game */ void generate_game() { int i=0; randomSeed(analogRead(1)); for (;i<(difficulty * (N+1)); i++) // Pour chaque niveau de difficulté, ajouter 5 tours de plus au jeu { GameMap[i] = random(1, N+1); } // Insert kind pattern in game if (random(1,9-difficulty)==1) {memcpy(&GameMap[(difficulty-1)*N], kind, sizeof(kind));}; //memcpy(&GameMap[0], Westminster, sizeof(Westminster)); } /****** * play_note */ void play_note(int index, int notespeed, int silence) { int led = LEDmap[index-1]; digitalWrite(led, HIGH); tone(speaker, notes[index-1], notespeed); delay(notespeed); digitalWrite(led, LOW); delay(silence); } /****** * game_over */ void game_over(bool win) { if (win) { Serial.println("Vous avez gagné !"); for (int i = 0; i < 3; i++){ // Jouer 3 fois la musique rapidement for (int j = 0; j < N; j++){ play_note(kind[j], 80, 80); } } } else { Serial.println("Perdu !"); for (int i = 0; i < 3; i++){ // Jouer 3 fois la musique rapidement à l'envers for (int j = N; j > 0; j--){ play_note(kind[j-1], 50, 50); } } } Serial.println("Jeu terminé"); }