#include <Servo.h>
#include <MD_MAX72xx.h>
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
#define MAX_DEVICES 4
#define VERT_PIN A0
#define HORZ_PIN A1
#define SEL_PIN 2
const int maxX = MAX_DEVICES * 8 - 1;
const int maxY = 31;
MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::PAROLA_HW, CS_PIN, MAX_DEVICES);
Servo myservo;
int snakeX[100] = {0, 1, 2};
int snakeY[100] = {0, 0, 0};
int snakeLength = 3;
int beanX, beanY;
bool gameRunning = true;
char direction = 'R'; // Initial direction: 'U', 'D', 'L', 'R'
void setup() {
myservo.attach(9);
mx.begin();
// Initialize snake and bean
drawSnake();
generateBean();
pinMode(VERT_PIN, INPUT);
pinMode(HORZ_PIN, INPUT);
pinMode(SEL_PIN, INPUT_PULLUP);
randomSeed(analogRead(0)); // Seed random number generator
}
void loop() {
if (digitalRead(SEL_PIN) == LOW) {
restartGame();
return;
}
if (!gameRunning) {
return;
}
readJoystick();
int x = snakeX[0];
int y = snakeY[0];
// Update position based on direction
switch (direction) {
case 'U': y = max(y - 1, 0); break;
case 'D': y = min(y + 1, maxY); break;
case 'L': x = max(x - 1, 0); break;
case 'R': x = min(x + 1, maxX); break;
}
// Check collision with bean
if (x == beanX && y == beanY) {
snakeLength++;
generateBean();
if (snakeLength == 10) {
for (int i = 0; i < 3; i++) {
myservo.write(180);
delay(500);
myservo.write(0);
delay(500);
}
}
}
// Check collision with boundaries or self
if (x < 0 || x > maxX || y < 0 || y > maxY || checkSelfCollision(x, y)) {
gameRunning = false;
return;
}
// Update snake position
for (int i = snakeLength - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
snakeX[0] = x;
snakeY[0] = y;
// Update display
mx.clear();
drawSnake();
mx.setPoint(beanY, beanX, true);
mx.update();
delay(100);
}
void readJoystick() {
int vert = analogRead(VERT_PIN);
int horz = analogRead(HORZ_PIN);
if (vert < 300 && direction != 'D') {
direction = 'U';
}
if (vert > 700 && direction != 'U') {
direction = 'D';
}
if (horz > 700 && direction != 'L') {
direction = 'R';
}
if (horz < 300 && direction != 'R') {
direction = 'L';
}
}
void generateBean() {
beanX = random(0, maxX + 1);
beanY = random(0, maxY + 1);
while (checkSelfCollision(beanX, beanY)) {
beanX = random(0, maxX + 1);
beanY = random(0, maxY + 1);
}
mx.setPoint(beanY, beanX, true);
}
bool checkSelfCollision(int x, int y) {
for (int i = 0; i < snakeLength; i++) {
if (snakeX[i] == x && snakeY[i] == y) {
return true;
}
}
return false;
}
void drawSnake() {
for (int i = 0; i < snakeLength; i++) {
mx.setPoint(snakeY[i], snakeX[i], true);
}
}
void restartGame() {
snakeLength = 3;
for (int i = 0; i < snakeLength; i++) {
snakeX[i] = i;
snakeY[i] = 0;
}
direction = 'R';
gameRunning = true;
mx.clear();
drawSnake();
generateBean();
}