Owen Cavender 201159294

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
el17oc
Date:
Sat May 30 06:12:09 2020 +0000
Parent:
1:897160a1a3ae
Commit message:
Final Submission. I have read and agreed with Statement of Academic Integrity

Changed in this revision

GameEngine.cpp Show annotated file Show diff for this revision Revisions of this file
GameEngine.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
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
--- a/GameEngine.cpp	Tue May 26 12:17:59 2020 +0000
+++ b/GameEngine.cpp	Sat May 30 06:12:09 2020 +0000
@@ -1,69 +1,73 @@
 #include "GameEngine.h"
-GameEngine::GameEngine()
+
+GameEngine::GameEngine()        //constructor
 {
 
 }
 
-GameEngine::~GameEngine()
+GameEngine::~GameEngine()      //deconstructor
 {
-
 }
 
-void GameEngine::init(int shx, int shy, int apx, int apy)
+
+void GameEngine::print_scores(N5110 &lcd, Snake &snake)
 {
-    _shx = shx;
-    _shy = shy;            //intial value in front of snake
-    _apx = apx;
-    _apy = apy;
+
+    int score = snake.get_score();                                  //gets score from snake class object
+
+    char buffer1[14];
+    sprintf(buffer1,"%2d",score);                                  //sprintf is used to print as the program is displaying a variable
+    lcd.printString(buffer1,0,48);
 }
 
 
 
-void GameEngine::set_Snakehead(Vector2D Snakehead)
-{
-    Snakehead.x = _shx;
-    Snakehead.y = _shy;
-}
 
-Vector2D GameEngine::get_Snakehead()
+void GameEngine::get_LEDs(Gamepad &pad, Snake &snake)       //controls LEDs based on snake position
 {
-    Vector2D Snakehead = {_shx, _shy};
-    return Snakehead;
-}
-
+    pad.leds_off();                                         //initialise leds
+    Vector2D Snakehead = snake.get_Snakehead();             //call values stored in _x0 and _y0 to identify the snakehead
+    int _x0 = Snakehead.x;
+    int _y0 = Snakehead.y;
+    //depending where the snakehead is on the screen, different LEDs will turn on indicating its postion
+    // top right led on
+    if (_x0 >= 42 && _y0 <= 16) {               //defines paramaters of the top right quadrant of the lcd rectangle and turns on and off the top right LED if the x and y values are in the top right quadrant
 
-Vector2D GameEngine::get_Applepos()
-{
-    Vector2D Applepos = {_apx, _apy};
-    return Applepos;
-}
+        pad.led(4, 1);                        //turn on top right led4
+        wait(0.2);                            //wait 0.2 seconds
+        pad.led(4, 0);                        //turn it off
+    }
+    // topleft led on
+    if (_x0 <= 42 && _y0 <= 16 ) {             //parameter for top left
 
-
-void GameEngine::set_Applepos(N5110 &lcd)
-{
-
-    int appleposx = rand()%84;             //is this generating new position or will it just stick to one random selection - need to make sure its in the loop
-    int appleposy = rand()%24;
-
+        pad.led(1, 1);                          //turns on top left led
+        wait(0.2);
+        pad.led(1, 0);
+    }
+    //bottom left                           //defines paramaters of the bottom left quadrant of the rectangle on the lcd display and turns on and off the bottom left LED
+    if (_x0 <=42 && _y0 >= 16 ) {
 
-    if(lcd.getPixel(appleposx, appleposy)) {      // this pixel is set } else {     // this pixel is clear }
-        appleposx = rand()%84;
-        appleposy = rand()%24;   //  making sure the apple doesnt spawn inside the snakes body or wall which would increase the score
+        pad.led(3,1);                       //turns on bottom left led
+        wait(0.2);
+        pad.led(3, 0);
+    }
+    //bottom right
+    if (_x0 >= 42 && _y0 >= 16) {          //there are some overlap on the symetrical x and y axis where conditions are true in both loops causing leds to coome on at the same time and alternately blink
+        // top right led on
+        pad.led(6, 1);
+        wait(0.2);
+        pad.led(6, 0);                      //turns of bottom right led
     } else {
-
-
-        _apx = appleposx;                 //i and j are fed into applepos.x/y -- those values are then fed into set_applepos which assigngs that value to _appleposx/y which then is fed into get_applepos where it is stored and returned
-        _apy = appleposy;      //alters value of private variable - this can then be accessed by get_Applepos
-
-        lcd.setPixel(_apx,_apy, true);
     }
 }
 
+void GameEngine::print_countdown(N5110 &lcd, Snake &snake)          //prints counter
+{
 
-//void GameEngine::clear_applepos(N5110 &lcd) {
-//   int length = _snake.get_Length();
-//   wait(length x fps);
-//   lcd.setPixel(Applepos.x, Applepos.y,0);
-// }
-//void Snakerender_apple()
-// lcd.setPixel(_apx,_apy, true);
+    int countdown = snake.get_countdown();                         //Accessing the value of the member variale _countdown
+
+    char buffer1[14];
+    sprintf(buffer1,"%2d",countdown);                              //printing value onto lcd in each loops. - counter is set to decrement by 1 each loop
+    lcd.printString(buffer1,0,4);  //
+// printf("  countdown= %d   ", countdown);
+}
--- a/GameEngine.h	Tue May 26 12:17:59 2020 +0000
+++ b/GameEngine.h	Sat May 30 06:12:09 2020 +0000
@@ -4,34 +4,42 @@
 #include "mbed.h"
 #include "N5110.h"
 #include "Gamepad.h"
-
-
+#include "snake.h"
 
 
-class GameEngine
-{
+/** GameEngine Class 
+* Owen Cavender, University of Leeds
+*/
 
+class GameEngine {
+    
 
 public:
-    GameEngine();
-    ~GameEngine();
-
-
-    void init(int shx, int shy, int apx, int apy);
-    void set_Snakehead(Vector2D Snakehead);
-    void set_Applepos(N5110 &lcd);
-    Vector2D get_Snakehead();
-    Vector2D get_Applepos();
-//void clear_Applepos();
+    GameEngine();   
+    /**comstructor
+    */       
+    ~GameEngine();   
+     /**decomstructor
+    */         
+    
+    
+    void print_scores(N5110 &lcd, Snake &snake);
+        /**comstructor
+    *  prints the score of the game while in game loop
+    */
+    void get_LEDs(Gamepad &pad, Snake &snake);
+    /**turn on and off leds depending on snake head position
+    */ 
+    void print_countdown(N5110 &lcd, Snake &snake);
+    /** prints countdown counter on each loop
+    */
 
 
 private:
-    int _shx;
-    int _shy;
-    int _apx;
-    int _apy;
+
+
 
 };
 
 
-#endif
+#endif
\ No newline at end of file
--- a/main.cpp	Tue May 26 12:17:59 2020 +0000
+++ b/main.cpp	Sat May 30 06:12:09 2020 +0000
@@ -1,127 +1,119 @@
 /*
 ELEC2645 Embedded Systems Project
-School of Electronic & Electrical Engineering
+School of Electronic & Electrical appleering
 University of Leeds
 2019/20
 
+/////////////SNAKE ///////////
 Name: Owen Cavender
 Username: el17oc
 Student ID Number: 201159294
 Date: 20/04/2020
-
-The game loop will be entered after the game is initialised. The first step is to process the
-user input (if any). The next step is to update the game engine depending on the input i.e.
-moving a character or checking for collisions. The final step is to update the display and render
-this on the LCD. There is usual
 */
 
-// includes
-#include "mbed.h"
+//////////////////////////////
+
+//includes
+#include "mbed.h"                        //addresses each header file of external classes being used in the programme
 #include "Gamepad.h"
 #include "N5110.h"
 #include "snake.h"
 #include "GameEngine.h"
 
+
 //objects
 Gamepad pad;
 Snake snake;
 N5110 lcd;
 GameEngine engine;
+
 //functions
-
 void welcome();
 void render();
 void init();
-void update_game_state();
+void update_snake();
+
 
-int main()  //FUNCTION 0
+//Serial pc(USBTX, USBRX);
+
+int main()
 {
 
-    int fps = 6;  // frames per second
+    init();                   //initialises game objects
+    welcome();                //displays welcome screen before entering game loop
+
+
+
+    while (1) {
+
 
-    init();                   // initialise and then display welcome screen...
-    welcome();
-    wait(1.0f/fps);  // and wait for one frame period
-    render();
+        update_snake();                                                     //reads input from gamepad and updates the position of the snake - this is the function influences how the other functions behave
+        snake.check_gameover(lcd);                                          //checking if any one of the three game over conditions is true
+        //   snake.gameover_true(lcd, pad);                                      //checking if an apple has been collected - increases the score and generates new apple position if apple has been collected
+        snake.apple_collected(lcd, pad);
+        snake.get_Apple_position(lcd);
+        engine.get_LEDs(pad, snake);
 
-    // game loop - read input, update the game state and render the display
-    while (1) {
-        snake.set_direction(pad);
-        update_game_state();
-        wait(1.0f/fps);                                 //need to make wait function - relate it to clock
+        engine.print_countdown(lcd, snake);                                //prints the value of the countdown counter - it will have incremented by 25 if an apple has been collected and would have decreased by 1 if not
+        snake.render(lcd, pad);                                            //prints the snake, the apple, the score and the border
+        //      snake.print_display_time(lcd);
+
+
+        wait(0.01);
     }
 
 }
 
-
-
 void init()
 {
+    lcd.init();             //initialises the lcd
+    pad.init();             //initialises the gamepad
+    snake.init();           //initialises snake class
 
-    snake.init();           //need to initialise snake class
-    pad.init();
-    lcd.init();
-    engine.init(48, 24, 48, 30);    // need to choose initial values A$AP   shx shy apx apy
+
 }
 
-void update_game_state()   //FUNCTION 2
+void update_snake()
 {
-
-    snake.set_direction(pad);
-    snake.move_and_draw_snake(lcd);
-    snake.gameover_true(lcd);
-    snake.check_if_scored(lcd, pad);
-
+    snake.get_direction(pad);                                          //sets the direction based on buttons pressed on the Gamepad
+    snake.render_clear_tail(lcd);                                      //clears the trailing pixel of the snake before updating position to avoid the snake growing with each move - the trailing pixel would be locked and fixed as 1 in its initial position without this
+    // =needs to be cleared before _x3, _y3 is updated
+    snake.move_snake();                                                //alters the coordinate of each snake bit in accordance with the Gamepad instruction
+    engine.get_LEDs(pad, snake);                                       //Turns on on LEDS based on where the snake is in the box
 }
 
 void welcome()
 {
 
-    lcd.printString("     SNAKE    ",0,1);
-    lcd.printString("  Press Start ",0,4);
-    lcd.refresh();
+
+    while ( pad.start_pressed() == false) {             //main menu - wont enter game loop until start is pressed
+        lcd.printString("     SNAKE    ",0,1);          //
+        lcd.printString("COLLECT APPLES",0,3);          //game task
+        lcd.printString("  Press Start ",0,5);          //instruction
+        lcd.setContrast( pad.read_pot1());              //adjust contrast
+
 
-    // wait flashing LEDs until start button is pressed
-    while ( pad.start_pressed() == false) {
-        lcd.setContrast( pad.read_pot1());
-        pad.leds_on();
+        pad.leds_off();
+        pad.led(1,1);
+        wait(0.2);
+        pad.led(1,0);                                   //turning on the LEDS in a sequence which reflects the snakes movement
+        pad.led(2,1);
+        wait (0.2);
+        pad.led(2,0);
+        pad.led(3,1);
+        wait(0.2);
+        pad.led(3,0);
         wait(0.1);
-        pad.leds_off();
-        wait(0.1);
+        pad.led(6,1);
+        wait (0.2);
+        pad.led(6,0);
+        pad.led(5,1);
+        wait (0.2);
+        pad.led(5,0);
+        pad.led(4,1);
+        wait(0.2);
+
+        lcd.refresh();                              //updates screen
     }
 
 }
-
-
-//void render(N5110 &lcd)
-//{
-void render()
-{
-    // clear screen, re-draw and refresh
-    lcd.clear();
-    lcd.drawRect(0, 0, 84, 42, FILL_TRANSPARENT);
-    lcd.refresh();
-}
-
-
-// for (int z=0; z<=_length; z++) {
-//     lcd.setPixel(snakebody[z].x, snakebody[z].y, 1);
-// }
-//use to draw wall - do i need to draw it everytime or can i do it as  constant
-//}
-
-
-
-
-
-
-//has an apple been collected? if so increase length by 1 increase score by 1 and makes coin collecting noise and spawn new apple
-//has snake touched itself or wall - if so end game - present score - make xxx sound fail --- apple needs to be different to the snakes body and different to wall
-//has button button been pressed - if so change direction accordingly
-//max length - when length = width x height - 1 - game complete
-//each pixel of length must follow the front pixel
-// 2 modes - time race - "get an apple before time runs out" - resets timer --- then classic snake
-
-
-
-//need to add audio, leds, (main menu end menu and entering and leaving the while(1) loop), time trial mode, .h files
\ No newline at end of file
--- a/snake.cpp	Tue May 26 12:17:59 2020 +0000
+++ b/snake.cpp	Sat May 30 06:12:09 2020 +0000
@@ -7,151 +7,298 @@
 
 Snake::~Snake()
 {
+}
+
+void Snake::init()//int x, int y)
+{
+    _x0 = 48;                           //initialises each part of the snake  //_x0 and _y0 is the snake's head coordinate whose position is followed by the other bits periodically
+    _x1 = 48;
+    _x2 = 48;
+    _x3 = 48;
+    _x4 = 48;
+    _x5 = 48;
+
+    _y0 = 20;                           //the snakes body is in a vertical positon
+    _y1 = 19;
+    _y2 = 18;
+    _y3 = 17;
+    _y4 = 16;
+    _y5 = 15;
+
+    _apx = 48;                        //initial apple position - directly in front of snake
+    _apy = 25;
+    _gameover = false;                //when _gameover = true, game cannot be played
+    _reset_apple = false;             //triggers the generation of a new apple position.
+    _score = 0;                       //initialises score to 0
+    _direction = down;                  //initial direction
+    _countdown = 18;                  //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty
+}
+
+Vector2D Snake::get_Snakehead()
+{
+    Vector2D Snakehead;             //defines Snakehead as a Vector
+    Snakehead.x = _x0;              //returns _x0, _y0 values
+    Snakehead.y = _y0;
+
+    return Snakehead;               //Snakehead position is called and used in GameEngine::get_LEDs by calling this class
 
 }
 
 
-void Snake::init ()
+void Snake::apple_collected(N5110 &lcd, Gamepad &pad)   //checks to see whether an apple has been collected
 {
 
-    //WIDTH =84 HEIGHT = 42 //snakebody[0] is initialised may have to initilaise the other 2 og snake parts
-    _length = 1;
-    _gameover = false;
-    _score = 0;
-    _direction = up;
+    if((_x0 == _apx) && (_y0 == _apy)) {        // directly comparing position of the apple and the Snakehead by using an and statement to see if the x and y components are equal
+        // if they are the same: the score increases, a new apple position is generated, the countdown timer is reset,  LEDS and Speaker are triggered
+        _score++;                               //increases score
+        _reset_apple = true;                   //causes new apple position to be generated - _reset _apple is compared to a bool true - when an apple is collected a new apple position is generated
+        _countdown = _countdown + 25;          //38 is added to the current countdown timer - this larger _countdown is, the further the snake can travel to collect apples.
+        pad.tone(1500.0,0.5);                  //if the counter is reset to just 38, there will be some distances the snake cannot as it is further than 38 pixels away - unless the player collects accumulates their available moves
+        pad.led(2, 1);                         //toggles middle left led on
+        pad.led(4, 1);                          //toggles middle right led on
+        wait(0.1);
+        pad.led(2, 0);
+        pad.led(4, 0);
 
+
+
+    } else {
+        _countdown = _countdown - 1;           //for each change in position, counter decreases by 1 - the counter represents how many moves you have to collect an apple
+
+    }
+}
+
+int Snake::get_countdown()
+{
+    //allows _countdown value to be called from other classes
+    return _countdown;
 }
 
 
+void Snake::check_gameover(N5110 &lcd)
+{
+    if (_x0 == 15 ||_x0 == 69 || _y0 == 32 || _y0 == 0) {   // the first condition is, if the snakehead coordinate touches the edge of the rectangle, it is gameover
+        //the second condition for, game over = true, is if the snake head cooroinate is equal to one of the snake body bits coordinate
+        _gameover = true;                                   // the third conditios is game is over if the counter = 0, indicating you've ran out of moves.
+    }
+    if ((_x0 == _x1 && _y0 == _y1) || (_x0 == _x2 && _y0 == _x2) || (_x0 == _x2 && _y0 == _y2) || (_x0 == _x3 && _y0 == _y3) || (_x0 == _x4 && _y0 == _y4)|| (_x0 == _x5 && _y0 == _y5)|| (_x0 == _x6 && _y0 == _y6)|| (_x0 == _x7 && _y0 == _y7)) {
+        _gameover = true;
+    }
+    if(_countdown == 0) {
+        _gameover = true;
 
-int Snake::set_direction(Gamepad &pad)     //int type as Directions is an enum
+    }
+}
+
+void Snake::render(N5110 &lcd, Gamepad &pad)                     //final function in the main function's while loop as the screen updates based on all any changes which occur in the functions
 {
+    lcd.clear();                                    //clears the lcd before assigning what is to be printed
 
-    Directions _direction;
+    // plot the apple
+    lcd.setPixel(_apx, _apy,1);                     //plot apple position -whether it is a new position or the same position
+
+    //plot the border
+    lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT);  //plots border of snake map
+
+    //plot the snake
+    lcd.setPixel(_x0, _y0,1);                       //plots snake body's new position changed by move_snake() function
+    lcd.setPixel(_x1, _y1,1);
+    lcd.setPixel(_x2, _y2,1);
+    lcd.setPixel(_x3, _y3,1);
+    lcd.setPixel(_x4, _y4,1);
+    lcd.setPixel(_x5, _y5,1);
+    lcd.setPixel(_x6, _y6,1);
+    lcd.setPixel(_x7, _y7,1);                        //new position of the end bit of the snake is plotted here
+    // _x0, _y0  old positional values are cleared previously before this function in an earlier one as otherwise the program would lose reference of that pixel when the position updates and we wouldnt be able to clear it
 
 
-    if (pad.A_pressed()) {
+    char buffer1[14];
+    sprintf(buffer1,"   %2d   %2d",_score, _countdown);
+    lcd.printString(buffer1,0,5);
+
+    if (_gameover == true) {                                    //As _gameover is a member variable, if the condition is the previous function is met, the true value will be stored in _gameover and can be accessed in this function
+        lcd.clear();                                            //
 
-        _direction = right;
+        pad.led(1,1);
+        pad.led(4,1);
+        lcd.printString( "  Game Over  ", 0, 1 );               //prints game over message
+        lcd.printString( " ~~~~~~~<:>-<", 0, 3 );               // prints symbolic snake
+        char buffer1[14];
+        sprintf(buffer1,"  Score: %2d", _score);                          //prints your score - cannot simply use N5110::printString as we need to output a value and the Number of inputs wouldnt match the function declaration
+        lcd.printString(buffer1,0,4);                                   ///print score
 
 
     }
 
-    if (pad.B_pressed()) {
+//   char buffer2[14];
+    // sprintf(buffer2,"%2d",_score);
+    // lcd.printString(buffer2,0,3);
+
+    lcd.refresh();                                       //updates the lcd display according to the code in this function
+}
+
+
+
+
 
-        _direction = left;     //check these are orrecrt
+void Snake::get_direction(Gamepad &pad)  //gets the direction based on the input of the gamepad
+{
+    // int x;                            // int x was used as a variable to test whether the button were generating the correct output
+    Directions direction = _direction;   //"direction" stores the previous value of _direction to stop the snake going in the opposite direction to the way its travelling
 
+    if(direction != left) {             //if current direction is left, the not statement is false blocking access to the next command from the 'A' button preventing _direction being set to right
+        if (pad.A_pressed()) {
+
+            _direction = right;         //the snake direction is stored in _direction so on the next loop direction = right
+            //       x=1;
+        }
     }
+    if(direction != right) {
+        if (pad.Y_pressed()) {
 
-    if (pad.X_pressed()) {
-
-        _direction = up;
+            _direction = left;
+            //      x=2;
+        }
 
     }
-
-    if (pad.Y_pressed()) {
+    if(direction != up) {
+        if (pad.B_pressed()) {
+            //       x=3;
+            _direction = down;
+        }
+    }
+    if(direction != down) {
+        if (pad.X_pressed()) {
 
-
-        _direction = down;
+            _direction = up;
+            //       x=4;
+        }
+    } else {
+        _direction = _direction;            // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set
 
     }
-
-    else {
-
-        _direction = _direction;
-    }
-    return _direction;
+    //  printf("direction %d ", x);        //printf statements used in CoolTerm to check whether the input commands where working correctly
 }
 
 
-void Snake::move_and_draw_snake(N5110 &lcd)
+
+void Snake::move_snake()           //assigns the new values of the snake position
 {
-    Vector2D Snakehead = _engine.get_Snakehead();           //initialises Snakehead value
-    Vector2D *snakebody = new Vector2D [_length];
-
-    snakebody[0].x = Snakehead.x;
-    snakebody[0].y = Snakehead.y;
+    if (_direction == down) {       //shifting the snake position bit by bit, with respect to _x0 and _y0;
+        _x7 = _x6;                //coordinate _x[i], _y[i] = _x[i-1], _y[i-1]
+        _y7 = _y6;
+        _x6 = _x5;
+        _y6 = _y5;
+        _x5 = _x4;
+        _y5 = _y4;
+        _x4 = _x3;
+        _y4 = _y3;
+        _x3 = _x2;
+        _y3 = _y2;
+        _x2 = _x1;
+        _y2 = _y1;
+        _x1 = _x0;
+        _y1 = _y0;               //_x1 ,_y1 and  must be assingned to _x0,_y0 before its own position updates otherwise bit 0 and bit 1 would be plotted as 1 pixel
 
-    while(1) {
-        if (_direction == up) {
-            Snakehead.y++;                              // alters Snakehead initial value
-        }
-        if (_direction == down) {             //this part is needed to keep the snake running continually
-            Snakehead.y--;
-        }
-        if (_direction == left) {
-            Snakehead.x--;
-        }
-        if (_direction == right) {
-            Snakehead.x++;                         //updates the head position before rendering so when it draws i=1 the 0 position will be new
-        }
+        _x0 = _x0;
+        _y0 = _y0 + 1;          //changes the position one bit at a time so the snake can only move horizontally or vertically
+    }
+    if (_direction == up) {
+        _x7 = _x6;
+        _y7 = _y6;
+        _x6 = _x5;
+        _y6 = _y5;
+        _x5 = _x4;
+        _y5 = _y4;
+        _x4 = _x3;
+        _y4 = _y3;
+        _x3 = _x2;
+        _y3 = _y2;
+        _x2 = _x1;
+        _y2 = _y1;
+        _x1 = _x0;
+        _y1 = _y0;
 
-        for(int i=1; i<=_length; i++) {                     //0 being head of snake  so snakepos[1]=snakepos[0] which is the head - moving up one place
-            snakebody[i].x = snakebody[i-1].x;
-            snakebody[i].y = snakebody[i-1].y;
-            lcd.setPixel(snakebody[i].x, snakebody[i].y, 1);
-            if(snakebody[i].x == Snakehead.x && snakebody[i].y == Snakehead.y) {  //is snakebody[0] being plotted
-                _gameover = true;
+        _x0 = _x0;             // x remains constant
+        _y0 = _y0 - 1;          //y decerases by 1 to move up as the y axis decreases from top to bottom
 
-            }
-        }
     }
+    if (_direction == left) {
+        _x7 = _x6;
+        _y7 = _y6;
+        _x6 = _x5;
+        _y6 = _y5;
+        _x5 = _x4;
+        _y5 = _y4;
+        _x4 = _x3;
+        _y4 = _y3;
+        _x3 = _x2;
+        _y3 = _y2;
+        _x2 = _x1;
+        _y2 = _y1;
+        _x1 = _x0;
+        _y1 = _y0;
+
+        _x0 = _x0 - 1;       //changes x=x-1
+        _y0 = _y0;           //y remains the same to move left
 
 
-}
-
-
-void Snake::gameover_true(N5110 &lcd)      //taking action if crash has occured
-{
-    if (_gameover == true) {
-
-        lcd.clear();
-        lcd.refresh();
-        lcd.printString( "  Game Over L ", 0, 2 );
-        lcd.printString ("score: _score ",15, 15);    //Need to add button to return to main screen / restart
 
     }
 
-    else {
+    if (_direction == right) {
+        _x7 = _x6;
+        _y7 = _y6;
+        _x6 = _x5;
+        _y6 = _y5;
+        _x5 = _x4;
+        _y5 = _y4;
+        _x4 = _x3;
+        _y4 = _y3;
+        _x3 = _x2;
+        _y3 = _y2;
+        _x2 = _x1;
+        _y2 = _y1;
+        _x1 = _x0;
+        _y1 = _y0;
+
+        _x0 = _x0 + 1;
+        _y0 = _y0;
 
 
     }
 }
 
 
-
-void Snake::check_if_scored(N5110 &lcd, Gamepad &pad)
+void Snake::render_clear_tail(N5110 &lcd)
 {
-    Vector2D Snakehead = _engine.get_Snakehead();
-    Vector2D Applepos = _engine.get_Applepos();                           //need to code clear apple and make sure apple isnt spawning every time
-
-    if(Snakehead.x == Applepos.x && Snakehead.y == Applepos.y) {
-
 
-        _score++;
-        _length = _length++;
-        _engine.set_Applepos(lcd);    //randomises new values for _apx,_apy and draws on lcd -- the position is not needed until we compare it to Snakehead
-        pad.tone(1500.0,0.5);          //need to clear apple
-        pad.leds_on();
-        wait(0.5);
-        pad.leds_off();
-
-    }
+    lcd.setPixel(_x7, _y7, false);                       //sets the end pixel to 0. it must be set to 0 before its position updates otherwise the snakebody will grow continually from _x7, _y7 coordinate
 }
 
-void Snake::check_wall_collisions()     // Vector2D *&snakebody hopefully this points to values stored in snakebody then can compare to snakehead
+bool Snake::get_gameover()                               //methods to access member variables of the class
 {
-    Vector2D Snakehead = _engine.get_Snakehead();
-
-
-    if (Snakehead.x == 0 || Snakehead.x == 84 || Snakehead.y == 0 || Snakehead.y == 42) {   //how do i access snakehead.headx
-
-        _gameover = true;
-    } else {
-        _gameover = false;
-
-    }
+    return _gameover;
+}
+int Snake::get_score()
+{
+    return _score;
 }
 
 
+
+
+
+void Snake::get_Apple_position(N5110 &lcd)
+{
+    if(_reset_apple == true) {      // _reset_apple is a triggered when an apple is collected and causes a new Apple position to be randomly generated
+        _reset_apple = false;         // returned to false immediately so another position can be generated function can be triggered again in the next loop
+        lcd.setPixel(_apx, _apy,0);     //sets the exisiting apple position to 0 to remove it from lcd.
+        _apx = rand()%52+16;         //54 = width of the rectangle on the lcd. - the x value of the apple has a range of 52 so it cannot spawn in either side of the wall                                 
+        _apy = rand()%28+2;        // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69
+    }
+
+
+}
+
     
--- a/snake.h	Tue May 26 12:17:59 2020 +0000
+++ b/snake.h	Sat May 30 06:12:09 2020 +0000
@@ -5,8 +5,10 @@
 #include "mbed.h"
 #include "N5110.h"
 #include "Gamepad.h"
-#include "GameEngine.h"
 
+/** Snake Class
+* Owen Cavender, University of Leeds
+*/
 
 class Snake
 {
@@ -14,37 +16,100 @@
 
 public:
     Snake();
+    /** constructor
+    */
     ~Snake();
+    /** deconstructor
+    */
 
-    enum Directions {
+    enum Directions {           /**enum of directions*/
         up,
         down,
         left,
         right,
-        null
+
     };
 
     void init();
-    int set_direction(Gamepad &pad);
-    //Directions get_direction();
-    void move_and_draw_snake(N5110 &lcd);
-    void gameover_true(N5110 &lcd);
-    void check_if_scored(N5110 &lcd, Gamepad &pad);
-    void check_wall_collisions();
-    //  void render(N5110 &lcd);
-    void clear_applepos(N5110 &lcd);
+    /** initialises 'Snake' class
+    */
+    void get_direction(Gamepad &pad);
+    /** reads input from gamepad
+    *updates direction
+    */
+    void render_clear_tail(N5110 &lcd);
+    /** clears pixel on the end of snake
+    *before everything else on the screen is updated and rendered
+    */
+    void move_snake();
+    /**alters the values assigned to the snake's body
+    *based on the _direction set in get_direction
+    */
+    void apple_collected(N5110 &lcd, Gamepad &pad);
+    /** check to see if the apple x,y = snakehead x,y values
+    *increases score, triggers a true which causes generation of apple, updates counter
+    *Plays a tone and toggles LEDs
+    */
+    void check_gameover(N5110 &lcd);
+    /**checks if game is over based on 3 conditions
+    */
+    void get_Apple_position(N5110 &lcd);
+    /**sets the apple position
+    *an update of position is triggered by bool _reset_apple
+    */
+    void render(N5110 &lcd, Gamepad &pad);
+    /**draws the snake, border, and apple during the game
+    * if it is game over, it displays the score and a gameo over message
+    */
 
 
 
+    Vector2D get_Snakehead();
+    /**returns _x0, and _y0 values
+    */
+
+    int get_countdown();
+    /**reurns counter value
+    */
+    int get_score();
+    /**returns score;
+    */
 
 private:
 
-    bool _gameover;
+
+    bool get_gameover();
+    /** returns _gameover
+    *private as it is only used in Snake class
+    */
+
+    /**Snake private variables*/
     Directions _direction;
-    int _length;
+    int _countdown;
+    bool _gameover;
     int _score;
-    GameEngine _engine;
+    int _reset_apple;
 
+    int _x0;            /**snake position variable*/
+    int _y0;
+    int _x1;
+    int _y1;
+    int _x2;
+    int _y2;
+    int _x3;
+    int _y3;
+    int _x4;
+    int _y4;
+    int _x5;
+    int _y5;
+    int _x6;
+    int _y6;
+    int _x7;
+    int _y7;
+
+
+    int _apx;       /**apple position variable*/
+    int _apy;
 
 };