#include <Adafruit_NeoPixel.h>
#include <Keypad.h>
#define NOMBRE_DIODES_PLATEAU 25 // Nombre de diodes lumineuses du plateau
#define BROCHE_PLATEAU 12 // Broche connectée à l'entrée de données des diodes lumineuses du plateau
#define NOMBRE_DIODES_CARTE 25 // Nombre de diodes lumineuses de la carte clé
#define BROCHE_CARTE A0 // Broche connectée à l'entrée de données des diodes lumineusesde la carte clé
#define BOUTON_ALEATOIRE A1
#define BOUTON_ROUGE A2
#define BOUTON_BLEU A3
#define BOUTON_PERDU A4
#define BUZZER_PIN A5 // Pin du buzzer
//-----------------------------
const byte LIGNES = 5; // 5 lignes
const byte COLONNES = 5; // 5 colonnes
int memoire = 0;
bool ancien_etat_ALEATOIRE = HIGH; // variable pour la lecture de l'état des boutons-poussoirs couleur
bool ancien_etat_ROUGE = HIGH;
bool ancien_etat_BLEU = HIGH;
bool ancien_etat_PERDU = HIGH;
const long periods2[] = {100, 1000, 1000, 300, 100, 500, 1000, 0};
byte index2;
unsigned long startTime;
unsigned long currentTime;
Adafruit_NeoPixel strip(NOMBRE_DIODES_PLATEAU, BROCHE_PLATEAU, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels(NOMBRE_DIODES_CARTE, BROCHE_CARTE, NEO_GRB + NEO_KHZ800);
// défini les numéros des diodes lumineuse RGB correspondant au boutons-poussoirs du plateau.
char tableau_boutons_plateau[LIGNES][COLONNES] = {
{1, 2, 3, 4, 5}, // boutons de la 1ere ligne
{6, 7, 8, 9, 10}, // boutons de la 2eme ligne
{11, 12, 13, 14, 15}, // boutons de la 3eme ligne
{16, 17, 18, 19, 20}, // boutons de la 4eme ligne
{21, 22, 23, 24, 25}, // boutons de la 5eme ligne
};
byte broches_lignes[LIGNES] = {11, 10, 9, 8, 7}; // se connecter aux broches de la rangée de boutons du plateau
byte broches_colonnes[COLONNES] = {6, 5, 4, 3, 2}; // se connecter aux broches de la colonne de boutons du plateau
//initialise une instance de la classe NewKeypad
Keypad boutons_plateau = Keypad(makeKeymap(tableau_boutons_plateau), broches_lignes, broches_colonnes, LIGNES, COLONNES);
const int DELAI = 10; // delai en milliseconds
const uint8_t LUMINOSITE = 255;
const int NOMBRE_COULEURS = 4;
enum colors { ROUGE, BLEU, YELLOW, PERDU };
int gameRound = 0; // Compteur pour suivre les tours (0 ou 1)
int cardTypes[NOMBRE_DIODES_CARTE]; // Tableau pour les types de cartes (rouge, bleu, neutre, assassin)
void setup() {
// initialiser la broche du bouton-poussoir en tant qu'entrée :
pinMode(BOUTON_ALEATOIRE, INPUT_PULLUP);
pinMode(BOUTON_ROUGE, INPUT_PULLUP);
pinMode(BOUTON_BLEU, INPUT_PULLUP);
pinMode(BOUTON_PERDU, INPUT_PULLUP);
// fonction de réinitialisation des diodes lumineuses de la carte clé(mode aléatoire)
// codenames();
Serial.begin(9600);
// Initialise la librairie Neopixel.
pixels.begin();
strip.begin();
strip.show(); // Initialise toutes les diodes lumineuses du plateau sur off.
strip.setBrightness(255);
// Générer les cartes clés sur la matrice NeoPixel des cartes clés
generateRandomCards(); // Afficher les cartes clés secrètes à l'espion
}
void loop() {
// récupérer l'état courant des boutons de couleur.
bool nouvel_etat_ALEATOIRE = digitalRead(BOUTON_ALEATOIRE);
bool nouvel_etat_ROUGE = digitalRead(BOUTON_ROUGE);
bool nouvel_etat_BLEU = digitalRead(BOUTON_BLEU);
bool nouvel_etat_PERDU = digitalRead(BOUTON_PERDU);
// récupérer la valeur du bouton de plateau
int valeurs_boutons_plateau = boutons_plateau.getKey();
if (valeurs_boutons_plateau) {
// Serial.println(valeurs_boutons_plateau);
memoire = valeurs_boutons_plateau;
strip.setPixelColor((valeurs_boutons_plateau -1 ), 255, 255, 0);
strip.show();
tone(BUZZER_PIN, 1000, 200); // Buzzer : Son de sélection de carte
delay(DELAI);
}
// ROUGE
if (nouvel_etat_ROUGE == LOW && ancien_etat_ROUGE == HIGH) {
// Délai court pour éviter le rebond(debounce)
delay(20);
// Vérifier si le bouton est toujours en position basse après le rebond.
nouvel_etat_ROUGE = digitalRead(BOUTON_ROUGE);
if (nouvel_etat_ROUGE == HIGH) {
rouge();
}
}
// BLEU
if (nouvel_etat_BLEU == LOW && ancien_etat_BLEU == HIGH) {
// Délai court pour éviter le rebond(debounce)
delay(20);
// Vérifier si le bouton est toujours en position basse après le rebond.
nouvel_etat_BLEU = digitalRead(BOUTON_BLEU);
if (nouvel_etat_BLEU == HIGH) {
bleu();
}
}
// PERDU
if (nouvel_etat_PERDU == LOW && ancien_etat_PERDU == HIGH) {
// Délai court pour éviter le rebond(debounce)
delay(20);
// Vérifier si le bouton est toujours en position basse après le rebond.
nouvel_etat_PERDU = digitalRead(BOUTON_PERDU);
if (nouvel_etat_PERDU == HIGH) {
perdu();
}
}
// Gestion du bouton de réinitialisation
if (digitalRead(BOUTON_ALEATOIRE) == LOW) {
gameRound = (gameRound + 1) % 2; // Alterner entre 0 et 1 (2 tours)
resetGame(); // Réinitialiser le jeu pour le nouveau tour
}
}
void rouge() {
if (memoire) {
strip.setPixelColor(memoire - 1, 255, 0, 0);
strip.show();
tone(BUZZER_PIN, 2000, 200); // Buzzer : Son équipe rouge
delay(DELAI);
}
}
void bleu() {
if (memoire) {
strip.setPixelColor(memoire - 1, 0, 0, 255);
strip.show();
tone(BUZZER_PIN, 1500, 200); // Buzzer : Son équipe bleue
delay(DELAI);
}
}
void perdu() {
if (memoire) {
strip.setPixelColor(memoire - 1, 255, 0, 255);
strip.show();
tone(BUZZER_PIN, 500, 200); // Buzzer : Son assassin
delay(DELAI);
}
}
// Fonction pour générer les cartes clés avec alternance entre 9 rouges et 8 bleues, ou 8 rouges et 9 bleues
void generateRandomCards() {
// Remplir le tableau avec les valeurs des cartes
int redCards = (gameRound == 0) ? 9 : 8; // 9 rouges pour le premier tour, 8 pour le second
int blueCards = (gameRound == 0) ? 8 : 9; // 8 bleues pour le premier tour, 9 pour le second
int neutralCards = 7; // 7 cartes neutres
int assassinCard = 1; // 1 carte assassin
Serial.println("gameRound\n");
Serial.println(gameRound);
// Remplir le tableau avec les valeurs de cartes (rouge, bleu, neutre, assassin)
for (int i = 0; i < redCards; i++) {
cardTypes[i] = 0; // Rouge
}
for (int i = redCards; i < redCards + blueCards; i++) {
cardTypes[i] = 1; // Bleu
}
for (int i = redCards + blueCards; i < redCards + blueCards + neutralCards; i++) {
cardTypes[i] = 2; // Neutre
}
for (int i = redCards + blueCards + neutralCards; i < NOMBRE_DIODES_CARTE; i++) {
cardTypes[i] = 3; // Assassin
}
// Mélanger les types de cartes pour les distribuer de manière aléatoire
for (int i = 0; i < NOMBRE_DIODES_CARTE; i++) {
int randIndex = random(NOMBRE_DIODES_CARTE);
int temp = cardTypes[i];
cardTypes[i] = cardTypes[randIndex];
cardTypes[randIndex] = temp;
}
// Affecter les couleurs aux LEDs de la matrice des cartes clés
for (int i = 0; i < NOMBRE_DIODES_CARTE; i++) {
if (cardTypes[i] == 0) {
pixels.setPixelColor(i, pixels.Color(255, 0, 0)); // Rouge pour l'équipe rouge
} else if (cardTypes[i] == 1) {
pixels.setPixelColor(i, pixels.Color(0, 0, 255)); // Bleu pour l'équipe bleue
} else if (cardTypes[i] == 2) {
pixels.setPixelColor(i, pixels.Color(192, 192, 192)); // Gris pour neutre
} else {
pixels.setPixelColor(i, pixels.Color(255, 0, 255)); // Violet pour assassin
}
}
pixels.show(); // Appliquer les changements de couleur aux LEDs de la matrice des cartes clés
}
// Fonction pour réinitialiser le jeu à chaque nouveau tour
void resetGame() {
// Réinitialiser le plateau de jeu
for (int i = 0; i < NOMBRE_DIODES_CARTE; i++) {
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // Éteindre chaque LED du plateau
}
pixels.show();
// Régénérer les cartes clés pour le nouveau tour
generateRandomCards();
}