#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define HIT_BUTTON 2
#define STAND_BUTTON 3
#define INC_BET_BUTTON 4
#define DEC_BET_BUTTON 5
#define CONFIRM_BET_BUTTON 6
#define DIFFICULTY_BUTTON 7
#define TOKEN_MACHINE_BUTTON 8
#define BUZZER_PIN 11
int playerScore = 0;
int dealerScore = 0;
bool playerTurn = true;
bool gameOver = false;
int playerMoney = 100;
int playerBet = 10;
int difficulty = 1; // 1 for easy, 2 for medium, 3 for hard
String deck[52];
int deckIndex = 0;
String playerHand[5], dealerHand[5];
int playerCardCount = 0, dealerCardCount = 0;
void setup() {
Serial.begin(9600);
// Initialize pins
pinMode(HIT_BUTTON, INPUT_PULLUP);
pinMode(STAND_BUTTON, INPUT_PULLUP);
pinMode(INC_BET_BUTTON, INPUT_PULLUP);
pinMode(DEC_BET_BUTTON, INPUT_PULLUP);
pinMode(CONFIRM_BET_BUTTON, INPUT_PULLUP);
pinMode(DIFFICULTY_BUTTON, INPUT_PULLUP);
pinMode(TOKEN_MACHINE_BUTTON, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
delay(2000);
display.clearDisplay();
display.display();
randomSeed(analogRead(0));
initializeDeck();
resetGame();
}
void loop() {
handleButtons();
if (gameOver) {
delay(3000); // Wait for 3 seconds
resetGame();
}
}
void initializeDeck() {
String suits[4] = {"H", "D", "C", "S"};
String values[13] = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
int index = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 13; j++) {
deck[index++] = values[j] + suits[i];
}
}
for (int i = 0; i < 52; i++) {
int r = random(0, 52);
String temp = deck[i];
deck[i] = deck[r];
deck[r] = temp;
}
deckIndex = 0;
}
String drawCard() {
if (deckIndex >= 52) {
initializeDeck();
}
return deck[deckIndex++];
}
int getCardValue(String card) {
char value = card.charAt(0);
if (value == 'A') return 11;
if (value == 'K' || value == 'Q' || value == 'J' || value == '1') return 10;
return value - '0';
}
int calculateHandValue(String hand[], int cardCount) {
int total = 0;
int aceCount = 0;
for (int i = 0; i < cardCount; i++) {
int value = getCardValue(hand[i]);
total += value;
if (hand[i].indexOf('A') != -1) {
aceCount++;
}
}
while (total > 21 && aceCount > 0) {
total -= 10;
aceCount--;
}
return total;
}
void displayGameState() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Player: ");
for (int i = 0; i < playerCardCount; i++) {
display.print(playerHand[i]);
display.print(" ");
}
display.setCursor(0, 10);
display.print("Player Score: ");
display.print(calculateHandValue(playerHand, playerCardCount));
display.setCursor(0, 20);
display.print("Dealer: ");
for (int i = 0; i < dealerCardCount; i++) {
display.print(dealerHand[i]);
display.print(" ");
}
display.setCursor(0, 30);
display.print("Dealer Score: ");
if (playerTurn) {
display.print("?");
} else {
display.print(calculateHandValue(dealerHand, dealerCardCount));
}
display.setCursor(0, 40);
if (playerTurn) {
display.print("Hit or Stand?");
} else {
if (dealerScore > 21 || dealerScore < playerScore) {
display.print("You Win!");
playWinSound();
} else {
display.print("You Lose!");
playLoseSound();
}
}
display.setCursor(0, 50);
display.print("Bet: ");
display.print(playerBet);
display.print(" Money: ");
display.print(playerMoney);
display.display();
}
void handleButtons() {
if (!gameOver) {
if (digitalRead(HIT_BUTTON) == LOW) {
playerHand[playerCardCount++] = drawCard();
playerScore = calculateHandValue(playerHand, playerCardCount);
playHitSound();
displayGameState();
delay(300); // Debounce delay
}
if (digitalRead(STAND_BUTTON) == LOW) {
playerTurn = false;
playStandSound();
dealerPlay();
displayGameState();
delay(300); // Debounce delay
}
if (playerScore > 21) {
gameOver = true;
displayGameOver();
}
if (digitalRead(INC_BET_BUTTON) == LOW) {
if (playerBet + 10 <= playerMoney) {
playerBet += 10;
displayGameState();
delay(300); // Debounce delay
}
}
if (digitalRead(DEC_BET_BUTTON) == LOW) {
if (playerBet - 10 >= 10) {
playerBet -= 10;
displayGameState();
delay(300); // Debounce delay
}
}
if (digitalRead(CONFIRM_BET_BUTTON) == LOW) {
playerCardCount = 0;
dealerCardCount = 0;
playerHand[playerCardCount++] = drawCard();
playerHand[playerCardCount++] = drawCard();
dealerHand[dealerCardCount++] = drawCard();
dealerHand[dealerCardCount++] = drawCard();
displayGameState();
delay(300); // Debounce delay
}
if (digitalRead(DIFFICULTY_BUTTON) == LOW) {
handleDifficulty();
displayGameState();
delay(300); // Debounce delay
}
if (digitalRead(TOKEN_MACHINE_BUTTON) == LOW) {
handleTokenMachine();
displayGameState();
delay(300); // Debounce delay
}
}
}
void dealerPlay() {
while (calculateHandValue(dealerHand, dealerCardCount) < (difficulty == 1 ? 17 : difficulty == 2 ? 18 : 19)) {
dealerHand[dealerCardCount++] = drawCard();
}
dealerScore = calculateHandValue(dealerHand, dealerCardCount);
gameOver = true;
}
void resetGame() {
playerScore = 0;
dealerScore = 0;
playerCardCount = 0;
dealerCardCount = 0;
playerTurn = true;
gameOver = false;
playerHand[playerCardCount++] = drawCard();
playerHand[playerCardCount++] = drawCard();
dealerHand[dealerCardCount++] = drawCard();
dealerHand[dealerCardCount++] = drawCard();
displayGameState();
}
void playHitSound() {
tone(BUZZER_PIN, 500, 100);
}
void playStandSound() {
tone(BUZZER_PIN, 400, 100);
}
void playWinSound() {
tone(BUZZER_PIN, 1000, 200);
delay(200);
tone(BUZZER_PIN, 1000, 200);
}
void playLoseSound() {
tone(BUZZER_PIN, 200, 400);
}
void displayGameOver() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 20);
if (playerScore > 21) {
display.print(" BUSTED!");
playLoseSound();
} else {
if (dealerScore > 21 || dealerScore < playerScore) {
display.print("You Win!");
playWinSound();
} else {
display.print("You Lose!");
playLoseSound();
}
}
display.display();
}
void handleDifficulty() {
difficulty++;
if (difficulty > 3) {
difficulty = 1;
}
}
void handleTokenMachine() {
playerMoney += 100;
}