#include <MD_MAX72xx.h>
#include <SPI.h>
#include <Servo.h>
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 2
#define CLK_PIN 13
#define DATA_PIN 11
#define CS_PIN 10
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
Servo myservo;
int servoPin = 9;
const int VRx = A0;
const int VRy = A1;
const int SW = 2;
int xPosition = 0;
int yPosition = 0;
int a = 0;
int b = 1;
int snakeX[64], snakeY[64];
int snakeLength = 3;
int initialSnakeLength = 3;
int foodX, foodY;
int direction = 1;
int lastDirection = 1;
unsigned long lastMoveTime = 0;
const unsigned long moveInterval = 500;
void setup() {
mx.begin();
mx.control(MD_MAX72XX::INTENSITY, MAX_INTENSITY / 2);
mx.clear();
myservo.attach(servoPin);
myservo.write(90);
pinMode(SW, INPUT_PULLUP);
initializeSnake();
randomSeed(analogRead(0));
spawnFood();
}
void loop() {
xPosition = analogRead(VRx);
yPosition = analogRead(VRy);
a = digitalRead(SW);
if (yPosition < 300 && lastDirection != 2) {
direction = 0;
} else if (xPosition > 700 && lastDirection != 3) {
direction = 1;
} else if (yPosition > 700 && lastDirection != 0) {
direction = 2;
} else if (xPosition < 300 && lastDirection != 1) {
direction = 3;
}
if (direction != lastDirection) {
lastDirection = direction;
}
if (a == LOW && b == HIGH) {
resetGame();
}
b = a;
unsigned long currentTime = millis();
if (currentTime - lastMoveTime >= moveInterval) {
lastMoveTime = currentTime;
moveSnake();
if (checkCollision()) {
resetGame();
}
if (checkFood()) {
snakeLength++;
spawnFood();
}
if (snakeLength >= 10) {
myservo.write(45);
delay(500);
myservo.write(135);
delay(500);
}
drawGame();
}
}
void moveSnake() {
for (int i = snakeLength - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
if (direction == 0) snakeY[0]--;
else if (direction == 1) snakeX[0]++;
else if (direction == 2) snakeY[0]++;
else if (direction == 3) snakeX[0]--;
}
bool checkCollision() {
if (snakeX[0] < 0 || snakeX[0] >= 16 || snakeY[0] < 0 || snakeY[0] >= 8) {
return true;
}
for (int i = 1; i < snakeLength; i++) {
if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
return true;
}
}
return false;
}
bool checkFood() {
if (snakeX[0] == foodX && snakeY[0] == foodY) {
return true;
}
return false;
}
void spawnFood() {
bool validPosition = false;
while (!validPosition) {
foodX = random(0, 16);
foodY = random(0, 8);
validPosition = true;
for (int i = 0; i < snakeLength; i++) {
if (snakeX[i] == foodX && snakeY[i] == foodY) {
validPosition = false;
break;
}
}
}
}
void drawGame() {
mx.clear();
mx.setPoint(foodY, foodX, true);
for (int i = 0; i < snakeLength; i++) {
mx.setPoint(snakeY[i], snakeX[i], true);
}
}
void initializeSnake() {
snakeLength = initialSnakeLength;
snakeX[0] = 8;
snakeY[0] = 4;
snakeX[1] = 7;
snakeY[1] = 4;
snakeX[2] = 6;
snakeY[2] = 4;
direction = 1;
lastDirection = 1;
}
void resetGame() {
initializeSnake();
myservo.write(90);
spawnFood();
}