Snake game for a 5x5 LED matrix
Revision 1:5fcb94bb03db, committed 2013-10-17
- 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
--- /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