Snake game for a 5x5 LED matrix

Dependencies:   MCP23S17 mbed

Files at this revision

API Documentation at this revision

Comitter:
dhamilton31
Date:
Thu Oct 17 04:32:58 2013 +0000
Parent:
0:dc906408980e
Child:
2:9c075a0a6d4e
Commit message:
Changes to just about everything

Changed in this revision

MCP23S17.lib Show annotated file Show diff for this revision Revisions of this file
bodyPiece.h Show annotated file Show diff for this revision Revisions of this file
draw.cpp Show diff for this revision Revisions of this file
draw.h Show diff for this revision Revisions of this file
ledCube.cpp Show annotated file Show diff for this revision Revisions of this file
ledCube.h Show annotated file Show diff for this revision Revisions of this file
ledValues.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
snake.cpp Show annotated file Show diff for this revision Revisions of this file
snake.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP23S17.lib	Thu Oct 17 04:32:58 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/romilly/code/MCP23S17/#068b1e8909bb
--- a/bodyPiece.h	Wed Oct 09 16:23:20 2013 +0000
+++ b/bodyPiece.h	Thu Oct 17 04:32:58 2013 +0000
@@ -2,9 +2,10 @@
 #define __BODYPIECE_H__   //   #define this so the compiler knows it has been included
 
 
-class bodyPiece{
-    public:
-        char currRow, currCol;
-};
+typedef
+struct{
+        char currRow;
+        char currCol;
+}bodyPiece;
 
 #endif // __BODYPIECE_H__
\ No newline at end of file
--- a/draw.h	Wed Oct 09 16:23:20 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-#include "mbed.h"
--- a/ledCube.cpp	Wed Oct 09 16:23:20 2013 +0000
+++ b/ledCube.cpp	Thu Oct 17 04:32:58 2013 +0000
@@ -1,8 +1,15 @@
+#include "mbed.h"
 #include "ledCube.h"
 #include "ledValues.h"
+#include "MCP23S17.h"
 
 // Set up the ledArray output pins
-ledCube::ledCube(){
+ledCube::ledCube()
+{
+    spi = new SPI(p11, p12, p13);
+    char Opcode = 0x40; // Used to start the spi communication with the DIP
+    chip = new MCP23S17(*spi, p20, Opcode);
+
     ledArray[0][0] = new DigitalOut(P000);
     ledArray[0][1] = new DigitalOut(P001);
     ledArray[0][2] = new DigitalOut(P002);
@@ -11,14 +18,14 @@
     ledArray[1][0] = new DigitalOut(P010);
     ledArray[1][1] = new DigitalOut(P011);
     ledArray[1][2] = new DigitalOut(P012);
-    ledArray[1][3] = new DigitalOut(P013);
-    ledArray[1][4] = new DigitalOut(P014);
-    ledArray[2][0] = new DigitalOut(P020);
-    ledArray[2][1] = new DigitalOut(P021);
-    ledArray[2][2] = new DigitalOut(P022);
-    ledArray[2][3] = new DigitalOut(P023);
-    ledArray[2][4] = new DigitalOut(P024);
-    ledArray[3][0] = new DigitalOut(P030);
+    ledArray[1][3] = NULL;
+    ledArray[1][4] = NULL;
+    ledArray[2][0] = NULL;
+    ledArray[2][1] = NULL;
+    ledArray[2][2] = NULL;
+    ledArray[2][3] = NULL;
+    ledArray[2][4] = NULL;
+    ledArray[3][0] = NULL;
     ledArray[3][1] = new DigitalOut(P031);
     ledArray[3][2] = new DigitalOut(P032);
     ledArray[3][3] = new DigitalOut(P033);
@@ -28,24 +35,93 @@
     ledArray[4][2] = new DigitalOut(P042);
     ledArray[4][3] = new DigitalOut(P043);
     ledArray[4][4] = new DigitalOut(P044);
-    
+    //  Set all 8 Port A bits to output direction
+    (*chip).direction(PORT_A, 0x00);
+    //  Set all 8 Port B bits to output direction
+    (*chip).direction(PORT_B, 0x00);
     lastLedLit = NULL;
+    (*chip).write(PORT_A, spiCurrentlyLit);
+}
+// Light the LED at the specified row, column, layer coordinate
+void ledCube::turnOnLed(char row, char column, char layer)
+{
+    if(ledArray[row][column] != NULL){
+        *ledArray[row][column] = 1;
+    }
+    else{
+        if( row == 1 && column == 3){
+            spiCurrentlyLit |= 0x01;   
+        }
+        else if(row == 1 && column == 4){
+            spiCurrentlyLit |= 0x02;
+        }
+        else if(row == 2 && column == 0){
+            spiCurrentlyLit |= 0x04;
+        }
+        else if(row == 2 && column == 1){
+            spiCurrentlyLit |= 0x08;
+        }
+        else if(row == 2 && column == 2){
+            spiCurrentlyLit |= 0x10;
+        }
+        else if(row == 2 && column == 3){
+            spiCurrentlyLit |= 0x20;
+        }
+        else if(row == 2 && column == 4){
+            spiCurrentlyLit |= 0x40;
+        }
+        else if(row == 3 && column == 0){
+            spiCurrentlyLit |= 0x80;
+        }
+        (*chip).write(PORT_A, spiCurrentlyLit);
+    }
 }
 
-// Light the LED at the specified row, column, layer coordinate
-void ledCube::lightLed(char row, char column, char layer){
-    //if(lastLedLit != NULL){
-    //    *lastLedLit = 0;
-    //}
-    *ledArray[row][column] = 1;
-    //lastLedLit = ledArray[row][column];
+void ledCube::turnOffLed(char row, char column, char layer)
+{
+    if(ledArray[row][column] != NULL){
+        *ledArray[row][column] = 0;
+    }
+    else{
+        if( row == 1 && column == 3){
+            spiCurrentlyLit &= ~(0x01);   
+        }
+        else if(row == 1 && column == 4){
+            spiCurrentlyLit &= ~(0x02);
+        }
+        else if(row == 2 && column == 0){
+            spiCurrentlyLit &= ~(0x04);
+        }
+        else if(row == 2 && column == 1){
+            spiCurrentlyLit &= ~(0x08);
+        }
+        else if(row == 2 && column == 2){
+            spiCurrentlyLit &= ~(0x10);
+        }
+        else if(row == 2 && column == 3){
+            spiCurrentlyLit &= ~(0x20);
+        }
+        else if(row == 2 && column == 4){
+            spiCurrentlyLit &= ~(0x40);
+        }
+        else if(row == 3 && column == 0){
+            spiCurrentlyLit &= ~(0x80);
+        }
+        (*chip).write(PORT_A, spiCurrentlyLit);
+    }
 }
 
-void ledCube::turnOffLed(char row, char column, char layer){
-    *ledArray[row][column] = 0;
+void ledCube::blink()
+{
+    for(char i = 0; i < 5; i++) {
+        for(char j = 0; j < 5; j++) {
+            turnOnLed(i,j,0);
+        }
+    }
+    wait(.3);
+    for(char i = 0; i < 5; i++) {
+        for(char j = 0; j < 5; j++) {
+            turnOffLed(i,j,0);
+        }
+    }
 }
-
-void ledCube::drawHorLine(char startRow, char startCol, char endRow, char endCol){
-
-}
-
--- a/ledCube.h	Wed Oct 09 16:23:20 2013 +0000
+++ b/ledCube.h	Thu Oct 17 04:32:58 2013 +0000
@@ -1,14 +1,24 @@
 #include "mbed.h"
+#include "MCP23S17.h"
 
-class ledCube{
+#ifndef LEDCUBE_H
+#define LEDCUBE_H
+
+class ledCube
+{
 public:
     DigitalOut *ledArray[5][5];
+    SPI *spi;
+    MCP23S17 *chip;
     int numRows, numCols;
     ledCube();
-    void lightLed(char row, char column, char layer);
-    void drawHorLine(char startRow, char startCol, char endRow, char endCol);
+    void turnOnLed(char row, char column, char layer);
     void turnOffLed(char row, char column, char layer);
-    
+    void blink();
+
 private:
     DigitalOut *lastLedLit;
-};
\ No newline at end of file
+    int spiCurrentlyLit;
+};
+
+#endif //LEDCUBE_H
\ No newline at end of file
--- a/ledValues.h	Wed Oct 09 16:23:20 2013 +0000
+++ b/ledValues.h	Thu Oct 17 04:32:58 2013 +0000
@@ -1,19 +1,22 @@
+#include "mbed.h"
+#include "MCP23S17.h"
+
 #define P000 PinName(p5)
 #define P001 PinName(p6)
 #define P002 PinName(p7)
 #define P003 PinName(p8)
 #define P004 PinName(p9)
 #define P010 PinName(p10)
-#define P011 PinName(p11)
-#define P012 PinName(p12)
-#define P013 PinName(p13)
-#define P014 PinName(p14)
-#define P020 PinName(p15)
-#define P021 PinName(p16)
-#define P022 PinName(p17)
-#define P023 PinName(p18)
-#define P024 PinName(p19)
-#define P030 PinName(p20)
+#define P011 PinName(p14)
+#define P012 PinName(p15)
+#define P013 NULL
+#define P014 NULL
+#define P020 NULL
+#define P021 NULL
+#define P022 NULL
+#define P023 NULL
+#define P024 NULL
+#define P030 NULL
 #define P031 PinName(p21)
 #define P032 PinName(p22)
 #define P033 PinName(p23)
@@ -22,4 +25,4 @@
 #define P041 PinName(p26)
 #define P042 PinName(p27)
 #define P043 PinName(p28)
-#define P044 PinName(p29)
\ No newline at end of file
+#define P044 PinName(p29)
--- a/main.cpp	Wed Oct 09 16:23:20 2013 +0000
+++ b/main.cpp	Thu Oct 17 04:32:58 2013 +0000
@@ -1,13 +1,72 @@
 #include "mbed.h"
 #include "ledCube.h"
 #include "snake.h"
+#include "main.h"
+
+snake mySnake(snakeStartRow,snakeStartCol);
+food myFood(foodStartRow, foodStartCol);
+ledCube cube;
+AnalogIn joyVer(p19);
+AnalogIn joyHor(p18);
+DigitalIn select(p17);
 
 int main()
 {
-    ledCube cube;
-    snake mySnake(0, 0);
-    
+    printf("Start\n");
+    int snakeUpdateCounter = 0;
+    cube.turnOnLed(snakeStartRow, snakeStartCol, 0);
+    updateFoodLed();
+    printf("Setup Complete\n");
+
     while(1) {
-        
+        // Update snake position if we are greater than the set movement speed
+        if(snakeUpdateCounter++ >= mySnake.movementSpeed) {
+            snakeUpdateCounter = 0;
+            if(mySnake.moveSnake(cube)) {
+                cube.blink();
+            }
+            if(checkForSnakeEating()) {
+                myFood.moveFood(rand() % 5, rand() % 5);
+                updateFoodLed();
+            }
+        }
+        updateDirectionInput();
+        wait(.1);
     }
+    
 }
+
+bool checkForSnakeEating()
+{
+    return mySnake.isEating(myFood.currRow, myFood.currCol);
+}
+
+void updateFoodLed()
+{
+    cube.turnOnLed(myFood.currRow, myFood.currCol, 0);
+}
+
+void updateDirectionInput(){
+   float verValue, horValue;
+    int pushed;
+    select.mode(PullUp);
+        verValue = joyVer;
+        horValue = joyHor;
+        pushed = select;
+        if(horValue < .4){
+            mySnake.movementDirection = Left;
+            printf("Left\n");
+        }
+        else if(horValue > .6){
+            mySnake.movementDirection = Right;
+            printf("Right\n");
+        }
+        if(verValue < .4){
+            mySnake.movementDirection = Down;
+            printf("Down\n");
+        }
+        else if(verValue > .6){
+            mySnake.movementDirection = Up;
+            printf("Up\n");
+        }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Thu Oct 17 04:32:58 2013 +0000
@@ -0,0 +1,14 @@
+// Function prototypes
+
+void updateSnakeLeds();
+void updateFoodLed();
+bool checkForSnakeEating();
+void updateDirectionInput();
+
+// constants
+
+#define snakeStartCol 0
+#define snakeStartRow 0
+
+#define foodStartCol 2
+#define foodStartRow 0
--- a/snake.cpp	Wed Oct 09 16:23:20 2013 +0000
+++ b/snake.cpp	Thu Oct 17 04:32:58 2013 +0000
@@ -1,15 +1,21 @@
 #include "snake.h"
 #include "bodyPiece.h"
 #include <list>
+#include "ledCube.h"
 
+// Constructor
 snake::snake(char startRow, char startCol){
     bodyPiece head = bodyPiece();
     head.currRow = startRow;
     head.currCol = startCol;
     snakeBody.push_back(head);
+    bodySize = 1;
+    movementDirection = START_DIRECTION;
+    movementSpeed = START_SPEED;
 }
 
-void snake::move(char newHeadRow, char newHeadCol){
+// Movement method for the snake, will update LEDs and snake's body
+char snake::move(char newHeadRow, char newHeadCol, ledCube cube){
     
     // Variables to hold the bodyPiece's X and Y positions on the grid
     char prevRow, prevCol, tempRow, tempCol;
@@ -22,10 +28,14 @@
     // Update the head to the new Row and Col
     (*it).currRow = newHeadRow;
     (*it).currCol = newHeadCol;
+    cube.turnOffLed(prevRow, prevCol, 0);
+    cube.turnOnLed(newHeadRow, newHeadCol, 0);
+    char bodyCount = 1;
     // Check to see if we are at the tail with this while loop
-    while(it != snakeBody.end()){
+    while(bodyCount < bodySize){
         // Move to the next bodyPiece
         it++;
+        bodyCount++;
         // Store the previous piece's location in the current piece
         tempRow = (*it).currRow;
         (*it).currRow = prevRow;
@@ -33,19 +43,87 @@
         (*it).currCol = prevCol;
         prevRow = tempRow;
         prevCol = tempCol;
+        // Check to see if the head has collided with this bodyPiece
+        if(snakeBody.front().currRow == prevRow && snakeBody.front().currCol == prevCol){
+            return 1;
+        }
+        if(prevRow < 5 && prevCol < 5){
+            cube.turnOffLed(prevRow, prevCol, 0);
+        }
+
+        cube.turnOnLed((*it).currRow, (*it).currCol, 0);
+    }
+    return 0;
+}
+
+// Checks the current movement direction and decided where to move the snake head next
+// Will return 1 if out of bounds or if the head has hit a bodyPiece, 0 if still in the boundaries
+char snake::moveSnake(ledCube cube){
+    bodyPiece head = snakeBody.front();
+    char ret = 0;
+    switch(movementDirection){
+    case Down:
+        if(head.currCol-1 < 0){
+            ret =  1;
+        }
+        else{
+            ret = move(head.currRow, head.currCol-1, cube);
+        }
+    break;
+    case Up:
+        if(head.currCol+1 > NUM_COLS){
+            ret = 1;
+        }
+        else{
+            ret = move(head.currRow, head.currCol+1, cube);
+        }
+    break;
+    case Left:
+        if(head.currRow-1 < 0){
+            ret = 1;
+        }
+        else{
+            ret = move(head.currRow-1, head.currCol, cube);
+        }
+    break;
+    case Right:
+        if(head.currRow+1 > NUM_ROWS){
+            ret = 1;
+        }
+        else{
+            ret = move(head.currRow+1, head.currCol, cube);
+        }
+    }
+    return ret;
+}
+
+// Adds a new piece on to snake's tail
+void snake::addPiece(){
+    bodyPiece b;
+    snakeBody.push_back(b);
+    bodySize++;
+    printf("piece added + bodySize: %d\n", bodySize);
+}
+
+bool snake::isEating(char foodRow, char foodCol){
+    if(snakeBody.front().currRow == foodRow && snakeBody.front().currCol == foodCol){
+        addPiece();
+        return 1;
+    }
+    else{
+        return 0;
     }
 }
 
-void snake::addPiece(){
-    snakeBody.push_back(bodyPiece());
-}
-
+// Constructor for the food class
 food::food(char row, char col){
     currRow = row;
     currCol = col;
 }
 
+// Moves food to a new row and column
 void food::moveFood(char row, char col){
     currRow = row;
     currCol = col;
-}
\ No newline at end of file
+}
+
--- a/snake.h	Wed Oct 09 16:23:20 2013 +0000
+++ b/snake.h	Thu Oct 17 04:32:58 2013 +0000
@@ -1,7 +1,17 @@
 #include "mbed.h"
 #include "bodyPiece.h"
 #include <list>
+#include "ledCube.h"
 
+#ifndef SNAKE_H
+#define SNAKE_H
+
+// Macros
+#define START_DIRECTION Up
+#define START_SPEED 10
+// Zero indexed number of columns and rows
+#define NUM_COLS 4
+#define NUM_ROWS 4
 
 typedef enum {
     Up,Down,Left,Right
@@ -10,15 +20,24 @@
 class snake
 {
 public:
+
+    // constructor
     snake(char startRow, char startCol);
-    void move(char newHeadRow, char newHeadCol);
-    int movementSpeed;
-    Direction movementDirection;
-    void addPiece();
+    
+    // public variables
+    int movementSpeed; // Speed at which the snake is moving
+    Direction movementDirection; // Direction in which the snake is moving
+    int bodySize; // Size of the snake's body
+    std::list<bodyPiece> snakeBody;
+    
+    // Function Prototypes
+    char moveSnake(ledCube cube); // Moves the snake by one in the direction of movementDirection
+                      // Will return 1 if out of bounds or if the head has hit a bodyPiece, 0 if still in the boundaries
+    void addPiece(); // Adds a bodyPiece to the tail
+    bool isEating(char foodRow, char foodCol);
 
 private:
-    std::list<bodyPiece> snakeBody;
-    int bodySize;
+    char move(char newHeadRow, char newHeadCol, ledCube cube);
 };
 
 class food
@@ -28,3 +47,5 @@
     food(char row, char col);
     void moveFood(char row, char col);
 };
+
+#endif // SNAKE_H
\ No newline at end of file