ELEC2645 (2015/16) / Mbed 2 deprecated SnakeProjectRev1

Dependencies:   Joystick N5110 SDFileSystem beep fsmMenu mbed

Fork of SnakeProjectRev1 by Meurig Phillips

Revision:
9:6d7074258c63
Parent:
8:9b767dd1e549
Child:
10:7820b46476ea
--- a/main.cpp	Thu Apr 28 19:24:03 2016 +0000
+++ b/main.cpp	Sun May 01 09:25:44 2016 +0000
@@ -10,6 +10,8 @@
  
 #include "mbed.h"
 #include "N5110.h"
+#include "beep.h"
+#include "SDFileSystem.h"
  
 // change this to alter tolerance of joystick direction
 #define DIRECTION_TOLERANCE 0.2 // previously 0.05
@@ -17,14 +19,20 @@
 //         VCC,    SCE,   RST,   D/C,   MOSI,  SCLK,   LED
 N5110 lcd (PTD3, PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
 // Can also power (VCC) directly from VOUT (3.3 V) -
-// Can give better performance due to current limitation from GPIO pin 
+// Can give better performance due to current limitation from GPIO pin
+
+// Connections to SD card holder on K64F (SPI interface)
+SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS
  
 // connections for joystick
 DigitalIn button(PTB18);
 AnalogIn xPot(PTB2);
 AnalogIn yPot(PTB3);
+DigitalOut greenLed(PTC2);
+DigitalOut redLed(PTA2);
 
-//PwmOut greenLed(PTC2);
+
+Beep buzzer(PTA1);
 
 // timer to regularly read the joystick
 Ticker pollJoystick;
@@ -83,6 +91,7 @@
 int snakeTailLength = 3;
 
 int score = 0;
+int top_score = 0;
 int fruitValue = 10;
 
 int i = 41; // snake head origin x
@@ -108,24 +117,32 @@
 void specialMap();
 void wrapAround();
 void scoreCalculation();
+void gameOver();
 void initSnakeTail();
+void snakeIntro();
 
+FILE *fp; // this is our file pointer
 
  
 int main()
 {
+
+    wait(1);
+    
     
     calibrateJoystick();  // get centred values of joystick
     pollJoystick.attach(&updateJoystick,0.5/10.0);  // read joystick 20 times per second
     
     srand(time(NULL));
-      
+    
+    greenLed = 1;
+    redLed = 0;
     lcd.init();
-    //lcd.drawRect(i,j,1,1,1); // default snake position
+    //snakeIntro();
     hardWall();
     generateFood();
     gamePlaying = true;
-    //initSnakeTail();
+    initSnakeTail();
  
     while(1) {
         
@@ -251,6 +268,17 @@
                 }
                 
                 lcd.clear();
+                greenLed = 1;
+                if (snakeTailLength > 4) {
+                for (int q=1; q<snakeTailLength; q++) {
+                    if (snakeTailX[q] == i && snakeTailY[q] == j) {
+                        gameOver();
+                        }
+                    }
+                }
+                
+                if (gamePlaying == true) {
+                
                 prev_i = snakeTailX[0];
                 prev_j = snakeTailY[0]; 
                 snakeTailX[0] = i; 
@@ -265,6 +293,8 @@
                     prev_j = prev2_j;
                  }
                 
+                 
+                
                 if (currentDirection == left) { // shift snake head coordinates according to current direction
                 i -= 2; } // move left
                 else if (currentDirection == right) {
@@ -277,9 +307,9 @@
                 
                 lcd.drawRect(i,j,1,1,1); // snake head
                 for (int b=0; b<snakeTailLength; b++) {
-                     lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1); }    
-          
-                
+                     lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1);
+                     }    
+             
                 lcd.refresh();
   
                 lcd.drawRect(randomX,randomY,1,1,1); // food
@@ -288,25 +318,19 @@
                 //wrapAround();
                 
                 if (i == randomX && j == randomY) { // if fruit is eaten
-                    //greenLedFlash();
+                    greenLed = 0;
+                    buzzer.beep(2000,0.2); 
                     scoreCalculation();
                     snakeTailLength++;
                     newFruitXY();
-                    generateFood();  
+                    generateFood();
+                    
                     }
                 wait(0.1);
-    
+    }
  }
  
-/*void greenLedFlash() {
-     
-     for(float p = 1.0f; p > 0.0f; p -= 0.1f) { // green led rapidly decreases from full brightness to off
-            greenLed = p;
-            wait(0.07);
-        }
-        greenLed = 0;
-     
-} */
+
 
 void hardWall() {
 
@@ -315,21 +339,76 @@
     if (i == 0 || i+1 == 0 ||
         i == 83 || i+1 == 83 || // if any of the 4 pixels within the snake head touch the border
         j == 0 || j+1 == 0 ||
-        j == 47 || j+1 == 47) {
-        
-        gamePlaying = false;
-        lcd.clear();
-        lcd.printString("Game Over",15,0); // width(6) * n(9) = 54, 84-54 = 30, 30/2 = 15
-        
-        char buffer[14];
-        int length = sprintf(buffer,"Score: %i",score); // display score of round
-        if (length <= 14) { // if string will fit on display
-            lcd.printString(buffer,0,1); }           // display on screen
-        
+        j == 47 || j+1 == 47)
+        {
+            gameOver(); 
         }
    
 }
 
+void gameOver() {
+    
+    redLed = 1;
+    if(score > top_score) {
+             ////////////////////// Simple writing example //////////////////////////
+    
+        // open file for writing ('w') - creates file if it doesn't exist and overwrites
+        // if it does. If you wish to add a score onto a list, then you can
+        // append instead 'a'. This will open the file if it exists and start
+        // writing at the end. It will create the file if it doesn't exist.
+        fp = fopen("/sd/topscore.txt", "w");
+        int top_score = score;
+    
+        if (fp == NULL) {  // if it can't open the file then print error message
+            serial.printf("Error! Unable to open file!\n");
+        } else {  // opened file so can write
+            serial.printf("Writing to file....");
+            fprintf(fp, "%d",top_score); // ensure data type matches
+            serial.printf("Done.\n");
+            fclose(fp);  // ensure you close the file after writing
+        }
+    }
+     gamePlaying = false;
+        lcd.clear();
+        buzzer.beep(294,0.5);
+        wait(0.5);
+        lcd.printString("Game Over",15,0); // width(6) * n(9) = 54, 84-54 = 30, 30/2 = 15
+        buzzer.beep(277,0.5);
+        wait(0.5);
+        
+        char buffer[14];
+        int length = sprintf(buffer,"Score:%i",score); // display score of round
+        if (length <= 14) { // if string will fit on display
+            lcd.printString(buffer,0,1); }           // display on screen
+        buzzer.beep(262,2);
+        
+         ////////////////////// Simple reading example //////////////////////////
+
+    // now open file for reading
+    fp = fopen("/sd/topscore.txt", "r");
+  //  int stored_top_score = -1;  // -1 to demonstrate it has changed after reading
+
+    if (fp == NULL) {  // if it can't open the file then print error message
+        serial.printf("Error! Unable to open file!\n");
+    } else {  // opened file so can write
+        fscanf(fp, "%d",&top_score); // ensure data type matches - note address operator (&)
+        serial.printf("Read %d from file.\n",top_score);
+        char buffer[14];
+        int length = sprintf(buffer,"HI Score:%i",top_score); // display score of round
+        if (length <= 14) { // if string will fit on display
+            lcd.printString(buffer,0,2); }           // display on screen
+        fclose(fp);  // ensure you close the file after reading
+    }
+        wait(0.5);
+        redLed = 0;
+        
+        lcd.printString("RB - Restart",0,4);
+        wait(0.5);
+        lcd.printString("LB - Menu",0,5);
+       
+}
+
+
 void specialMap() {
 
     for (int i=0; i<21; i++) { // top/bottom left x line
@@ -428,6 +507,37 @@
      
      lcd.drawRect(i,j,1,1,1); // snake head
                 for (int b=0; b<snakeTailLength; b++) {
-                     lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1); }  
+                     lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1);
+                     }
+     currentDirection = right;                   
     
-} 
\ No newline at end of file
+} 
+
+void snakeIntro() {
+  
+  for(int i=0; i<WIDTH; i++) {
+        for(int j=0; j<HEIGHT; j++) {
+            lcd.setPixel(i,j);
+        }
+    }
+    for (int q=0; q<WIDTH/2; q++) {
+    lcd.drawCircle(WIDTH/2,HEIGHT/2,q,2);
+    wait_ms(2);
+    }  // x,y,radius,white fill
+    
+    lcd.printString("Snake",27,0);
+    buzzer.beep(2000,0.5);   
+    wait(0.5);
+    lcd.printString("by",36,2);
+    buzzer.beep(1000,0.5);
+    wait(0.5);
+    lcd.printString("Meurig",24,3);
+    buzzer.beep(500,0.5);
+    wait(0.5);
+    lcd.printString("Phillips",18,4);
+    buzzer.beep(250,2);
+    wait(2);
+    
+    lcd.clear();  
+    
+ }   
\ No newline at end of file