Owen Cavender 201159294

Dependencies:   mbed Gamepad2

Revision:
14:7fb3c93343b6
Parent:
13:b37dde18bfdc
Child:
16:9500059ad5d8
--- a/snake.cpp	Fri May 29 16:27:29 2020 +0000
+++ b/snake.cpp	Sat May 30 02:31:43 2020 +0000
@@ -11,9 +11,9 @@
 
 
 
-void Snake::init()
+void Snake::init()//int x, int y)
 {
-    _x0 = 48;
+    _x0 = 48;                           //initialises the snake and apple position
     _x1 = 48;
     _x2 = 48;
     _x3 = 48;
@@ -26,14 +26,15 @@
     _y3 = 17;
     _y4 = 16;
     _y5 = 15;
-    
-    _apx = 48;
+
+    _apx = 48;                         //initial apple position - directly in front of snake
     _apy = 25;
-    _gameover = false;
+    _gameover = false;                //when _gameover = true, game cannot be played
     _reset_apple = false;
     _score = 0;
     _direction = up;
-    _countdown = 30;
+    _countdown = 12;                  //initial number of moves is lower than the reset value in order to keep the number of moves low to increase difficulty
+
     //  Vector2D *_snakebody = new Vector2D [_length];
 }
 
@@ -55,89 +56,95 @@
 {
 
     //need to code clear apple and make sure apple isnt spawning every time
-    if((_x0 == _apx) && (_y0 == _apy)) {
+    if((_x0 == _apx) && (_y0 == _apy)) {       // directly comparing position of the apple and the Snakehead - if they are the same: the score increases, countdown timer is reset, a new apple position is generated, LEDS and Speaker are triggered
 
         //   _countdown = _reset_value;
         _score++;
-        _reset_apple = true;
-        _countdown = 30;          //causes new apple position to be generated
-        pad.tone(1500.0,0.5);
-        pad.led(2, 1);
+        _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 + 38;          //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);                         //
         pad.led(4, 1);
-
-        //pad.led(2, 0);
-        //pad.led(4, 0);
+        wait(0.1);
+        pad.led(2, 0);
+        pad.led(4, 0);
 
 
 
     } else {
-        _countdown = _countdown - 1;
-        printf("  countdown = %d      score   %d  ", _countdown ,_score);
+        _countdown = _countdown - 1;           //for each change in position, counter decreases by 1
 
     }
 }
 
 int Snake::get_countdown()
 {
+    //allows _countdown value to be called from other classes
     return _countdown;
 }
 
 
-void Snake::check_gameover(N5110 &lcd)   //code where it hits itself
+void Snake::check_gameover(N5110 &lcd)
 {
-        if (_x0 == 0 ||_x0 == 84 || _y0 == 32 || _y0 == 0) {   //how do i access snakehead.headx
-
-            _gameover = true;
-        }
-        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)) {
-            _gameover = true;
-        }
-        if(_countdown == 0) {
-            _gameover = true;                                                  //|| (_x0 == _x4 && _y0 == _y4))
-
-        }
+    if (_x0 == 15 ||_x0 == 69 || _y0 == 32 || _y0 == 0) {   // the snakehead coordinate is on any edge of the rectangle, it is gameover
+        //the second condition is the game is over 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.
     }
-
-void Snake::gameover_true(N5110 &lcd)
-{
+    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;
 
-    while (_gameover == true) {
-
-        lcd.printString( "  Game Over L ", 0, 2 );    
-    char buffer1[14];
-    sprintf(buffer1,"%2d",_score);
-    lcd.printString(buffer1,0 ,48);  // font is 8 wide, so leave 4 pixel gape from middle assuming two digits
-
-
-        if (_score <= 7) {
-            lcd.printString("    Loser     ", 0,10);
-        }
-        if (7< _score <= 25) {
-            lcd.printString("    Good Job!     ", 0,10);
-        } else {
-            lcd.printString("    SNAKE PRO     ", 0,10);
-            lcd.printString(" ~.~.~.~.<8>~  ", 0, 5);
-
-        }
-            lcd.refresh();
     }
 }
 
-void Snake::render(N5110 &lcd)
+void Snake::gameover_true(N5110 &lcd, Gamepad &pad)
 {
 
+    while (_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();
+        pad.tone(500,1);
+        lcd.printString( "  Game Over  ", 0, 1 );
+        lcd.printString( " ~~~~~~~<:>-<", 0, 3 );
+        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 No. of inputs wouldnt match up to the function declaration
+        lcd.printString(buffer1,0,4);  // font is 8 wide, so leave 4 pixel gape from middle assuming two digits    ///print score
+
+        lcd.refresh();
+    }
+}
+
+void Snake::render(N5110 &lcd)                     //final function in the main function's while loop as the screen updatesbased on all any changes which occur in the functions
+{
+    lcd.clear();
 
     //apple
-    lcd.setPixel(_apx, _apy,1);                        //apple
+    lcd.setPixel(_apx, _apy,1);                     //plot apple position -whether it is a new position or the same position
 
-    lcd.drawRect(0, 0, 84, 40, FILL_TRANSPARENT);    //game
-    lcd.setPixel(_x0, _y0,1);                        //snake
+    lcd.drawRect(15, 0, 54, 32, FILL_TRANSPARENT);  //plots border of snake map
+
+    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 - its old position cleared
+    //NOTES CHANGLE LED VALUES SO IT IS TOP RIHGT OF THE BOX NOT TOP HALF OF THE SCREEN    //CHANGE APPLE POSITION COORDINATES SO ITS IN BOX // GET SCORE IN THE SAME PLACE WHEN IT PRINTS AT END
+
+    char buffer1[14];
+    sprintf(buffer1,"   %2d   %2d",_score, _countdown);    //prints score and counter on the same line
+    lcd.printString(buffer1,0,5);  // font is 8 wide, so leave 4 pixel gape from middle assuming two digits
+
+
+//   char buffer2[14];
+    // sprintf(buffer2,"%2d",_score);
+    // lcd.printString(buffer2,0,3);  // font is 8 wide, so leave 4 pixel gape from middle assuming two digits
+
+    lcd.refresh();                                       //applies plotting commands togeher
+}
 
 
 
@@ -145,27 +152,27 @@
 
 void Snake::get_direction(Gamepad &pad)
 {
-   // int x;
-    Directions direction = _direction;
-    if(direction != left) {
+    // int x;
+    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;
-     //       x=1;
+            //       x=1;
         }
     }
     if(direction != right) {
         if (pad.Y_pressed()) {
 
             _direction = left;
-      //      x=2;
+            //      x=2;
         }
 
-        //check these are orrecrt
     }
     if(direction != down) {
         if (pad.B_pressed()) {
-     //       x=3;
+            //       x=3;
             _direction = up;
         }
     }
@@ -173,35 +180,47 @@
         if (pad.X_pressed()) {
 
             _direction = down;
-     //       x=4;
+            //       x=4;
         }
     } else {
-        _direction = _direction;
+        _direction = _direction;            // setting the direction equal to itself if no button is pressed means the snake will move automatically once direction is set
 
     }
-    //  printf("direction %d ", x);
+    //  printf("direction %d ", x);        //printf statements used in CoolTerm to check whether the input commands where working correctly
 }
 
 
 
 void Snake::move_snake()
 {
-    if (_direction == up) {
-        _x5 = _x4; 
-        _x4 = _x3;      
+    if (_direction == up) {       //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;
+        _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
 
         _x0 = _x0;
-        _y0 = _y0 + 1;
+        _y0 = _y0 + 1;          //changes the position one bit at a time so the snake can only move horizontally or vertically
     }
     if (_direction == down) {
+        _x7 = _x6;
+        _y7 = _y6;
+        _x6 = _x5;
+        _y6 = _y5;
         _x5 = _x4;
+        _y5 = _y4;
         _x4 = _x3;
+        _y4 = _y3;
         _x3 = _x2;
         _y3 = _y2;
         _x2 = _x1;
@@ -214,8 +233,14 @@
 
     }
     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;
@@ -223,7 +248,7 @@
         _x1 = _x0;
         _y1 = _y0;
 
-        _x0 = _x0 - 1;
+        _x0 = _x0 - 1;       //changes x=x-1 , y remains the same to move left
         _y0 = _y0;
 
 
@@ -231,8 +256,14 @@
     }
 
     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;
@@ -244,18 +275,17 @@
         _y0 = _y0;
 
 
-    } else
-        _direction = _direction;
+    }
 }
 
 
 void Snake::render_clear_tail(N5110 &lcd)
 {
 
-    lcd.setPixel(_x5, _y5, false);
+    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
 }
 
-bool Snake::get_gameover()
+bool Snake::get_gameover()                               //methods to access member variables of the class
 {
     return _gameover;
 }
@@ -263,70 +293,21 @@
 {
     return _score;
 }
-int Snake::get_oldscore()
-{
-    return _oldscore;
-}
 
 
-int Snake::get_reset_value()
-{
-    return _reset_value;
-}
+
+
 
 void Snake::get_Apple_position(N5110 &lcd)
 {
-    if(_reset_apple == true)
-     {
-    lcd.setPixel(_apx, _apy,0);
-        _apx = rand()%82+1;
-        _apy = rand()%30+1;
+    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
+        // the range is from 16 to 69 as the lowest x coordinate of the rectangle is 15 and the highest is 69
+        _apy = rand()%28+2;
+    }
 
-        _reset_apple = false;
-    } else {
-        _apx = _apx;
-        _apy = _apy;
-    }
 
 }
-/*
-void Snake::get_time(Timer &timer)
-{
-    ticker.attach(&flip, 2.0);
-    _realtime = timer.read();
-    _display_time = (Reset_value - _realtime);
-    int x = _realtime;
-    int y = _display_time;
 
-    printf("12-T = %d     t =  %d   ", y, x);
-*/
-
-int Snake::set_reset_value()
-{
-
-    if (0 <= _score && _score < 10) {
-        _reset_value = 12;
-    }
-    if (10 <= _score && _score < 15) {
-        _reset_value = 10;
-    }
-    if (15 <= _score && _score < 20) {
-        _reset_value = 8;
-    } else {
-        _reset_value = 6;
-    }
-
-    return _reset_value;
-}
-
-
-//void Snake::print_display_time(N5110 &lcd)
-//{
-  //  int countdown = _realtime;
-
-  //  char buffer1[14];
-    //sprintf(buffer1,"%2d",countdown);
-    //lcd.printString(buffer1,WIDTH/2,30);  // font is 8 wide, so leave 4 pixel gape from middle assuming two digits
-    //char buffer2[14];
-    
-//}
\ No newline at end of file