Skip to content

Instantly share code, notes, and snippets.

@stefreak
Created December 16, 2013 22:48
Show Gist options
  • Save stefreak/7995953 to your computer and use it in GitHub Desktop.
Save stefreak/7995953 to your computer and use it in GitHub Desktop.
arduino fritzing led matrix snake
#define X 1
#define Y 0
#define GAMESTATE_NORMAL 0
#define GAMESTATE_GAMEOVER 1
int soundPin = 4;
int rowPins[8] = {
9,22,18,12,15,11,7,6}; // matrix rows connected to the Arduino
int colPins[8] = {
13,8,17,10,5,16,19,14}; // matrix columns connected to the Arduino
int image[8][8]={ // the image displayed on the matrix : 1 = LED on, 0 = LED off
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
,
{
1,1,1,1,1,1,1,1 }
};
#define BUTTON_LEFT 1
#define BUTTON_RIGHT 2
int leftPin = 2;
int rightPin = 3;
int buttonStackLength = 0;
int buttonStack[10] = {
0,0,0,0,0,0,0,0,0,0};
void pushButton(int button) {
buttonStack[buttonStackLength++] = button;
}
int getNextButton() {
if (buttonStackLength > 0) {
int nextButton = buttonStack[0];
memmove(&buttonStack[0], &buttonStack[1], sizeof(buttonStack) - sizeof(*buttonStack));
buttonStackLength --;
return nextButton;
}
return 0;
}
int gameState = GAMESTATE_NORMAL;
int snakeLength = 3;
int snake[100][2]={
{
0,0 }
, {
1,0 }
, {
2,0 }
};
int snakeDirection[2] = {
1, 0};
int foodInvalid = 1;
int food[2] = {
0, 0};
int speedMultiplier = 40;
void setup(){
for (int i=0; i<8; i++){ // all pins are declared as outputs
pinMode(rowPins[i],OUTPUT);
pinMode(colPins[i],OUTPUT);
}
pinMode(soundPin, OUTPUT);
pinMode(leftPin, INPUT);
pinMode(rightPin, INPUT);
fill(0);
gameState = GAMESTATE_NORMAL;
speedMultiplier = 40;
Serial.begin(9600);
}
unsigned long counter = 0;
void loop(){
if (gameState == GAMESTATE_GAMEOVER) {
fill(1);
render();
tone(soundPin, 120, 100);
if (! (counter++ % (500))) {
software_Reset() ;
}
return;
}
readButtonStates();
if (! (counter++ % (10000/speedMultiplier))) {
tick();
}
render();
}
int tickCount = 0;
void tick() {
fill(0);
makeFood();
int nextButton = getNextButton();
if (nextButton == BUTTON_LEFT) {
turnLeft();
}
if (nextButton == BUTTON_RIGHT) {
turnRight();
}
moveSnake();
// blit
image[food[X]][food[Y]] = 1;
for (int i=0; i<snakeLength; i++) {
image[snake[i][X]][snake[i][Y]] = 1;
}
}
int lastLeftState = -1;
int lastRightState = -1;
void readButtonStates() {
int leftState = digitalRead(leftPin);
int rightState = digitalRead(rightPin);
if (lastLeftState != leftState) {
if (leftState == LOW) {
//Serial.println("LEFT: %i");
pushButton(BUTTON_LEFT);
}
}
if (lastRightState != rightState) {
if (rightState == LOW) {
pushButton(BUTTON_RIGHT);
}
}
lastLeftState = leftState;
lastRightState = rightState;
}
void moveSnake() {
if (snake[snakeLength-1][Y] + snakeDirection[Y] == food[Y] && snake[snakeLength-1][X] + snakeDirection[X] == food[X]) {
tone(soundPin, 261, 100);
snake[snakeLength][X] = food[X];
snake[snakeLength][Y] = food[Y];
snakeLength+=1;
foodInvalid = 1;
//speedMultiplier += 5;
return;
}
memmove(&snake[0], &snake[1], sizeof(snake) - sizeof(*snake));
if (snakeHitCoordinates(snake[snakeLength-2][X] + snakeDirection[X], snake[snakeLength-2][Y] + snakeDirection[Y])) {
gameState = GAMESTATE_GAMEOVER;
counter = 1;
}
snake[snakeLength-1][X] = snake[snakeLength-2][X] + snakeDirection[X];
snake[snakeLength-1][Y] = snake[snakeLength-2][Y] + snakeDirection[Y];
if(snake[snakeLength-1][Y] < 0 || snake[snakeLength-1][Y] > 7 || snake[snakeLength-1][X] < 0 || snake[snakeLength-1][X] > 7) {
gameState = GAMESTATE_GAMEOVER;
counter = 1;
}
}
void turnRight() {
if (snakeDirection[X] == 1 && snakeDirection[Y] == 0) {
snakeDirection[X] = 0;
snakeDirection[Y] = -1;
}
else if (snakeDirection[X] == 0 && snakeDirection[Y] == 1) {
snakeDirection[X] = 1;
snakeDirection[Y] = 0;
}
else if (snakeDirection[X] == -1 && snakeDirection[Y] == 0) {
snakeDirection[X] = 0;
snakeDirection[Y] = 1;
}
else if (snakeDirection[X] == 0 && snakeDirection[Y] == -1) {
snakeDirection[X] = -1;
snakeDirection[Y] = 0;
}
}
void turnLeft() {
if (snakeDirection[X] == 1 && snakeDirection[Y] == 0) {
snakeDirection[X] = 0;
snakeDirection[Y] = 1;
}
else if (snakeDirection[X] == 0 && snakeDirection[Y] == 1) {
snakeDirection[X] = -1;
snakeDirection[Y] = 0;
}
else if (snakeDirection[X] == -1 && snakeDirection[Y] == 0) {
snakeDirection[X] = 0;
snakeDirection[Y] = -1;
}
else if (snakeDirection[X] == 0 && snakeDirection[Y] == -1) {
snakeDirection[X] = 1;
snakeDirection[Y] = 0;
}
}
void makeFood() {
if (foodInvalid) {
foodInvalid = 0;
do {
food[X] = random(0, 7);
food[Y] = random(0, 7);
}
while (snakeHitCoordinates(food[X], food[Y]));
}
}
bool snakeHitCoordinates(int Xcoord, int Ycoord) {
for (int i=0; i<snakeLength; i++) {
if (snake[i][X] == Xcoord && snake[i][Y] == Ycoord) {
return 1;
}
}
return 0;
}
void fill(int i) {
for (int y=0; y<8; y++){
for (int x=0; x<8; x++){
image[x][y] = i;
}
}
}
void render() {
for (int y=0; y<8; y++){ // rowwise
for (int x=0; x<8; x++){ // check all entries of the array from left to right
if (image[x][y]==1){ // is the entry 1
digitalWrite(colPins[x],HIGH); // switch on column pin
}
else { // else
digitalWrite(colPins[x],LOW); // switch it off
}
}
digitalWrite(rowPins[y],LOW); // switch the row pin to LOW (because it is the cathode of the LED; LOW means ON)
delayMicroseconds(100); // stop the program for 100 milliseconds
digitalWrite(rowPins[y],HIGH); // switch the row pin to HIGH (this means OFF)
}
}
void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile (" jmp 0");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment