#include <LiquidCrystal.h>
#include <stdlib.h> // for random functions
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Define button pins - AVOID PIN CONFLICTS!
const int CONTRAST = 6; // Use this for contrast control if needed
const int RUN = 6;
const int PASS = 5;
const int LONGPASS = 4;
const int KICK = 3;
const int buttonManBlitz = 6;
const int buttonZoneBlitz = 5; // Changed to 7
const int buttonManCoverage = 4; // Changed to 8
const int buttonZone = 3; // Changed to 9
// Game variables
int yardsToGo = 10;
int down = 1;
int fieldPosition = 20; // Starting at the 20-yard line
bool offense = true; // Start on offense
int playerScore = 0;
int computerScore = 0;
void setup() {
// Initialize LCD
lcd.begin(16, 2);
// Initialize buttons as inputs with pull-up resistors
pinMode(RUN, INPUT_PULLUP);
pinMode(PASS, INPUT_PULLUP);
pinMode(LONGPASS, INPUT_PULLUP);
pinMode(KICK, INPUT_PULLUP);
pinMode(buttonManBlitz, INPUT_PULLUP);
pinMode(buttonZoneBlitz, INPUT_PULLUP);
pinMode(buttonManCoverage, INPUT_PULLUP);
pinMode(buttonZone, INPUT_PULLUP);
// Display initial game state
updateDisplay();
// Initialize random seed
randomSeed(analogRead(0));
}
void loop() {
// Check for button presses - IMPROVED TO PREVENT MULTIPLE READINGS
if (digitalRead(RUN) == LOW) {
play("Run");
} else if (digitalRead(PASS) == LOW) {
play("Pass");
} else if (digitalRead(LONGPASS) == LOW) {
play("Long Pass");
} else if (digitalRead(KICK) == LOW) {
play("Kick");
} else if (!offense && digitalRead(buttonManBlitz) == LOW) {
defensivePlay("Man Blitz");
} else if (!offense && digitalRead(buttonZoneBlitz) == LOW) {
defensivePlay("Zone Blitz");
} else if (!offense && digitalRead(buttonManCoverage) == LOW) {
defensivePlay("Man Coverage");
} else if (!offense && digitalRead(buttonZone) == LOW) {
defensivePlay("Zone Coverage");
}
delay(100); // Small delay to avoid holding down a button
}
void play(String playType) {
// Simulate the play outcome based on the chosen play type
int yardsGained = 0;
String computerChoice;
if (offense) {
computerChoice = getDefense(); // Get computer's defensive choice
} else {
computerChoice = getOffense();
}
if (playType == "Run") {
yardsGained = run(computerChoice);
} else if (playType == "Pass") {
yardsGained = pass(computerChoice);
} else if (playType == "Long Pass") {
yardsGained = longPass(computerChoice);
} else if (playType == "Kick") {
// Assume successful field goal if within range
if (fieldPosition >= 40) {
lcd.clear();
lcd.print("Field Goal Good!");
delay(2000);
if (offense) {
playerScore += 3;
} else {
computerScore += 3;
}
resetGame();
switchPossession(); // Switch to defense after score
} else {
lcd.clear();
lcd.print("Field Goal Missed!");
delay(2000);
turnover();
}
return;
}
// Display yards gained
lcd.clear();
if (yardsGained >= 0) {
lcd.print("Gain of ");
lcd.print(yardsGained);
} else {
lcd.print("Loss of ");
lcd.print(-yardsGained);
}
lcd.setCursor(0, 1); // Move to second row
lcd.print("AI: ");
lcd.print(computerChoice);
delay(2000);
// Update game state
yardsToGo -= yardsGained;
fieldPosition += yardsGained;
// Check for touchdown
if (fieldPosition >= 100) {
lcd.clear();
lcd.print("Touchdown!");
delay(2000);
if (offense) {
playerScore += 7;
} else {
computerScore += 7;
}
resetGame();
switchPossession();
return;
}
// Check for first down or turnover
if (yardsToGo <= 0) {
firstDown();
} else if (down >= 4) {
turnover();
} else {
down++;
}
// Update the display
updateDisplay();
checkGameOver(); // Check for game over after each play
}
void defensivePlay(String defenseType) {
int yardsGained = 0;
String computerChoice = getOffense();
if (defenseType == "Man Blitz") {
yardsGained = manBlitz(computerChoice);
} else if (defenseType == "Zone Blitz") {
yardsGained = zoneBlitz(computerChoice);
} else if (defenseType == "Man Coverage") {
yardsGained = manCoverage(computerChoice);
} else if (defenseType == "Zone Coverage"){
yardsGained = zoneCoverage(computerChoice);
}
// Display yards gained (from the perspective of the OFFENSE)
lcd.clear();
if (yardsGained >= 0) {
lcd.print("Gain of ");
lcd.print(yardsGained);
} else {
lcd.print("Loss of ");
lcd.print(-yardsGained);
}
lcd.setCursor(0, 1); // Move to the second row
lcd.print("AI: ");
lcd.print(computerChoice);
delay(2000);
// Update game state (from the perspective of the OFFENSE)
yardsToGo -= yardsGained;
fieldPosition += yardsGained;
// Check for touchdown (by the offense, even though it's a defensive play)
if (fieldPosition >= 100) {
lcd.clear();
lcd.print("Touchdown!");
delay(2000);
if (offense) {
playerScore += 7;
} else {
computerScore += 7;
}
resetGame();
switchPossession();
return;
}
// Check for first down or turnover
if (yardsToGo <= 0) {
firstDown();
} else if (down >= 4) {
turnover();
} else {
down++;
}
// Update the display
updateDisplay();
checkGameOver(); // Check for game over after each play
}
// Simulate different defensive plays
String getDefense() {
int defenseType = random(1, 5); // Changed to 5 to include Zone Coverage
switch (defenseType) {
case 1: return "Man Blitz";
case 2: return "Zone Blitz";
case 3: return "Man Coverage";
case 4: return "Zone Coverage";
}
}
// Run play with defense consideration
int run(String defense) {
int yards = 0;
if (defense == "Man Blitz" || defense == "Zone Blitz") {
int big_stop = random(100);
if (big_stop < 30) {
yards = random(-3, 2);
} else if (big_stop < 80) {
yards = random(1, 5);
} else {
yards = random(5, 20);
}
} else { // Man or Zone Coverage
int big_run = random(100);
if (big_run < 15) {
yards = random(10, 25);
} else if (big_run < 50) {
yards = random(6, 11);
} else {
yards = random(-1, 6);
}
}
return yards;
}
// Short Pass play with defense consideration
int pass(String defense) {
int yards = 0;
int outcome = random(0, 20);
if (defense == "Zone Blitz") {
if (outcome == 0) {
lcd.clear();
lcd.print("Interception!");
delay(2000);
turnover();
return 0; // Return 0 yards on turnover
} else if (outcome < 7) {
lcd.clear();
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
} else {
yards = random(5, 15);
}
} else if (defense == "Man Blitz") {
if (outcome < 2) {
lcd.clear();
lcd.print("Sack!");
delay(2000);
yards = random(-5, -10); // Lose yards on sack
} else if (outcome < 8) {
lcd.clear();
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
} else {
yards = random(5, 20);
}
} else { // Man or Zone Coverage
if (outcome == 0) {
lcd.clear();
lcd.print("Interception!");
delay(2000);
turnover();
return 0;
} else if (outcome < 10) {
lcd.clear();
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
} else {
yards = random(2, 13); // Normal pass yards
}
}
return yards;
}
int longPass(String defense) {
int yards = 0;
int outcome = random(0, 20);
if (defense == "Man Blitz") {
if (outcome < 3) {
lcd.clear(); // Clear before printing "Sack!"
lcd.print("Sack!");
delay(2000);
yards = random(-5, -10); // Lose yards on sack
} else if (outcome < 8) {
yards = random(25, 36);
} else if (outcome < 18) {
lcd.clear(); // Clear before printing "Incomplete!"
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
} else {
yards = random(5, 16);
}
} else if (defense == "Zone Blitz") {
if (outcome < 2) {
lcd.clear(); // Clear before printing "Sack!"
lcd.print("Sack!");
delay(2000);
yards = random(-5, -10); // Lose yards on sack
} else if (outcome < 5) {
lcd.clear(); // Clear before printing "Interception!"
lcd.print("Interception!");
delay(2000);
turnover();
return 0;
} else if (outcome < 17) {
yards = random(10, 26);
} else {
lcd.clear(); // Clear before printing "Incomplete!"
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
}
} else { // Man or Zone Coverage
if (outcome < 7) {
yards = random(25, 36);
} else if (outcome < 18) {
lcd.clear(); // Clear before printing "Incomplete!"
lcd.print("Incomplete!");
delay(1000);
return 0; // Return 0 yards on incompletion
} else {
yards = random(5, 16);
}
}
return yards;
}
void firstDown() {
yardsToGo = 10;
down = 1;
}
void turnover() {
lcd.clear();
lcd.print("Turnover!");
delay(2000);
switchPossession(); // Switch to defense after turnover
resetGame();
}
void switchPossession() {
offense = !offense; // Toggle between offense and defense
}
void resetGame(int position) {
yardsToGo = 10;
down = 1;
// The team that just scored kicks off
if (offense) {
if (position >= 100) {
fieldPosition = 80;
} else { // Turnover
fieldPosition = 100 - position;
}
} else if (position <= 0) {
fieldPosition = 20; // Defense (now on offense) starts at their own 20
} else {
fieldPosition = 100 - position;
}
updateDisplay();
}
void updateDisplay() {
lcd.clear();
lcd.print("Down:");
lcd.print(down);
lcd.print(" & ");
lcd.print(yardsToGo);
lcd.setCursor(0, 1);
// Adjust field position display to show opponent's side of the field
if (fieldPosition > 50) {
lcd.print("Opp ");
lcd.print(100 - fieldPosition);
} else {
lcd.print("Own ");
lcd.print(fieldPosition);
}
// Add indicator for offense/defense
if (offense) {
lcd.print(" (O)");
} else {
lcd.print(" (D)");
}
}
String getOffense() {
if (fieldPosition <= 40 && down = 4) {
return "Kick";
} else {
int offenseType = random(1, 4);
switch (offenseType) {
case 1: return "Run";
case 2: return "Pass";
case 3: return "Long Pass";
}
}
}
int manBlitz(String offense) {
if (offense == "Run") {
return random(-1, 5);
} else if (offense == "Pass") {
int sackOrLong = random(5);
if (sackOrLong == 0) {
lcd.clear();
lcd.print("Sack!");
delay(2000);
return -5;
} else if (sackOrLong == 1) { // long!
lcd.clear();
lcd.print("Over the top!");
delay(2000);
return random(15, 30);
} else {
return random(5, 15);
}
}
return 0; // Add a default return to avoid warnings
}
int zoneBlitz(String offense) {
if (offense == "Run") {
return random(1, 7);
} else if (offense == "Pass") {
// Small chance of interception
if (random(0, 10) == 0) {
lcd.clear();
lcd.print("Interception!");
delay(2000);
turnover();
return 0;
} else {
return random(5, 15);
}
}
return 0; // Add a default return to avoid warnings
}
int manCoverage(String offense) {
if (offense == "Run") {
return random(3, 9);
} else if (offense == "Pass") {
if (random(10) == 0) {
lcd.clear();
lcd.print("Interception!");
delay(2000);
turnover();
return 0;
} else {
return random(0, 8);
}
}
return 0; // Add a default return to avoid warnings
}
int zoneCoverage(String offense) {
if (offense == "Run") {
return random(2, 8);
} else if (offense == "Pass") {
if (random(10) == 0) {
lcd.clear();
lcd.print("Interception!");
delay(2000);
turnover();
return 0;
} else {
return random(0, 10);
}
}
return 0; // Add a default return to avoid warnings
}
void checkGameOver() {
if (playerScore >= 21 || computerScore >= 21) {
lcd.clear();
if (playerScore > computerScore) {
lcd.print("You Win!");
} else {
lcd.print("Computer Wins!");
}
while (true) {
// Game over loop - you might want to add a reset button here
delay(100);
}
}
}