#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 PADDLE_HEIGHT 10
#define PADDLE_WIDTH 2
#define BALL_SIZE 3
// Paddle positions
int playerPaddleY = SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2;
int aiPaddleY = SCREEN_HEIGHT / 2 - PADDLE_HEIGHT / 2;
// Ball position and speed
float ballX = SCREEN_WIDTH / 2;
float ballY = SCREEN_HEIGHT / 2;
float ballSpeedX = -2;
float ballSpeedY = 1;
// AI parameters
float aiSpeed = 1.5; // AI reaction speed
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_I2C_ADDRESS, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
}
void loop() {
// Update ball position
ballX += ballSpeedX;
ballY += ballSpeedY;
// Ball collision with top and bottom
if (ballY <= 0 || ballY >= SCREEN_HEIGHT - BALL_SIZE) {
ballSpeedY *= -1;
}
// Ball collision with player paddle
if (ballX <= PADDLE_WIDTH && ballY > playerPaddleY && ballY < playerPaddleY + PADDLE_HEIGHT) {
ballSpeedX *= -1;
}
// Ball collision with AI paddle
if (ballX >= SCREEN_WIDTH - PADDLE_WIDTH - BALL_SIZE &&
ballY > aiPaddleY && ballY < aiPaddleY + PADDLE_HEIGHT) {
ballSpeedX *= -1;
}
// Ball reset if it goes off-screen
if (ballX < 0 || ballX > SCREEN_WIDTH) {
ballX = SCREEN_WIDTH / 2;
ballY = SCREEN_HEIGHT / 2;
ballSpeedX = -ballSpeedX; // Reset direction
}
// AI Paddle movement (basic logic, replace with Q-learning)
if (ballY > aiPaddleY + PADDLE_HEIGHT / 2) {
aiPaddleY += aiSpeed;
} else {
aiPaddleY -= aiSpeed;
}
aiPaddleY = constrain(aiPaddleY, 0, SCREEN_HEIGHT - PADDLE_HEIGHT);
// Drawing
display.clearDisplay();
// Draw paddles
display.fillRect(0, playerPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT, SSD1306_WHITE);
display.fillRect(SCREEN_WIDTH - PADDLE_WIDTH, aiPaddleY, PADDLE_WIDTH, PADDLE_HEIGHT, SSD1306_WHITE);
// Draw ball
display.fillRect(ballX, ballY, BALL_SIZE, BALL_SIZE, SSD1306_WHITE);
// Update display
display.display();
delay(20); // Adjust speed
}