Trey German
Published

Big Snake

A bigger and badder game of SNAKE! Now with wireless controls!

AdvancedShowcase (no instructions)3,444
Big Snake

Things used in this project

Story

Read more

Code

Wireless Controller Firmware

C/C++
Energia sketch for the wireless controller (MSP430F5529 LP + CC110L BoosterPack + Educational BoosterPack MK II)
/**
 *  Wireless Controller Sketch for the Big Snake Game.
 *  This sketch is designed to run on a MSP430F5529 LaunchPad with 
 *  a CC110L and Educational BoosterPack MK II attached.
 *  
 *  Trey German 2015
 *  @yertnamreg
 */
 
 
#include <SPI.h>
#include <AIR430BoostFCC.h>

// -----------------------------------------------------------------------------
/**
 *  Defines, enumerations, and structure definitions
 */

#define ADDRESS_LOCAL    0x03
#define ADDRESS_REMOTE   0x01

/**
 *  sPacket - packet format.
 */
struct sPacket
{
  uint8_t from;           // Local node address that message originated from
  uint8_t message;    // Local node message [MAX. 59 bytes]
};

// -----------------------------------------------------------------------------
/**
 *  Global data
 */

struct sPacket txPacket;

// -----------------------------------------------------------------------------
// Main example

const int joystickSel = 5;     // the number of the joystick select pin
const int joystickX = 2;       // the number of the joystick X-axis analog
const int joystickY =  26;     // the number of the joystick Y-axis analog
int joystickSelState = 0;      // variable for reading the joystick sel status
int joystickXState, joystickYState ; 

void setup()
{
  // The radio library uses the SPI library internally, this call initializes
  // SPI/CSn and GDO0 lines. Also setup initial address, channel, and TX power.
  Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX);

  txPacket.from = ADDRESS_LOCAL;

  // Setup serial for debug printing.
  Serial.begin(9600);


  // initialize the pushbutton pin as an input:
  pinMode(joystickSel, INPUT_PULLUP);   


  pinMode(RED_LED, OUTPUT);       // Use red LED to display message reception
  digitalWrite(RED_LED, LOW);
}

void loop()
{
  int i, j;
  delay(10);    // Send every second


  //Clear previous message
  txPacket.message = 0;
  
    // read the analog value of joystick x axis
  joystickXState = analogRead(joystickX);
    // read the analog value of joystick y axis
  joystickYState = analogRead(joystickY);
  
    // read the state of the joystick select button value:
  joystickSelState = digitalRead(joystickSel);

  
  
    Serial.println(" X: ");
  Serial.println(joystickXState);
    Serial.println(" Y: ");
  Serial.println(joystickYState);
  
  
  if(joystickXState > 3000){
    txPacket.message |= 1;  //Up X
  }else if(joystickXState < 1000){
    txPacket.message |= 2;  //Down X  
  }
  
  if(joystickYState > 3000){
    txPacket.message |= 4; // Up Y
  }else if(joystickYState < 1000){
    txPacket.message |= 8; // Down X
  }
  
  if (joystickSelState == LOW) {     
    // turn LED on:    
    txPacket.message |= 0x10;
  } 
  else {
    // turn LED off:
    txPacket.message &= ~0x10;
  }
  
  
  Radio.transmit(ADDRESS_REMOTE, (unsigned char*)&txPacket, sizeof(txPacket));
}

Big Snake Firmware

C/C++
Energia sketch for the main game processor/display driver (TM4C129 LP + CC110L BP)
/**
 *  Big Snake Game.
 *  This sketch is designed to run on a TM4C129 LaunchPad with 
 *  10 Olimex 8x8 RGB LED Modules and a CC110L BoosterPack attached.
 *
 *  This code was ported to use the Texas Instruments LaunchPad and 
 *  Olimex RGB LED displays.  Original author comments below.
 *  
 *  Trey German 2015
 *  @yertnamreg
 */

// Code Example for jolliFactory Bi-color LED Matrix Snake Game example 1.0

// Adapted from - http://forum.arduino.cc/index.php/topic,8280.0.html#11
// Snake Game program coded for either 1 or 2 Bi-color LED Matrix Snake Game - Just change the value of variable bi_maxInUse



/* ============================= LED Matrix Display ============================= */
#include <SPI.h>   
#include "lcd8x8rgb.h"  

#include <AIR430BoostFCC.h>
       
#define GREEN 0                          
#define RED 1                            


int bi_maxInUseX = 2; // No. of Bi-color LED Matrix used  // Snake Game program for either 1 or 2 LED Matrix Snake Game - Just change the value of variable bi_maxInUse
int bi_maxInUseY = 5; // No. of Bi-color LED Matrix used  // Snake Game program for either 1 or 2 LED Matrix Snake Game - Just change the value of variable bi_maxInUse


//Radio stuff
#define ADDRESS_LOCAL    0x01

/**
 *  sPacket - packet format.
 */
struct sPacket
{
  uint8_t from;           // Local node address that message originated from
  uint8_t message[59];    // Local node message [MAX. 59 bytes]
};

// -----------------------------------------------------------------------------
/**
 *  Global data
 */

struct sPacket rxPacket;


unsigned char h[] = "Big Snake";
unsigned char e[] = " Game Over";
unsigned char c[] = "Click";
unsigned char points[12];


int numrow = 8 * bi_maxInUseY;
int numcol = 8 * bi_maxInUseX;
int mask8 = B11111111;
int row = 0;
int col = 0;
int pixel = 0;
int pointer = 0;

int empty = 0;
int red = 1;
int green = 2;
int orange = 3;

int direction = 1;


byte matrix[640];
int snake[640];
int newsnake[640];

int snakehead = 0;
int oldsnakehead = 0;
int snaketail = 0;
int applecaught = 0;
int apple = 0;
int moveSpeed = 150;

int score = 0;

unsigned long lastMillis = 0;

int button1value = HIGH;

unsigned long startTime;
unsigned long elapsedTime;
int cnt = 0;
boolean gameoverFlag = false;



//**********************************************************************************************************************************************************  
void setup() 
{

  Serial.begin (115200);
  Serial.println("LED Snake Game + Wireless Controls");

   //Set up SPI for RGB 8x8 LED
   SPI.begin();
   SPI.setModule(2);
   SPI.setDataMode(SPI_MODE1);
   SPI.setClockDivider(SPI_CLOCK_DIV32);
   pinMode(chipSelectPin, OUTPUT);
   
   
  scrollString(h, 0);

  vClear();
  Transfer();
  
  //off = 0
  //red = 1
  //green = 2
  //yellow = 3
  //blue = 4
  //purple = 5
  //light blue = 6
  //white = 7
  
    pinMode(RED_LED, OUTPUT);       // Use red LED to display message reception
  digitalWrite(RED_LED, LOW);
  
  

  delay(1000);
  
  Radio.begin(ADDRESS_LOCAL, CHANNEL_1, POWER_MAX);

  rxPacket.from = 0;
  memset(rxPacket.message, 0, sizeof(rxPacket.message));

  randomSeed(analogRead(5));

  resetSnake();
}



//**********************************************************************************************************************************************************  
void loop() 
{


  moveSnake();
  outputDisplay();


  if (Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), 50) > 0)
  {
    digitalWrite(RED_LED, HIGH);
    Serial.print("FROM: ");
    Serial.print(rxPacket.from);
    Serial.println(" MSG: ");
    Serial.println(rxPacket.message[0]);
		digitalWrite(RED_LED, LOW);

    if(rxPacket.message[0] & 1){
      Serial.println("Up X");
      direction = 2;
    }

    if(rxPacket.message[0] & 2){
      Serial.println("Down X");
      direction = 0;
    }

    if(rxPacket.message[0] & 4){
      Serial.println("Up Y");
      direction = 1;
    }

    if(rxPacket.message[0] & 8){
      Serial.println("Down Y");
      direction = 3;
    }
    
    if(rxPacket.message[0] & 0x10){
      Serial.println("Select");
      button1value = 0;
    }

  }
  
  
}

//**********************************************************************************************************************************************************  
void resetSnake() 
{
  // Create empty snake
  for (int i=0; i < 64 * bi_maxInUseX * bi_maxInUseY; i++)
  {
    snake[i] = -1;
    newsnake[i] = -1;
  }

  clearMatrix();

  int startingpoint = random(64 * bi_maxInUseX * bi_maxInUseY);

  // Add starting dot
  matrix[startingpoint] = red;
  snakehead = startingpoint;
  snake[0] = snakehead;

  score = 0;

  generateApple();
  matrix[apple] = green;

  direction = 1;
}



//**********************************************************************************************************************************************************  
void clearMatrix() 
{
  // Clear matrix
  for (int i=0; i < 64 * bi_maxInUseX * bi_maxInUseY; i++)
  {
    matrix[i] = 0;
  }
  
  
}


//**********************************************************************************************************************************************************  
void outputDisplay() 
{


  for(int pixelXCount = 0; pixelXCount < (8 * bi_maxInUseY); pixelXCount++){
    for(int pixelYCount = 0; pixelYCount < (8 * bi_maxInUseX); pixelYCount++){
      if(matrix[(pixelXCount * 8 * bi_maxInUseX) + pixelYCount] == red){
        color = 1;
        drawPixel(pixelXCount + 1, pixelYCount + 1);
      }

      if(matrix[(pixelXCount * 8 * bi_maxInUseX) + pixelYCount] == green){
        color = 2;
        drawPixel(pixelXCount + 1, pixelYCount + 1);
      }

      if(matrix[(pixelXCount * 8 * bi_maxInUseX) + pixelYCount] == orange){
        color = 3;
        drawPixel(pixelXCount + 1, pixelYCount + 1);
      }

      if(matrix[(pixelXCount * 8 * bi_maxInUseX) + pixelYCount] == empty){
        color = 0;
        drawPixel(pixelXCount + 1, pixelYCount + 1);
      }

    }
    
  }
  
  Transfer();

}



//**********************************************************************************************************************************************************  
void moveSnake() 
{
  if (millis() - lastMillis >= moveSpeed) 
  {
    oldsnakehead = snakehead;
    switch(direction) 
    {
      case 0:
      // up
        if ((snakehead - numcol) < 0) 
        {
          snakehead += ((numrow - 1) * numcol);
        }
        else 
        {
          snakehead -= numcol;
        }
        break;
      case 1:
      // right
        if ((snakehead - (snakehead % numcol)) == (((snakehead+1) - (snakehead+1) % numcol))) 
        {
          snakehead += 1;
        }
        else 
        {
          snakehead = snakehead - (numcol - 1); // to start of row
        }
        break;
      case 2:
      // down
        if ((snakehead + numcol) > ((numrow * numcol - 1))) 
        {
          snakehead = snakehead % numcol;
        }
        else {
          snakehead += numcol;
        }
        break;
      case 3:
      // left
        if (snakehead == 0) 
        {
          // exception for topleft, pixel 0
          snakehead += (numcol - 1);
        }
        else if ((snakehead - (snakehead % numcol)) == (((snakehead-1) - (snakehead-1) % numcol))) 
        {
          snakehead -= 1;
        }
        else {
          snakehead += (numcol - 1); // end of row
        }
        break;
        default:

      break;
    }  // End switch

    // Check if we have the apple
    if (snakehead == apple) 
    {
    // Got it!
      generateApple();
      applecaught = 1;
    }

    for (int i = 1; i < 64 * bi_maxInUseX * bi_maxInUseY; i++)
    {
      if (snake[i] == snakehead) 
      {
      endGame();
      }
    }

    newsnake[0] = snakehead;
  
    for(int n = 0; n < 64 * bi_maxInUseX * bi_maxInUseY - 1; n++)
    {
      if (snake[n] == -1) 
      {
        snaketail = snake[n-1];
        if (applecaught == 0) {
          newsnake[n] = -1; // undo last, we are moving on
        }
        break;
      }
    
      newsnake[n+1] = snake[n];
    }
  
    for(int m = 0; m < 64 * bi_maxInUseX * bi_maxInUseY; m++)
    {
      snake[m] = newsnake[m];
    }

    if (applecaught == 1) 
    {
      generateApple();
      applecaught = 0;
      score++;
    }

    updateMatrix();

    lastMillis = millis();
  }
}



//**********************************************************************************************************************************************************  
void updateMatrix() 
{
  clearMatrix();

  for (int i = 1; i < 64 * bi_maxInUseX * bi_maxInUseY; i++)
  {
    if (snake[i] == -1) 
    {
      break;
    }

    matrix[snake[i]] = red;
  }

  matrix[snakehead] = orange;
  matrix[apple] = green;
}



//**********************************************************************************************************************************************************  
void generateApple() 
{
  apple = random(64 * bi_maxInUseX * bi_maxInUseY);

  for (int n = 1; n < 64 * bi_maxInUseX * bi_maxInUseY; n++)
  {
    if (snake[n] == apple) {
      generateApple();
    }
  }
}


//**********************************************************************************************************************************************************  
void endGame() 
{

  gameoverFlag=false;

  clearMatrix();
  outputDisplay();
//  delay(3000);
  
  sprintf((char *)points, "%d Points", score);
  scrollString(e, 0);
  scrollString(points, 0);
  
  drawString(c);
  Transfer();
  
  // Re-play if any button depressed
  while(true)
  {
    
    if (Radio.receiverOn((unsigned char*)&rxPacket, sizeof(rxPacket), 50) > 0)
    {
      digitalWrite(RED_LED, HIGH);
      Serial.print("FROM: ");
      Serial.print(rxPacket.from);
      Serial.println(" MSG: ");
      Serial.println(rxPacket.message[0]);
  		digitalWrite(RED_LED, LOW);
      
      if(rxPacket.message[0] & 0x10){
        Serial.println("Select");
        button1value = 0;
      }
  
    }
     if (button1value== LOW)
       break;
  }
  
  button1value == HIGH;
      
  resetSnake();
}




//**********************************************************************************************************************************************************  
// Clear Display
void clearDisplay(uint8_t whichColor)
{     
  vClear();
  Transfer();
}

Big Snake Firmware (full package)

C/C++
Full firmware package for Big Snake (includes miscellaneous header files needed to drive display). If you are recreating this project, download this!
No preview (download only).

Credits

Trey German

Trey German

10 projects • 33 followers
Freelance Engineer, hacker, sky junkie, programmer, designer. All projects are my own.

Comments