#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ILI9341.h> // Hardware-specific library
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define BUTTON_PIN_1 2 // Player 1 Score Button
#define BUTTON_PIN_2 3 // Player 2 Score Button
#define RESET_PIN 4 // Reset Button
#define GAME_BUTTON_PIN 5 // Button to change game mode
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Game modes
enum GameMode {
TABLE_TENNIS,
VOLLEYBALL,
BADMINTON
};
// Game-specific variables
int player1Score = 0;
int player2Score = 0;
bool player1Serving = true; // Player 1 serves first
GameMode currentGameMode = TABLE_TENNIS;
bool lastPoint= true; //True Means Player1
void setup() {
Serial.begin(9600);
tft.begin();
tft.setRotation(3); // Adjust if needed
pinMode(BUTTON_PIN_1, INPUT_PULLUP);
pinMode(BUTTON_PIN_2, INPUT_PULLUP);
pinMode(RESET_PIN, INPUT_PULLUP);
pinMode(GAME_BUTTON_PIN, INPUT_PULLUP);
drawScoreboard();
}
void loop() {
// Check for button press to change game mode
if (digitalRead(GAME_BUTTON_PIN) == LOW) {
changeGameMode();
delay(200); // Debouncing delay
}
// Handle scoring and serving based on current game mode
if (currentGameMode == TABLE_TENNIS) {
handleTableTennis();
} else if (currentGameMode == VOLLEYBALL) {
handleVolleyball();
} else if (currentGameMode == BADMINTON) {
handleBadminton();
}
}
void handleTableTennis() {
// Table tennis scoring and serving logic
if (digitalRead(BUTTON_PIN_1) == LOW) {
player1Score++;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(BUTTON_PIN_2) == LOW) {
player2Score++;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(RESET_PIN) == LOW) {
player1Score = 0;
player2Score = 0;
updateScore();
delay(200); // Debouncing delay
}
}
void handleVolleyball() {
// Volleyball scoring and serving logic
if (digitalRead(BUTTON_PIN_1) == LOW) {
player1Score++;
lastPoint = true;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(BUTTON_PIN_2) == LOW) {
player2Score++;
lastPoint = false;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(RESET_PIN) == LOW) {
player1Score = 0;
player2Score = 0;
lastPoint = true;
updateScore();
delay(200); // Debouncing delay
}
}
void handleBadminton() {
// Badminton scoring and serving logic
if (digitalRead(BUTTON_PIN_1) == LOW) {
player1Score++;
lastPoint = true;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(BUTTON_PIN_2) == LOW) {
player2Score++;
lastPoint = false;
updateScore();
delay(200); // Debouncing delay
}
if (digitalRead(RESET_PIN) == LOW) {
player1Score = 0;
player2Score = 0;
lastPoint = true;
updateScore();
delay(200); // Debouncing delay
}
}
void changeGameMode() {
// Toggle between game modes
currentGameMode = static_cast<GameMode>((currentGameMode + 1) % 3); // Assuming 3 game modes
player1Score = 0;
player2Score = 0;
player1Serving = true; // Reset serving indicator
drawScoreboard(); // Redraw scoreboard for the new game mode
}
void updateScore() {
// Clear previous score and serving information
tft.fillRect(10, 100, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 140, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 40, 220, 40, ILI9341_BLACK);
// Draw updated score
drawScoreboard();
// Check for winner based on current game mode
if (currentGameMode == TABLE_TENNIS) {
if (player1Score >= 11 && player1Score - player2Score >= 2) {
displayWinner("Player 1");
} else if (player2Score >= 11 && player2Score - player1Score >= 2) {
displayWinner("Player 2");
} else {
if((player1Score + player2Score) < 20){
if((player1Score + player2Score) % 2 == 0 && (player1Score + player2Score) !=0){
player1Serving = !player1Serving;
}
}
else{
player1Serving = !player1Serving;
}
displayServing();
}
} else if (currentGameMode == VOLLEYBALL) {
if (player1Score >= 25 && player1Score - player2Score >= 2) {
displayWinner("Team 1");
} else if (player2Score >= 25 && player2Score - player1Score >= 2) {
displayWinner("Team 2");
} else {
if(lastPoint){
player1Serving= true;
}
else{
player1Serving = false;
}
displayServing();
}
} else if (currentGameMode == BADMINTON) {
if (player1Score >= 21 && player1Score - player2Score >= 2) {
displayWinner("Player 1");
} else if (player2Score >= 21 && player2Score - player1Score >= 2) {
displayWinner("Player 2");
} else {
if(lastPoint){
player1Serving= true;
}
else{
player1Serving = false;
}
displayServing();
}
}
}
void drawScoreboard() {
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
if(currentGameMode == TABLE_TENNIS || currentGameMode == BADMINTON){
tft.fillRect(10, 100, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 140, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 40, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 200, 220, 40, ILI9341_BLACK);
if(currentGameMode == TABLE_TENNIS){
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(2);
tft.setCursor(10, 200);
tft.print("Table Tennis");
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, 100);
}
else{
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(2);
tft.setCursor(10, 200);
tft.print("Badminton");
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, 100);
}
tft.print("Player 1: ");
tft.print(player1Score);
tft.setCursor(10, 140);
tft.print("Player 2: ");
tft.print(player2Score);
if((player1Score + player2Score) == 0){
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.setCursor(10, 40);
tft.print("Player 1 serving");
}
}
else{
tft.fillRect(10, 100, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 140, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 40, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 200, 220, 40, ILI9341_BLACK);
tft.setTextColor(ILI9341_BLUE);
tft.setTextSize(2);
tft.setCursor(10, 200);
tft.print("Volleyball");
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, 100);
tft.print("Team 1: ");
tft.print(player1Score);
tft.setCursor(10, 140);
tft.print("Team 2: ");
tft.print(player2Score);
if((player1Score + player2Score) == 0){
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.setCursor(10, 40);
tft.print("Team 1 serving");
}
}
}
void displayServing() {
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.setCursor(10, 40);
if(currentGameMode == TABLE_TENNIS || currentGameMode == BADMINTON){
if (player1Serving) {
tft.print("Player 1 serving");
} else {
tft.print("Player 2 serving");
}
}
else{
if (player1Serving) {
tft.print("Team 1 serving");
} else {
tft.print("Team 2 serving");
}
}
}
void displayWinner(String winner) {
tft.fillRect(10, 100, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 140, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 40, 220, 40, ILI9341_BLACK);
tft.fillRect(10, 200, 220, 40, ILI9341_BLACK);
// Display winner
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(3.5);
tft.setCursor(10, 100);
tft.print(winner + " Wins!");
// Delay for 2 seconds before resetting the scoreboard
delay(3000);
// Reset scoreboard after delay
resetScoreboard();
}
void resetScoreboard() {
// Reset scoreboard for a new game
player1Score = 0;
player2Score = 0;
lastPoint = true;
drawScoreboard();
}