#include <TM1637Display.h>
// Initialisation des afficheurs 7 segments pour chaque joueur
TM1637Display display(11, 12); // CLK, DIO pour le joueur 1
TM1637Display display2(9, 8); // CLK, DIO pour le joueur 2
// Boutons pour chaque joueur
int buttonPlayer1 = 5;
int buttonPlayer2 = 10;
int modeButton = 4; // Bouton pour choisir le mode de jeu
// Variables pour les compteurs de chaque joueur (en secondes)
int counterPlayer1 = 180; // Par défaut : 3 minutes (180 secondes)
int counterPlayer2 = 180; // Par défaut : 3 minutes (180 secondes)
// Rajouts de temps pour les modes avec incréments
int incrementPlayer1 = 0;
int incrementPlayer2 = 0;
unsigned long previousMillis = 0; // Pour le chronométrage
const long interval = 1000; // Intervalle d'une seconde
bool player1Turn = true; // Indicateur pour savoir quel joueur joue
bool player2Turn = false;
bool gameStarted = false; // Indicateur pour savoir si le jeu a démarré
bool player1HasStarted = false; // Indicateur pour savoir si le joueur 1 a démarré son compteur
bool player2HasStarted = false; // Indicateur pour savoir si le joueur 2 a démarré son compteur
int gameMode = 0; // 0 = 3 min, 1 = 5 min + 2 sec, 2 = 10 min + 5 sec, 3 = 15 min + 10 sec
// Variables pour le double-clic
unsigned long lastClickTime = 0;
bool doubleClickDetected = false;
const long doubleClickInterval = 500; // Intervalle pour détecter un double-clic (500 ms)
// Variables pour le clignotement
bool gameOver = false;
bool player1Blinking = false;
bool player2Blinking = false;
unsigned long blinkInterval = 500; // Intervalle de clignotement
unsigned long lastBlinkTime = 0;
bool blinkState = false;
void setup() {
// Configurer les broches des boutons comme entrées avec pullup
pinMode(buttonPlayer1, INPUT_PULLUP);
pinMode(buttonPlayer2, INPUT_PULLUP);
pinMode(modeButton, INPUT_PULLUP);
display.setBrightness(4); // Luminosité de 0 à 7
display.clear();
display2.setBrightness(4); // Luminosité de 0 à 7
display2.clear();
// Initialiser les deux afficheurs à 00:00
display.showNumberDecEx(0, 0x40, true, 2, 0); // Affiche "00"
display2.showNumberDecEx(0, 0x40, true, 2, 0); // Affiche "00"
}
void loop() {
unsigned long currentTime = millis();
// Gestion du double clic
if (digitalRead(modeButton) == LOW) {
if (currentTime - lastClickTime < doubleClickInterval) {
// Double clic détecté
doubleClickDetected = true;
resetGame(); // Appeler la fonction reset en cas de double-clic
}
lastClickTime = currentTime;
delay(300); // Anti-rebond
}
// Si le jeu est terminé, gérer le clignotement
if (gameOver) {
handleBlinking(currentTime);
return; // Sortir de la boucle tant que le jeu n'est pas réinitialisé
}
if (!gameStarted && !doubleClickDetected) {
// Choix du mode de jeu
if (digitalRead(modeButton) == LOW) {
delay(300); // Anti-rebond
gameMode++;
if (gameMode > 3) gameMode = 0; // Revenir au premier mode après le quatrième
// Ajuster les compteurs et les incréments selon le mode sélectionné
switch (gameMode) {
case 0:
counterPlayer1 = 180; // 3 minutes
counterPlayer2 = 180;
incrementPlayer1 = 0;
incrementPlayer2 = 0;
break;
case 1:
counterPlayer1 = 300; // 5 minutes
counterPlayer2 = 300;
incrementPlayer1 = 2; // +2 secondes
incrementPlayer2 = 2;
break;
case 2:
counterPlayer1 = 600; // 10 minutes
counterPlayer2 = 600;
incrementPlayer1 = 5; // +5 secondes
incrementPlayer2 = 5;
break;
case 3:
counterPlayer1 = 900; // 15 minutes
counterPlayer2 = 900;
incrementPlayer1 = 10; // +10 secondes
incrementPlayer2 = 10;
break;
}
// Afficher le temps initial sélectionné
displayTime(counterPlayer1, display);
displayTime(counterPlayer2, display2);
}
// Commencer le jeu lorsque l'un des boutons est pressé
if (digitalRead(buttonPlayer1) == LOW || digitalRead(buttonPlayer2) == LOW) {
gameStarted = true;
previousMillis = millis(); // Réinitialiser le chronomètre
}
} else if (!doubleClickDetected) {
unsigned long currentMillis = millis();
// Vérifier si le bouton du joueur 1 est pressé
if (digitalRead(buttonPlayer1) == LOW && !player1Turn) {
player1Turn = true;
player2Turn = false;
// Ajouter les secondes supplémentaires seulement si ce n'est pas le début
if (player1HasStarted) {
counterPlayer1 += incrementPlayer1; // Ajouter les secondes supplémentaires après le premier tour
} else {
player1HasStarted = true; // Marquer le compteur comme démarré
}
}
// Vérifier si le bouton du joueur 2 est pressé
if (digitalRead(buttonPlayer2) == LOW && !player2Turn) {
player1Turn = false;
player2Turn = true;
// Ajouter les secondes supplémentaires seulement si ce n'est pas le début
if (player2HasStarted) {
counterPlayer2 += incrementPlayer2; // Ajouter les secondes supplémentaires après le premier tour
} else {
player2HasStarted = true; // Marquer le compteur comme démarré
}
}
// Compteur pour le joueur 1
if (player1Turn && currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (counterPlayer1 > 0) {
counterPlayer1--;
} else {
// Le joueur 1 est à 0, le jeu est terminé
gameOver = true;
player1Blinking = true;
return;
}
displayTime(counterPlayer1, display);
}
// Compteur pour le joueur 2
if (player2Turn && currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (counterPlayer2 > 0) {
counterPlayer2--;
} else {
// Le joueur 2 est à 0, le jeu est terminé
gameOver = true;
player2Blinking = true;
return;
}
displayTime(counterPlayer2, display2);
}
}
}
// Fonction pour afficher le temps au format "MM:SS"
void displayTime(int seconds, TM1637Display& display) {
int minutes = seconds / 60;
int remainingSeconds = seconds % 60;
// Afficher le format MM:SS avec deux chiffres pour chaque partie
display.showNumberDecEx(minutes * 100 + remainingSeconds, 0x40, true);
}
// Fonction pour réinitialiser le jeu à l'état d'origine
void resetGame() {
// Remettre tous les états à l'état d'origine
gameStarted = false;
player1Turn = true;
player2Turn = false;
player1HasStarted = false;
player2HasStarted = false;
gameMode = 0;
// Réinitialiser les compteurs et les incréments
counterPlayer1 = 180;
counterPlayer2 = 180;
incrementPlayer1 = 0;
incrementPlayer2 = 0;
// Réinitialiser les afficheurs
display.clear();
display2.clear();
// Afficher le temps initial sur les afficheurs
displayTime(counterPlayer1, display);
displayTime(counterPlayer2, display2);
doubleClickDetected = false; // Réinitialiser le double-clic détecté
gameOver = false; // Remettre le jeu à l'état initial
player1Blinking = false;
player2Blinking = false;
blinkState = false;
}
// Fonction pour gérer le clignotement
void handleBlinking(unsigned long currentTime) {
if (currentTime - lastBlinkTime >= blinkInterval) {
lastBlinkTime = currentTime;
blinkState = !blinkState;
if (player1Blinking) {
if (blinkState) {
display.clear();
} else {
displayTime(counterPlayer1, display);
}
}
if (player2Blinking) {
if (blinkState) {
display2.clear();
} else {
displayTime(counterPlayer2, display2);
}
}
}
}