Completed Snake Program

Dependencies:   N5110 PinDetect PowerControl mbed

Fork of DocTest by Craig Evans

Revision:
6:1de103a19681
Parent:
5:1bfc306466db
Child:
7:2942e97924f0
diff -r 1bfc306466db -r 1de103a19681 main.cpp
--- a/main.cpp	Wed Apr 15 16:34:05 2015 +0000
+++ b/main.cpp	Mon Apr 27 20:27:23 2015 +0000
@@ -1,131 +1,6 @@
-#include "mbed.h"
-#include "N5110.h"
-#include <vector> 
-#include <cstddef>      // std::size_t
-#include <valarray>  
-#include <iostream>
-
-//#include "PinDetect.h"
-
-// change this to alter tolerance of joystick direction
-#define DIRECTION_TOLERANCE 0.1
-//        VCC,SCE,RST,D/C,MOSI,SCLK,LED
-N5110 lcd(p7,p8,p9,p10,p11,p13,p21);
-BusOut myleds(LED1,LED2,LED3,LED4);
-InterruptIn startButton(p16);
-InterruptIn resetButton(p17);
-
-// connections for joystick
-DigitalIn button(p18);
-AnalogIn xPot(p19);
-AnalogIn yPot(p20);
-Serial serial(USBTX,USBRX);
-int snake[84][47];
-bool gamePlaying =0;
-
-vector<int> snakeX (5);
-vector<int> snakeY (5,27);
-int food[2];//element 0 = x position element 1= y position 
-
-void randomiseFood(){
-    
-    srand(time(NULL));
-    
-    int randomX = rand() %84; // generate random number between 0 and 83 
-    int randomY = rand() %47;// generate random number betwwen 0 and 46 
-    
-    if (lcd.getPixel(randomX,randomY)==1){ // if that pixel is already filled
-        
-        randomX = rand() %83 ;  // generate new random numbers
-        randomY = rand() %47 ;// 
-        
-        
-        }
-        lcd.setPixel(randomX,randomY) ;// set the food
-        food[0]=randomX; // update food position
-        food[1]=randomY;// update food position 
-        lcd.refresh();
-    
-    }
-
- // snakeX.insert(snakeX.begin() , 60);
-        // snakeY.insert(snakeY.begin() , 60 );
-       // snakeX.push_front(30);
-       // snakeY.push_front(30);
-       
-       
-void checkForFood(){
-    
-    if (snakeX.back()==food[0] && snakeY.back()==food[1]){ // if  x and y of head match food
-       
-      snakeX.push_back(food[0]+1);
-     snakeY.push_back(food[1]);
-       
-       
-      // snakeX.insert (snakeX.begin() + 0, );
-       //snakeY.insert (snakeY.begin() + 0, );
-        
-        randomiseFood();
-        
-        }
-    
-    
-    }
-
-//snakeX[4]=21;
-
-//int snakeX[4]={21,22,23,24}; //5 pixels start position 21 22 23 24 25
-//int snakeY[4]={27,27,27,27}; //5 pixels y position     27 27 27 27 27 
-
-
-void startingSnake(){
-    
-    for (int i=0; i<5; i++){
-        lcd.setPixel(snakeX[i],snakeY[i]);
-       // lcd.drawRect(snakeX[i],snakeY[i],1,1,1);
-    }
-    }
-    
-
-
-// timer to regularly read the joystick
-Ticker pollJoystick;
-
-Ticker startGame;
-
-
-void Boundary(){
-
-    
-    for(int x = 0; x< 84; x++) {
-        lcd.setPixel(x,0);
-    }
-    for(int x = 0; x< 84; x++) {
-        lcd.setPixel(x,47);
-    }
-    for(int y = 0; y< 48; y++) {
-        lcd.setPixel(0,y);
-    }
-    for(int y = 0; y< 48; y++) {
-        lcd.setPixel(83,y);
-    }
-   
-    lcd.refresh();
-    
-
-}
-enum Difficulty {
-    EASY,
-    MEDIUM,
-    HARD,
-};
-
-int gameSpeed;//change depending on difficulty selected
-
-Difficulty currentDifficulty=EASY;
+#include "main.h"
 
 // create enumerated type (0,1,2,3 etc. for direction)
-// could be extended for diagonals etc.
 enum DirectionName {
     UP,
     DOWN,
@@ -135,6 +10,16 @@
     UNKNOWN
 };
 
+// create enumerated type (0,1,2 for difficulty)
+enum Difficulty {
+    EASY,
+    MEDIUM,
+    HARD,
+};
+
+Difficulty currentDifficulty=EASY;
+
+
 // struct for Joystick
 typedef struct JoyStick Joystick;
 struct JoyStick {
@@ -148,7 +33,6 @@
 // create struct variable
 Joystick joystick;
 
-
 DirectionName previousDirection =RIGHT;
 
 // read default positions of the joystick to calibrate later readings
@@ -172,118 +56,22 @@
     if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
         joystick.direction = CENTRE;
     } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
-        joystick.direction = UP;
+        joystick.direction = DOWN;
     } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
-        joystick.direction = DOWN;
+        joystick.direction = UP;
     } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
-        joystick.direction = LEFT; // remember switched this with right
+        joystick.direction = RIGHT; // remember switched this with right
     } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
-        joystick.direction = RIGHT;
+        joystick.direction = LEFT;
     } else {
         joystick.direction = UNKNOWN;
     }
 }
 
+//GAME FUNCTIONS
 
-void updateSnakeArray(){
-        
-        if (joystick.direction==LEFT && previousDirection==RIGHT){
-            joystick.direction=RIGHT;
-            }
-            
-        if (joystick.direction==RIGHT && previousDirection==LEFT){
-            joystick.direction=LEFT;
-            }
-            
-            if (joystick.direction==UP && previousDirection==DOWN){
-            joystick.direction=DOWN;
-            }
-            
-            if (joystick.direction==DOWN && previousDirection==UP){
-            joystick.direction=UP;
-            }
-            
-             if (joystick.direction==UNKNOWN || joystick.direction==CENTRE){
-                 joystick.direction= previousDirection;
-            }
-        
-    
-       lcd.clearPixel(snakeX[0],snakeY[0]);//delete tail 
-    //  lcd.drawRect(snakeX[0],snakeY[0],1,1,2);
-        
-             for (int i =0; i<snakeX.size(); i++){   // shift elements 
-                snakeX[i]=snakeX[i + 1]; // apart from head 
-                snakeY[i]=snakeY[i+ 1];
-                } 
-                
-                 switch(joystick.direction){
-                      
-                       case UP:snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2];
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2]-1;
-                    break;
-                    
-                      case DOWN:
-                    snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2];
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2]+1;
-                    break;
-                    
-                      case LEFT:
-                    snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]-1;
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
-                    break;
-                    
-                      case RIGHT:
-                    snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+1;
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
-                    break;
-                    
-                    case CENTRE:
-                    snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+1;
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
-                    break;
-                     case UNKNOWN:
-                    snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+1;
-                    snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
-                    break;
-                        
-                    
-                    }
-                   
-                 /* snakeX[0]=snakeX[1];
-                snakeX[1]=snakeX[2];
-                snakeX[2]=snakeX[3];
-                snakeX[3]=snakeX[4];
-                snakeY[0]=snakeY[1];
-                snakeY[1]=snakeY[2];
-                snakeY[2]=snakeY[3];
-                snakeY[3]=snakeY[4];
-                
-                
-               */
-                  
-}
+//For start MENU
 
-void checkForCollision(){
-    
-    if (snakeX.back()==0 || snakeX.back()==83 || snakeY.back()==0 ||snakeY.back()==47){
-        startGame.detach();
-        lcd.clear();
-        
-        
-        
-        }
-    
-    
-    }
-void startButtonPressed(){
-    gamePlaying=1;
-    myleds=15;
-    }
-    
-    void resetButtonPressed(){
-    gamePlaying=0;
-    myleds=0;
-    }
 void displaySplash()
 {
     // these are default settings so not strictly needed
@@ -324,7 +112,7 @@
     lcd.drawCircle(10,35,2,0);
     lcd.drawCircle(10,43,2,0);
 
-    gameSpeed= 1.0;
+    gameSpeed= 0.5;
 }
 void mediumSelected() // display when medium is selected
 {
@@ -339,7 +127,7 @@
     lcd.drawCircle(10,27,2,0);
     lcd.drawCircle(10,35,2,1);
     lcd.drawCircle(10,43,2,0);
-    gameSpeed=1.0/4;
+    gameSpeed=0.5;
 }
 
 void hardSelected() // display when hard is selected
@@ -355,19 +143,11 @@
     lcd.drawCircle(10,27,2,0);
     lcd.drawCircle(10,35,2,0);
     lcd.drawCircle(10,43,2,1);
-    gameSpeed=1.0/8;
-}
-void drawSnake() {  
- 
-    for(int x =10; x<15; x++) {
-        lcd.setPixel(x,25);
-       // lcd.drawRect(x,25,2,2,1);
-        snake[x][25]=1;
-    }
+    gameSpeed=1.0/32;
 }
 
-
-void checkSelectedDifficulty() {
+void checkSelectedDifficulty()
+{
 
     switch(currentDifficulty) {
         case EASY:
@@ -420,87 +200,401 @@
     wait(0.2);
 }
 
-int updateGameFlag=0;
-void updateGameISR(){
-    updateGameFlag=1;
+
+
+
+//for gamePLAY
+
+
+
+void startingSnake()
+{
+    snakeX[0]=20;
+            snakeX[1]=22;
+            snakeX[2]=24;
+           snakeX[3]=26;
+            snakeX[4]=28;
+
+   for (int i=0; i<5; i++) {
+       // lcd.setPixel(snakeX[i],snakeY[i]);
+         lcd.drawRect(snakeX[i],snakeY[i],1,1,1);
     }
     
-    void printVectorContent(){
-        
-        
-        for( int i=0; i<snakeX.size(); i++)
-    serial.printf( "%d \n \r"  ,snakeX[i]);
+     
+     wait(5);
+}
+
+
+void randomiseFood()
+{
+
+    srand(time(NULL));
+
+    int randomX = rand() % (83-1)+1; // generate random number between 1 and 82  // spaces within boundar
+
+    int randomY = rand() %(46-9)+9;// generate random number betwwen 9 and 46
+
+    // int r = rand() % (21 - 10) + 10 // 10 -21 inclusive
+
+    while(lcd.getPixel(randomX,randomY)==1) { // if that pixel is already filled
+
+        int randomX = rand() % (83-1)+1; // generate random number between 1 and 82  // spaces within boundar
+
+        int randomY = rand() %(46-9)+9;
+
+
+    }
+   // lcd.setPixel(randomX,randomY) ;// set the food
+   lcd.drawRect(randomX,randomY,1,1,1);
+    food[0]=randomX; // update food position
+    food[1]=randomY;// update food position
+    lcd.refresh();
+
+}
+
+void Boundary()
+{
+
+
+    for(int x = 0; x< 84; x++) {
+        lcd.setPixel(x,8);
+    }
+    for(int x = 0; x< 84; x++) {
+        lcd.setPixel(x,47);
+    }
+    for(int y = 8; y< 48; y++) {
+        lcd.setPixel(0,y);
+    }
+    for(int y = 8; y< 48; y++) {
+        lcd.setPixel(83,y);
+    }
+
+    lcd.refresh();
+
+}
+
+
+
+
+
+void updateSnakeArray()
+{
+
+    if (joystick.direction==LEFT && previousDirection==RIGHT) {
+        joystick.direction=RIGHT;
+    }
+
+    if (joystick.direction==RIGHT && previousDirection==LEFT) {
+        joystick.direction=LEFT;
+    }
+
+    if (joystick.direction==UP && previousDirection==DOWN) {
+        joystick.direction=DOWN;
+    }
+
+    if (joystick.direction==DOWN && previousDirection==UP) {
+        joystick.direction=UP;
+    }
+
+    if (joystick.direction==UNKNOWN || joystick.direction==CENTRE) {
+        joystick.direction= previousDirection;
+    }
+
+
+   // lcd.clearPixel(snakeX[0],snakeY[0]);//delete tail
+      lcd.drawRect(snakeX[0],snakeY[0],1,1,2);
+
+    for (int i =0; i<snakeX.size(); i++) {  // shift elements
+        snakeX[i]=snakeX[i + 1]; // apart from head
+        snakeY[i]=snakeY[i+ 1];
+    }
+
+    switch(joystick.direction) {
+
+        case UP:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2];
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2]-2;
+            break;
+
+        case DOWN:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2];
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2]+2;
+            break;
+
+        case LEFT:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]-2;
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
+            break;
+
+        case RIGHT:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+2;
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
+            break;
+
+        case CENTRE:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+2;
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
+            break;
+        case UNKNOWN:
+            snakeX[snakeX.size()-1]=snakeX[snakeX.size()-2]+2;
+            snakeY[snakeY.size()-1]=snakeY[snakeY.size()-2];
+            break;
+
+    }
+}
+
+void gameOver()
+{
+    startGame.detach();
+    lcd.clearPixel(snakeX.back(),snakeY.back());
+    wait(0.2);
+    lcd.refresh();
+    lcd.setPixel(snakeX.back(),snakeY.back());
+    wait(0.3);
+    lcd.refresh();
+    lcd.clearPixel(snakeX.back(),snakeY.back());
+    wait(0.2);
+    lcd.refresh();
+    lcd.setPixel(snakeX.back(),snakeY.back());
+    wait(0.2);
+    lcd.refresh();
+    lcd.clear();
+    lcd.inverseMode();
+
+    
+    lcd.printString("Your Score" ,12,0);
+     lcd.printString("=" ,34,1);
+     
+     int updatedScore=score;
+     int length = sprintf(buffer,"%2d",updatedScore);
+
+        if (length <= 14)  // if string will fit on display
+            lcd.printString(buffer,40,1);
+            
+             lcd.printString("Press Reset" ,2,3);
+             lcd.printString("Button To" ,10,4);
+             lcd.printString("Play Again" ,20,5);
+           // 
+            lcd.refresh();
+    gamePlaying=0;
     
     
+
+}
+
+void checkForCollision()
+{
+
+    if (snakeX.back()<=0 || snakeX.back()>=82 || snakeY.back()<=8 ||snakeY.back()>=47) {
+        
+        gameOver();
+    }
+}
+
+
+
+void checkForFood()
+{
+
+    if (snakeX.back()+1==food[0] && snakeY.back()==food[1]) {   // if  x and y of head match food
+
+
+        switch(joystick.direction) {
+
+            case RIGHT:
+                snakeX.push_back(food[0]+2);
+                snakeY.push_back(food[1]);
+                break;
+            case LEFT:
+
+                snakeX.push_back(food[0]-2);
+                snakeY.push_back(food[1]);
+                break;
+
+
+            case UP:
+                snakeX.push_back(food[0]);
+                snakeY.push_back(food[1]-2);
+                break;
+
+            case DOWN:
+                snakeX.push_back(food[0]);
+                snakeY.push_back(food[1]+2);
+                break;
+        }
+
+        int updatedScore;
+        // snakeX.insert (snakeX.begin() + 0, );
+        //snakeY.insert (snakeY.begin() + 0, );
+
+        updatedScore= score+5;
+        score=updatedScore;
+        int length = sprintf(buffer,"%2d",updatedScore);
+
+        if (length <= 14)  // if string will fit on display
+            lcd.printString(buffer,0,0);
+        // lcd.refresh();
+
+        randomiseFood();
+
     }
 
-int main()
+
+}
+
+void startButtonPressed()
+{
+    gamePlaying=1;
+   // myleds=15;
+}
+
+
+
+
+void updateGameISR()
+{
+    updateGameFlag=1;
+}
+
+void printVectorContent()
+{
+
+    for( int i=0; i<snakeX.size(); i++)
+        serial.printf( "%d \n \r"  ,snakeX[i]);
+
+}
+
+
+
+void pauseButtonPressed()
+{
+
+    if (gamePaused==0) {
+
+        startGame.detach();
+
+        gamePaused=1;
+    }
+
+    else {
+
+
+        startGame.attach(&updateGameISR,gameSpeed);
+
+        gamePaused=0;
+    }
+
+
+
+}
+
+void checkForCollisionWithSelf(int i)
+{
+
+        if(snakeX.back()==snakeX[i] && snakeY.back()==snakeY[i]) {
+
+
+            gameOver();
+
+        
+    }
+
+
+}
+void startUpMenu()
 {
 
     // first need to initialise display
-    lcd.init();
     
     displaySplash();
     wait(4);
     easySelected();
     joystick.direction=UNKNOWN;
     calibrateJoystick();  // get centred values of joystick
-    pollJoystick.attach(&updateJoystick,1.0/5.0); 
+    pollJoystick.attach(&updateJoystick,1.0/5.0);
     startGame.attach(&updateGameISR,gameSpeed); // read joystick 10 times per second
-    startButton.mode(PullUp);
+    
+
+
+}
+
+void resetButtonPressed()
+{
+  // myleds=0;
+   easySelected();
+   pollJoystick.attach(&updateJoystick,1.0/5.0);
+}
+
+
+int main()
+{
+    lcd.init();
+    startUpMenu();
+    resetButton.mode(PullDown);
+    startButton.mode(PullDown);
+    button.mode(PullDown);
     startButton.rise(&startButtonPressed);
     resetButton.rise(&resetButtonPressed);
-  //  startGame.attach(&startButtonPressed,10);
-    
+    button.rise(&pauseButtonPressed);
+serial.printf("starting");
     while(1) {
-        if (gamePlaying==0){
-        checkSelectedDifficulty();
+        if (gamePlaying==0) {
+            checkSelectedDifficulty();
+            serial.printf("check difficulty loop");
+        }
+
+        else if (gamePlaying==1) {
+            lcd.clear();
+            lcd.normalMode();      // normal colour mode
+            Boundary();
+            
+            pollJoystick.detach();
+            startGame.attach(&updateGameISR,gameSpeed);
+            startingSnake();
+            randomiseFood();
+            if (length <= 14)  // if string will fit on display
+                lcd.printString(buffer,0,0);
+            // lcd.drawRect(0,0,83,7,0);
+            lcd.refresh();
+            serial.printf("gameplaying=1 game init");
+
+            //init game start time back food
+            while (1) {
+                serial.printf("enter game loop");
+                if(updateGameFlag==1) {
+                    //updateJoystick();
+                    updateGameFlag=0;
+                    updateJoystick();
+                    // lcd.clearPixel(snakeX[0],snakeY[0]);
+                    // updateSnakeDirection();
+                    updateSnakeArray();
+                    for (int i=0; i<snakeX.size(); i++) {
+                        lcd.drawRect(snakeX[i],snakeY[i],1,1,1);
+                       // lcd.setPixel(snakeX[i],snakeY[i]);
+                        
+
+                    }
+                    lcd.refresh();
+                    previousDirection=joystick.direction;
+                    
+                    checkForFood();
+                    checkForCollision();
+                    
+                    for (int i=0; i<snakeX.size()-1; i++) {
+                        checkForCollisionWithSelf(i);
+                    }
+
+
+                    //serial.printf("%d",snakeX.size());
+                    // printVectorContent();
+
+                }
+
+            }
+
+        }
     }
-    else if (gamePlaying==1){
-     lcd.clear();
-     lcd.normalMode();      // normal colour mode
-     Boundary();
-     snakeX[0]=21;
-    snakeX[1]=22;
-    snakeX[2]=23;
-    snakeX[3]=24;
-    snakeX[4]=25;
- pollJoystick.detach();
-    startGame.attach(&updateGameISR,0.1);
-     startingSnake();
-     randomiseFood();
-         lcd.refresh();
-         
-     //init game start time back food
-     while (1){
-       if(updateGameFlag==1){
-         //updateJoystick();
-         updateGameFlag=0;
-         updateJoystick();
-         // lcd.clearPixel(snakeX[0],snakeY[0]);
-          // updateSnakeDirection();
-          updateSnakeArray();
-          for (int i=0;i<snakeX.size();i++){
-             // lcd.drawRect(snakeX[i],snakeY[i],1,1,1);
-             lcd.setPixel(snakeX[i],snakeY[i]);
-              }
-              lcd.refresh(); 
-              previousDirection=joystick.direction;  
-              
-              checkForCollision(); 
-              checkForFood();
-              
-              
-              //serial.printf("%d",snakeX.size()); 
-             // printVectorContent();
-               
-    }
-                  
-         }
- 
-         }
-     }
-     
-    
+
+
 
 }
\ No newline at end of file