hgftf

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

main.cpp

Committer:
ajorgih3
Date:
2020-11-20
Revision:
9:d09b96b6c39c
Parent:
8:34fd253d0fa5
Child:
10:0b2f37cef9b9

File content as of revision 9:d09b96b6c39c:

//=================================================================
// The main program file.
//
// Copyright 2020 Georgia Tech.  All rights reserved.
// The materials provided by the instructor in this course are for
// the use of the students currently enrolled in the course.
// Copyrighted course materials may not be further disseminated.
// This file must not be made publicly available anywhere.
//==================================================================

// Project includes
#include "globals.h"
#include "hardware.h"
#include "map.h"
#include "graphics.h"
#include "snake.h"

#include <math.h>
#include<stdio.h>
#include <time.h>
#include <stdlib.h>
#include <ctime>
#include <cstdlib>
#include <iostream> 

#define CITY_HIT_MARGIN 1
#define CITY_UPPER_BOUND (SIZE_Y-(LANDSCAPE_HEIGHT+MAX_BUILDING_HEIGHT))

// Helper function declarations
void playSound(char* wav);

/**
 * The main game state. Must include snake locations and previous locations for
 * drawing to work properly. Other items can be added as needed.
 */

/**
 * Given the game inputs, determine what kind of update needs to happen.
 * Possbile return values are defined below.
 */
Snake snake;
int score;
GameInputs input;
int main();
int previousState;
int thisState;
int lives = 0;
int main2();
int y;
MapItem *nextHead;
int updateY();
void go_right2();
void go_up2();
void go_down2();
void go_left2();
int bodyLength = 1;
int bodyX[50];
int bodyY[50];
int reverseCounter;
int speedCounter;
bool invincibility = false;
int shieldCounter = 0;
int slowflakeCounter = 0;
void additional_info();
int redCounter = 0;
int blueCounter = 0;

// Function prototypes

/**
 * Given the game inputs, determine what kind of update needs to happen.
 * Possible return values are defined below.
 */
#define NO_RESULT 0
#define NO_ACTION 0
#define ACTION_BUTTON 1
#define MENU_BUTTON 2
#define GO_LEFT 3
#define GO_RIGHT 4
#define GO_UP 5
#define GO_DOWN 6
#define GAME_OVER 7
#define FULL_DRAW 8
#define HAX 9
#define PAUSE 10
#define IN_GAME_MENU 11
#define NOT_RIGHT 12
#define SNAKE_MAX_LENGTH 50
#define WIN_GAME 13


// Get Actions from User (push buttons & accelerometer)
// Based on push button and accelerometer inputs, determine which action
// needs to be performed (may be no action).
int get_action(GameInputs inputs)
{
    // threshold for moving right
   if (inputs.ax >= 0.30 && inputs.ax <= 0.60) {
      return GO_RIGHT;
   }
    // threshold for moving left
   if (inputs.ax <= -0.30 && inputs.ax >= -0.60) {
      return GO_LEFT;
   }
    // threshold for moving up 
   if (inputs.ay >= 0.30 && inputs.ay <= 0.60) {
      return GO_UP;
   }
    // threshold for moving down
   if (inputs.ay <= -0.30 && inputs.ay >= -0.60) {
      return GO_DOWN;
   }
    
   if (!inputs.b1) {
      return HAX;
   }
   
   if (!inputs.b2) {
    return PAUSE;
   }
    
    // if we do not satisfy these conditions then 
    // no action is done
   return NO_ACTION;
}
/**
 * Update the game state based on the user action. For example, if the user
 * requests GO_UP, then this function should determine if that is possible by
 * consulting the map, and update the snake position accordingly.
 *
 * Return values are defined below. FULL_DRAW indicates that for this frame,
 * draw_game should not optimize drawing and should draw every tile, even if
 * the snake has not moved.
 */


/**
 * Draw the upper status bar.
 */
void draw_upper_status(int x, int y, int z)
{
   uLCD.line(0, 9, 127, 9, GREEN);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.color(0xFFFF00);
   uLCD.locate(0,0);
   uLCD.printf("POS:%d,%d ", x, y);
   uLCD.locate(10,0);
   uLCD.printf("SCORE:%d", score);
}

/**
 * Draw the lower status bar.
 */
void draw_lower_status(int lives)
{
   uLCD.line(0, 118, 127, 118, 0xFFFF00);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.color(0xFFFF00);
   uLCD.locate(0,15);
   uLCD.printf("LIVES:%d", lives);

}

/**
 * Draw the border for the map.
 */
void draw_border()
{
   uLCD.filled_rectangle(0,     9, 127,  14, WHITE); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, WHITE); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, WHITE); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, WHITE); // Right
}


/**
 * Entry point for frame drawing. This should be called once per iteration of
 * the game loop. This draws all tiles on the screen, followed by the status
 * bars. Unless init is nonzero, this function will optimize drawing by only
 * drawing tiles that have changed from the previous frame.
 */
void draw_game(int draw_option)
{   
    if (draw_option == WIN_GAME) {
      int u = 58;
      int v = 56;
      uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(5,7);
      uLCD.color(RED);
      uLCD.printf("YOU WIN\n");
      draw_snake_head(u+11, v+11);
      draw_snake_body(u, v+11);
      draw_snake_tail(u-11, v+11);
        
      uLCD.textbackground_color(BLACK);
      uLCD.color(0xFFFFFF);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(4, 10);
      uLCD.printf("Press  'B2'\n");
      uLCD.locate(2, 11);
      uLCD.printf("to play again!\n");  
      
      do {
         input = read_inputs();   
      } while(input.b2);
        
      uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
      main2();  
        
    }

    
    // prints game over if the player loses.
   if (draw_option == GAME_OVER) {
      int u = 58;
      int v = 56;
      uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(5,7);
      uLCD.color(RED);
      uLCD.printf("GAME OVER\n");
      draw_snake_head(u+22, v+11);
      draw_snake_tail(u-22, v+11);
        
      uLCD.textbackground_color(BLACK);
      uLCD.color(0xFFFFFF);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(4, 10);
      uLCD.printf("Press  'B2'\n");
      uLCD.locate(5, 11);
      uLCD.printf("to retry!\n");
        
      do {
         input = read_inputs();   
      } while(input.b2);
      
      uLCD.filled_rectangle(0, 0, 255, 255, BLACK);  
      main();
          
   }
    
    // Draw game border first
   if(draw_option == FULL_DRAW) 
   {
      draw_border();
      int u = 58;
      int v = 59;
        
      snake.locations[0].x = snake.body_x;
      snake.locations[0].y = snake.body_y;
        
      draw_snake_head(u, v);
      draw_snake_body(u-11, v);
      draw_snake_tail(u-22, v);
        
      return;
   }
    // Iterate over all visible map tiles
   for (int i = -5; i <= 5; i++) { // Iterate over columns of tiles
      for (int j = -4; j <= 4; j++) { // Iterate over one column of tiles
            // Here, we have a given (i,j)
      
            // Compute the current map (x,y) of this tile
         int x = i + snake.head_x;
         int y = j + snake.head_y;
      
            // Compute the previous map (px, py) of this tile
         int px = i + snake.head_px;
         int py = j + snake.head_py;
      
            // Compute u,v coordinates for drawing
         int u = (i+5)*11 + 3;
         int v = (j+4)*11 + 15;
      
            // Figure out what to draw
         DrawFunc draw = NULL;
         if (x >= 0 && y >= 0 && x < map_width() && y < map_height()) { // Current (i,j) in the map
            MapItem* curr_item = get_here(x, y);
            MapItem* prev_item = get_here(px, py);
            if (draw_option || curr_item != prev_item) { // Only draw if they're different
               if (curr_item) { // There's something here! Draw it
                  draw = curr_item->draw;
               } 
               else { // There used to be something, but now there isn't
                  draw = draw_nothing;
               }
            } 
            else if (curr_item && curr_item->type == CLEAR) {
                    // This is a special case for erasing things like doors.
               draw = curr_item->draw; // i.e. draw_nothing
            }
         } 
         else if (draw_option) { // If doing a full draw, but we're out of bounds, draw the walls.
            draw = draw_wall;
         }
      
            // Actually draw the tile
         if (draw) draw(u, v);
      }
   }

    // Draw status bars
   draw_upper_status(snake.head_x, updateY(), score);
   draw_lower_status(lives);
}

int updateY() {
   y = snake.head_y;
   return y;    
}

void start_game() {
   int u = 58;
   int v = 56; 
    
   uLCD.textbackground_color(GREEN);
   uLCD.filled_rectangle(0,     9, 127,  14, WHITE); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, WHITE); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, WHITE); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, WHITE); // Right
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(2, 3);
   uLCD.color(RED);
   uLCD.printf("-Sneaky Snakey-");
   uLCD.textbackground_color(BLUE);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(5, 4);
   uLCD.color(0xFFFF00);
   uLCD.printf("ECE 2035");
   uLCD.locate(7,5);
    
   draw_snake_head(u, v);
   draw_snake_body(u-11, v);
   draw_snake_tail(u-22, v);
    
   draw_goodie(u+22, v);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 10);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(5, 11);
   uLCD.printf("to start!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
}

void title_page() {
    
   int u = 58;
   int v = 56; 
    
   uLCD.filled_rectangle(0,     9, 127,  14, 0xFFFF00); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, 0xFFFF00); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, 0xFFFF00); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, 0xFFFF00); // Right
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(5, 3);
   uLCD.color(RED);
   uLCD.printf("OBJECTIVE");
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(2, 4);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Eat 20 goodies!");
    
   uLCD.locate(7,5);
   draw_goodie(u, v);
   draw_goodie(u-22, v);
   draw_goodie(u+22, v);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(3, 10);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(3, 11);
   uLCD.printf("to continue!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    
}

void helpful_items() {
   int u = 58;
   int v = 56; 
   
   uLCD.filled_rectangle(0,     9, 127,  14, 0xADD8E6); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, 0xADD8E6); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, 0xADD8E6); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, 0xADD8E6); // Right
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(6, 3);
   uLCD.color(0xFFFF00);
   uLCD.printf("BUFFS");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(1, 4);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Score w/o length");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(2, 5);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Invincibility");
    
   draw_shield(u-22, v);
   draw_blue_potion(u+22, v);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(3, 10);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(3, 11);
   uLCD.printf("to continue!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    
}

void harmful_items() {
   int u = 58;
   int v = 56; 
   
   uLCD.filled_rectangle(0,     9, 127,  14, RED); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, RED); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, RED); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, RED); // Right
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(5, 3);
   uLCD.color(0xFFA500);
   uLCD.printf("DEBUFFS");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(5, 4);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Reverse");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(1, 5);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Length w/o score");
    
   draw_red_potion(u-22, v);
   draw_reverse(u+22, v);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(3, 10);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(3, 11);
   uLCD.printf("to continue!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
   
}

void helpful_items2() {
   int u = 58;
   int v = 56; 
   
   uLCD.filled_rectangle(0,     9, 127,  14, 0x0000FF); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, 0x0000FF); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, 0x0000FF); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, 0x0000FF); // Right
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(2, 3);
   uLCD.color(0xFFFF00);
   uLCD.printf("HELPFUL ITEMS++");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 4);
   uLCD.color(0xFFFFFF);
   uLCD.printf("Extra Life!");
    
   draw_life(u, v);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 10);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(4, 11);
   uLCD.printf("to go back!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
   additional_info(); 
}


void harmful_items2() {
   int u = 58;
   int v = 56; 
   
   uLCD.filled_rectangle(0,     9, 127,  14, 0xD2691E); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, 0xD2691E); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, 0xD2691E); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, 0xD2691E); // Right
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(2, 3);
   uLCD.color(0xFFA500);
   uLCD.printf("HARMFUL ITEMS++");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 4);
   uLCD.color(0xFFFFFF);
   uLCD.printf("SLOWFLAKES");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 5);
   uLCD.color(0xFFFFFF);
   uLCD.printf("LIFETAKER");
    
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 6);
   uLCD.color(0xFFFFFF);
   uLCD.printf("LIGHTSPEED");
    
   draw_snowflake(u-22, v+11);
   draw_sword(u, v+11);
   draw_lightspeed(u+22, v+11);
    
   uLCD.textbackground_color(BLACK);
   uLCD.color(0xFFFFFF);
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 11);
   uLCD.printf("Press  'B2'\n");
   uLCD.locate(4, 12);
   uLCD.printf("to continue!\n");
    
   do {
      input = read_inputs();    
   } while(input.b2);
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
   helpful_items2();
}

void additional_info() {
    
    int u = 58;
    int v = 56;
    
    draw_shield(u+22, v+22);
    draw_blue_potion(u-22, v+22);
    draw_red_potion(u-22, v+33);
    draw_reverse(u+22, v+33);
    
   uLCD.filled_rectangle(0,     9, 127,  14, RED); // Top
   uLCD.filled_rectangle(0,    13,   2, 114, GREEN); // Left
   uLCD.filled_rectangle(0,   114, 127, 117, 0x0000FF); // Bottom
   uLCD.filled_rectangle(124,  14, 127, 117, 0xFFFF00); // Right 

   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(1, 3);
   uLCD.color(0xFFFFFF);
   uLCD.printf("B1: OTHER ITEMS!");
   
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 5);
   uLCD.color(0xFFFFFF);
   uLCD.printf("B2: MAPS!");
   
   uLCD.text_width(1);
   uLCD.text_height(1);
   uLCD.locate(4, 7);
   uLCD.color(0xFFFFFF);
   uLCD.printf("B3: START!");
   
   do {
    input = read_inputs();
   } while (input.b1 && input.b2 && input.b3);
   
   uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
   if (!input.b1) {
       harmful_items2();
    }
    
    uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    if (!input.b2) {
       main2();
    }
    
    if (!input.b3) {
    uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    return;    
    }
   
}

void bruh() {
return;    
}


/**
 * Initialize the main world map. Add walls around the edges, interior chambers,
 * and plants in the background so you can see motion.
 */
void init_main_map()
{   
    // "Random" plants
   Map* map = set_active_map(0);
   pc.printf("plants\r\n");
   
   add_portal(7, 5);
   
   for (int i = 0; i < 20; i++) {
   int goodieRandX = rand() % 50;
   int goodieRandY = rand() % 50;
   add_goodie(goodieRandX, goodieRandY);
   }
   
   for (int i = 0; i < 30; i++) {
   int goodieRandX = rand() % 50;
   int goodieRandY = rand() % 50;
   add_goodie(goodieRandX, goodieRandY);
   }
   
   for (int i = 0; i < 10; i++) {
   int redRandX = rand() % 50;
   int redRandY = rand() % 50;
   add_red_potion(redRandX, redRandY);
   }
//   
   for (int i = 0; i < 10; i++) {
   int swordRandX = rand() % 50;
   int swordRandY = rand() % 50;
   add_sword(swordRandX, swordRandY);
   }
//   
   for (int i = 0; i < 5; i++) {
   int lifeRandX = rand() % 50;
   int lifeRandY = rand() % 50;
   add_life(lifeRandX, lifeRandY);
   }
//   
   for (int i = 0; i < 5; i++) {
   int blueRandX = rand() % 50;
   int blueRandY = rand() % 50;
   add_blue_potion(blueRandX, blueRandY);
   }
//   
    for (int i = 0; i < 5; i++) {
   int shieldRandX = rand() % 50;
   int shieldRandY = rand() % 50;
   add_shield(shieldRandX, shieldRandY);
   }
   
   for (int i = 0; i < 10; i++) {
   int reverseRandX = rand() % 50;
   int reverseRandY = rand() % 50;
   add_reverse(reverseRandX, reverseRandY);
   }
    
   pc.printf("Adding walls!\r\n");
   add_wall(0,              0,              HORIZONTAL, map_width());
   add_wall(0,              map_height()-1, HORIZONTAL, map_width());
   add_wall(0,              0,              VERTICAL,   map_height());
   add_wall(map_width()-1,  0,              VERTICAL,   map_height());
   pc.printf("Walls done!\r\n");
    
   add_snake_head(snake.locations[0].x, snake.locations[0].y);
   add_snake_body(snake.locations[1].x, snake.locations[1].y);
   add_snake_tail(snake.locations[2].x, snake.locations[2].y);
    
  // pc.printf("Add extra chamber\r\n");
//   add_wall(30, 0, VERTICAL, 10);
//   add_wall(30, 10, HORIZONTAL, 10);
//   add_wall(39, 0, VERTICAL, 10);
//   pc.printf("Added!\r\n");
    
    


    // Add stairs to chamber (map 1)
    //add_stairs(15, 5, 1, 5, 5);

//    profile_hashtable();
   print_map();
}

void init_map_2() {
    
   Map* map = set_active_map(0);
    
   pc.printf("Adding walls!\r\n");
   add_blue_wall(0,              0,              HORIZONTAL, map_width());
   add_blue_wall(0,              map_height()-1, HORIZONTAL, map_width());
   add_blue_wall(0,              0,              VERTICAL,   map_height());
   add_blue_wall(map_width()-1,  0,              VERTICAL,   map_height());
   pc.printf("Walls done!\r\n"); 
   print_map();  
    
}

void go_right2() {
   add_nothing(snake.tail_x, snake.tail_y);
// previous coordinate of the snake head which will be used by the body
   int previousX = snake.head_x;
   int previousY = snake.head_y;
//int tempPreviousX = previousX;
//int tempPreviousY = previousY;
   pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);

// try this
   for (int i = 0; i < bodyLength; i++) {
      pc.printf("Loop Number: %d\n", i);
    
      add_snake_body(previousX, previousY); // adds snake body to the head //7, 5
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.body_x = previousX; // updates the coordinates of the snake body with the previous head
      snake.body_y = previousY; // snake body is now 7, 5
    
      pc.printf("snake_body_x: %d, snake_body_y: %d\n", snake.body_x, snake.body_y);
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
    
      previousX = snake.locations[i].x; // previous location of the body to previousX 
      previousY = snake.locations[i].y; // and previousY //6,5 
    
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.locations[i].x = snake.body_x; // updates the snake locations with the new values
      snake.locations[i].y = snake.body_y;
    
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
   }
       
   snake.tail_x = previousX;
   snake.tail_y = previousY;
   add_snake_tail(snake.tail_x, snake.tail_y);

// update the head
   snake.head_x = snake.head_x + 1;
   snake.head_y = snake.head_y + 0; 
   add_snake_head(snake.head_x, snake.head_y); // correct
   
   if (speedCounter <= 50 && speedCounter != 0) {
     speedCounter--;
     return;  
   }
    if (slowflakeCounter <= 20 && slowflakeCounter != 0) {
      slowflakeCounter--;
      wait(1);
      return; 
    }

   wait(0.2);
}

void go_up2() {
   add_nothing(snake.tail_x, snake.tail_y);
// previous coordinate of the snake head which will be used by the body
   int previousX = snake.head_x;
   int previousY = snake.head_y;
//int tempPreviousX = previousX;
//int tempPreviousY = previousY;
   pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);

// try this
   for (int i = 0; i < bodyLength; i++) {
      pc.printf("Loop Number: %d\n", i);
    
      add_snake_body(previousX, previousY); // adds snake body to the head //7, 5
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.body_x = previousX; // updates the coordinates of the snake body with the previous head
      snake.body_y = previousY; // snake body is now 7, 5
    
      pc.printf("snake_body_x: %d, snake_body_y: %d\n", snake.body_x, snake.body_y);
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
    
      previousX = snake.locations[i].x; // previous location of the body to previousX 
      previousY = snake.locations[i].y; // and previousY //6,5 
    
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.locations[i].x = snake.body_x; // updates the snake locations with the new values
      snake.locations[i].y = snake.body_y;
    
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
   }
       
   snake.tail_x = previousX;
   snake.tail_y = previousY;
   add_snake_tail(snake.tail_x, snake.tail_y);

// update the head
   snake.head_x = snake.head_x + 0;
   snake.head_y = snake.head_y - 1; 
   add_snake_head(snake.head_x, snake.head_y); // correct
   
   if (speedCounter <= 50 && speedCounter != 0) {
     speedCounter--;
     return;  
   }
    if (slowflakeCounter <= 20 && slowflakeCounter != 0) {
      slowflakeCounter--;
      wait(1);
      return; 
    }

   wait(0.2); 
}

void go_down2() {
   add_nothing(snake.tail_x, snake.tail_y);
// previous coordinate of the snake head which will be used by the body
   int previousX = snake.head_x;
   int previousY = snake.head_y;
//int tempPreviousX = previousX;
//int tempPreviousY = previousY;
   pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);

// try this
   for (int i = 0; i < bodyLength; i++) {
      pc.printf("Loop Number: %d\n", i);
    
      add_snake_body(previousX, previousY); // adds snake body to the head //7, 5
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.body_x = previousX; // updates the coordinates of the snake body with the previous head
      snake.body_y = previousY; // snake body is now 7, 5
    
      pc.printf("snake_body_x: %d, snake_body_y: %d\n", snake.body_x, snake.body_y);
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
    
      previousX = snake.locations[i].x; // previous location of the body to previousX 
      previousY = snake.locations[i].y; // and previousY //6,5 
    
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.locations[i].x = snake.body_x; // updates the snake locations with the new values
      snake.locations[i].y = snake.body_y;
    
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
   }
       
   snake.tail_x = previousX;
   snake.tail_y = previousY;
   add_snake_tail(snake.tail_x, snake.tail_y);

// update the head
   snake.head_x = snake.head_x + 0;
   snake.head_y = snake.head_y + 1; 
   add_snake_head(snake.head_x, snake.head_y); // correct
   
   if (speedCounter <= 50 && speedCounter != 0) {
     speedCounter--;
     return;  
   }
   
    if (slowflakeCounter <= 20 && slowflakeCounter != 0) {
      slowflakeCounter--;
      wait(1);
      return; 
    }

   wait(0.2);  
}

void go_left2() {
   
   if (!(get_here(snake.head_x - 1, snake.head_y)->walkable)) {
       pc.printf("SUCCESS!\n\n");
       return;
    }

   add_nothing(snake.tail_x, snake.tail_y);
// previous coordinate of the snake head which will be used by the body
   int previousX = snake.head_x;
   int previousY = snake.head_y;
//int tempPreviousX = previousX;
//int tempPreviousY = previousY;
   pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);

// try this
   for (int i = 0; i < bodyLength; i++) {
      pc.printf("Loop Number: %d\n", i);
    
      add_snake_body(previousX, previousY); // adds snake body to the head //7, 5
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.body_x = previousX; // updates the coordinates of the snake body with the previous head
      snake.body_y = previousY; // snake body is now 7, 5
    
      pc.printf("snake_body_x: %d, snake_body_y: %d\n", snake.body_x, snake.body_y);
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
    
      previousX = snake.locations[i].x; // previous location of the body to previousX 
      previousY = snake.locations[i].y; // and previousY //6,5 
    
      pc.printf("previousX: %d, previousY: %d\n", previousX, previousY);
    
      snake.locations[i].x = snake.body_x; // updates the snake locations with the new values
      snake.locations[i].y = snake.body_y;
    
      pc.printf("snake.locations[%d].x: %d, snake.locations[%d].x: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
   }
       
   snake.tail_x = previousX;
   snake.tail_y = previousY;
   add_snake_tail(snake.tail_x, snake.tail_y);

// update the head
   snake.head_x = snake.head_x - 1;
   snake.head_y = snake.head_y + 0; 
   add_snake_head(snake.head_x, snake.head_y); // correct
   
   if (speedCounter <= 50 && speedCounter != 0) {
     speedCounter--;
     return;  
   }
   
   if (slowflakeCounter <= 20 && slowflakeCounter != 0) {
      slowflakeCounter--;
      wait(1);
      return; 
    }

   wait(0.2);  

}


int update_game(int action)
{   
   snake.head_px = snake.head_x;
   snake.body_px = snake.body_x;
   snake.tail_px = snake.tail_x;
   snake.head_py = snake.head_y;
   snake.body_py = snake.body_y;
   snake.tail_py = snake.tail_y;
    
    //snake.locations[0].x = snake.body_x;
    //snake.locations[0].y = snake.body_y;
    
    if (score == 20) {
    draw_game(WIN_GAME);    
    }
    
        uLCD.filled_rectangle(0,     9, 127,  14, 0xFFFFFF); // Top
        uLCD.filled_rectangle(0,    13,   2, 114, 0xFFFFFF); // Left
        uLCD.filled_rectangle(0,   114, 127, 117, 0xFFFFFF); // Bottom
        uLCD.filled_rectangle(124,  14, 127, 117, 0xFFFFFF); // Right
        draw_nothing(102, 100);
        
    
    //pc.printf("Shield Counter: %d\n", shieldCounter);
   switch(action) {
        
      case GO_RIGHT:
         nextHead = get_east(snake.head_x, snake.head_y);
         pc.printf("GO RIGHT\n");
         if (nextHead->walkable && nextHead->type != LIFE && nextHead->type != GOODIE && nextHead->type != SWORD && nextHead->type != REVERSE && nextHead->type != LIGHTSPEED && nextHead->type != SHIELD && nextHead->type != SNOWFLAKE && nextHead->type != BLUEPOTION && nextHead->type !=REDPOTION && nextHead->type != BLUEPOTION && nextHead->type != PORTAL) {
            pc.printf("Before:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            pc.printf("reverseCounter: %d\n\n", reverseCounter);
            pc.printf("speedCounter: %d\n\n", speedCounter);
            pc.printf("shieldCounter: %d\n\n", shieldCounter);
            pc.printf("slowflakeCounter: %d", slowflakeCounter);
            pc.printf("blueCounter: %d\n", blueCounter);
            pc.printf("redCounter: %d", redCounter);
            if (reverseCounter == 0) {
            go_right2(); 
            draw_arrow_right(113, 100);  
            }
            if (reverseCounter <= 20 && reverseCounter != 0) {
            go_left2(); 
            draw_arrow_left(113, 100);
            pc.printf("reverseCounter: %d", reverseCounter);
            reverseCounter--;  
            }
           //draw_snake_head(snake.head_pi, snake.head_pj);
           //draw_snake_body(snake.body_pi, snake.body_pj);
           //draw_snake_tail(snake.tail_pi, snake.tail_pj);
            updateY();
            pc.printf("After:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            if (shieldCounter <= 15 && shieldCounter != 0) {
             shieldCounter--;
             }
            if (blueCounter <= 20 && blueCounter != 0) {
              blueCounter--;  
            }
            if (redCounter <= 20 && redCounter != 0) {
              redCounter--;  
            }
         }
        
         if (!nextHead->walkable && invincibility == false) {
            if (shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               lives--;  
                }
            }
         }
      
         if (nextHead->type == LIFE) {
            lives += 1;
            add_nothing(snake.head_x + 1, snake.head_y);
         }
        
         if (nextHead->type == GOODIE) {
            if (redCounter == 0) {
            score++;
            }
            
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x + 1, snake.head_y);
            
            if (blueCounter == 0) {
            // if the snake is straight right
            if ((snake.body_x - 1) == (snake.tail_x)) {
               add_snake_body(snake.body_x - 1, snake.body_y);
               add_snake_tail(snake.tail_x - 1, snake.tail_y);
            }
            
            // if the snake's tail is on top of the body
            if ((snake.body_y - 1) == snake.tail_y) {
               add_snake_body(snake.body_x, snake.body_y - 1);
               add_snake_tail(snake.tail_x, snake.tail_y - 1);
            }
            
            // if the snake's tail is below the body
            if ((snake.body_y + 1) == snake.tail_y) {
               add_snake_body(snake.body_x, snake.body_y + 1);
               add_snake_tail(snake.tail_x, snake.tail_y + 1);    
            }
            
            // this places a new body coordinate before the main body, this is go right function
            for (int i = 0; i < SNAKE_MAX_LENGTH; i++) {
               if (snake.locations[i].x == 0 && snake.locations[i].y == 0) {
                    
                    // assuming that the snake is all the way to the right
                  if ((snake.body_x - 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x - 1;
                     snake.locations[i].y = snake.body_y;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x - 1;
                     snake.tail_y = snake.tail_y;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                  }
                    
                    // tail is over the body
                  if ((snake.body_y - 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y - 1;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y - 1;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                  }
                        
                    //assuming that the body is on top of the tail
                  if ((snake.body_y + 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y + 1;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y + 1;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);   
                  }
                    
                  break;
               }
               pc.printf("i: %d\n", i);
            }
         }
        }
        
         if (nextHead->type == SNOWFLAKE) {
            slowflakeCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x + 1, snake.head_y);
         } 
        
         if (nextHead->type == SWORD) {
            if (lives == 0 && shieldCounter == 0) {
               draw_game(GAME_OVER);
            }
            else {
               if (shieldCounter == 0) {
               lives--; 
               } 
            }
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x + 1, snake.head_y);
         }
         
         if (nextHead->type == REVERSE) {
            reverseCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x + 1, snake.head_y);
         }
        
        if (nextHead->type == LIGHTSPEED) {
            speedCounter = 50; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x + 1, snake.head_y);
         }
         
         if (nextHead->type == SHIELD) {
         shieldCounter = 15; 
         map_erase(snake.head_x, snake.head_y);
         add_nothing(snake.head_x + 1, snake.head_y);  
         }
         
         if (nextHead->type == REDPOTION) {
         redCounter = 20; 
         map_erase(snake.head_x, snake.head_y);
         add_nothing(snake.head_x + 1, snake.head_y);  
         }
         
         if (nextHead->type == BLUEPOTION) {
         blueCounter = 20; 
         map_erase(snake.head_x, snake.head_y);
         add_nothing(snake.head_x + 1, snake.head_y);  
         }
         
         if (nextHead->type == PORTAL) {
         main2();  
         }
         
         break;
        
      case GO_LEFT:
         nextHead = get_west(snake.head_x, snake.head_y);
         pc.printf("GO LEFT\n");
         if (nextHead->walkable && nextHead->type != LIFE && nextHead->type != GOODIE && nextHead->type != SWORD && nextHead->type != REVERSE && nextHead->type != LIGHTSPEED && nextHead->type != SHIELD && nextHead->type != SNOWFLAKE && nextHead->type != BLUEPOTION && nextHead->type != REDPOTION) {
            pc.printf("Before:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            pc.printf("reverseCounter: %d\n\n", reverseCounter);
            pc.printf("speedCounter: %d\n\n", speedCounter);
            pc.printf("shieldCounter: %d\n\n", shieldCounter);
             pc.printf("slowflakeCounter: %d", slowflakeCounter);
             pc.printf("blueCounter: %d", blueCounter);
             pc.printf("redCounter: %d", redCounter);
            if (reverseCounter == 0 && nextHead->walkable) {
            go_left2();
            draw_arrow_left(113, 100);
            }
            if (reverseCounter <= 20 && reverseCounter != 0) {
            go_right2();
            draw_arrow_right(113, 100);  
            pc.printf("reverseCounter: %d", reverseCounter);
            reverseCounter--;  
            }
           //draw_snake_head(snake.head_pi, snake.head_pj);
           //draw_snake_body(snake.body_pi, snake.body_pj);
           //draw_snake_tail(snake.tail_pi, snake.tail_pj);
            updateY();
            pc.printf("After:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            if (shieldCounter <= 15 && shieldCounter != 0) {
             shieldCounter--;
             }
            if (blueCounter <= 20 && blueCounter != 0) {
              blueCounter--;  
            }
            if (redCounter <= 20 && redCounter != 0) {
              redCounter--;  
            }
         }
        
         if (!nextHead->walkable && invincibility == false) {
            if (shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               lives--;  
                }
            }
         }
      
         if (nextHead->type == LIFE) {
            lives++;
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x-1, snake.head_y);
         }
        
         if (nextHead->type == GOODIE) {
            if (redCounter == 0) {
            score++;
            }
            
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y); // eat the goodie
            
            if (blueCounter == 0) {
            if ((snake.body_x + 1) == (snake.tail_x)) {
               add_nothing(snake.head_x - 1, snake.head_y); // eat the goodie
               add_snake_body(snake.body_x + 1, snake.body_y);
               add_snake_tail(snake.tail_x + 1, snake.tail_y);
            }
            
            if ((snake.body_y - 1) == snake.tail_y) {
               add_nothing(snake.head_x - 1, snake.head_y); // eat the goodie
               add_snake_body(snake.body_x, snake.body_y - 1);
               add_snake_tail(snake.tail_x, snake.tail_y - 1);    
            }
            
            if ((snake.body_y + 1) == snake.tail_y) {
               add_nothing(snake.head_x - 1, snake.head_y); // eat the goodie
               add_snake_body(snake.body_x, snake.body_y + 1);
               add_snake_tail(snake.tail_x, snake.tail_y + 1);    
            }
            
            // this places a new body coordinate before the main body, this is go right function
            for (int i = 0; i < SNAKE_MAX_LENGTH; i++) {
               if (snake.locations[i].x == 0 && snake.locations[i].y == 0) {
                    
                  if ((snake.body_x + 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x + 1;
                     snake.locations[i].y = snake.body_y;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x + 1;
                     snake.tail_y = snake.tail_y;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                  }
                    
                  if ((snake.body_y - 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y - 1;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y - 1;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);    
                  }
                    
                  if ((snake.body_y + 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y + 1;
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     bodyLength++;
                     pc.printf("body length: %d\n", bodyLength);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y + 1;
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);    
                  }
                    
                  break;
               }
               pc.printf("i: %d\n", i);
            }
         }
    }
        
        
         if (nextHead->type == SNOWFLAKE) {
            slowflakeCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         } 
        
         if (nextHead->type == SWORD && shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               if (shieldCounter == 0) {
               lives--; 
               } 
            }
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x-1, snake.head_y);
         }
         
         if (nextHead->type == REVERSE) {
            reverseCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         }
         
         if (nextHead->type == LIGHTSPEED) {
            speedCounter = 50; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         }
         
         if (nextHead->type == SHIELD) {
            shieldCounter = 15; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         }
         
         if (nextHead->type == REDPOTION) {
            redCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         }
         
         if (nextHead->type == BLUEPOTION) {
            blueCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         }
         break;
        
        
      case GO_UP:
         nextHead = get_north(snake.head_x, snake.head_y);
         pc.printf("GO UP\n");
         if (nextHead->walkable && nextHead->type != LIFE && nextHead->type != GOODIE && nextHead->type != SWORD && nextHead->type != REVERSE && nextHead->type != LIGHTSPEED && nextHead->type != SHIELD && nextHead->type != SNOWFLAKE && nextHead->type != BLUEPOTION && nextHead->type != REDPOTION) {
            pc.printf("Before:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            pc.printf("reverseCounter: %d\n\n", reverseCounter);
            pc.printf("speedCounter: %d\n\n", speedCounter);
            pc.printf("shieldCounter: %d\n\n", shieldCounter);
             pc.printf("slowflakeCounter: %d", slowflakeCounter);
             pc.printf("blueCounter: %d", blueCounter);
             pc.printf("redCounter: %d", redCounter);
            // reverse direction 
            if (reverseCounter == 0) {
            go_up2();
            draw_arrow_up(113, 100);
            }
            if (reverseCounter <= 20 && reverseCounter != 0) {
            go_down2(); 
            draw_arrow_down(113, 100);  
            pc.printf("reverseCounter: %d", reverseCounter);
            reverseCounter--;
            }
           //draw_snake_head(snake.head_pi, snake.head_pj);
           //draw_snake_body(snake.body_pi, snake.body_pj);
           //draw_snake_tail(snake.tail_pi, snake.tail_pj);
            updateY();
            pc.printf("After:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            if (shieldCounter <= 15 && shieldCounter != 0) {
             shieldCounter--;
             }
            if (blueCounter <= 20 && blueCounter != 0) {
              blueCounter--;  
            }
            if (redCounter <= 20 && redCounter != 0) {
              redCounter--;  
            }
         }
        
         if (!nextHead->walkable && invincibility == false) {
            if (shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               lives--;  
                }
            }
         }
      
         if (nextHead->type == LIFE) {
            lives++;
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
        
         if (nextHead->type == GOODIE) {
            
            if (redCounter == 0) {
            score++;
            }
            
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1); // eat the goodie
            
            if (blueCounter == 0) {
            if ((snake.body_x - 1) == snake.tail_x) {
               add_snake_body(snake.body_x - 1, snake.body_y);
               add_snake_tail(snake.tail_x - 1, snake.tail_y);
            }
            
            if ((snake.body_x + 1) == snake.tail_x) {
               add_snake_body(snake.body_x + 1, snake.body_y);
               add_snake_tail(snake.tail_x + 1, snake.tail_y);
            }
            
            if ((snake.body_y + 1) == snake.tail_y) {
               add_snake_body(snake.body_x, snake.body_y + 1);
               add_snake_tail(snake.tail_x, snake.tail_y + 1);
            }
            
    
            // this places a new body coordinate before the main body, this is go right function
            for (int i = 0; i < SNAKE_MAX_LENGTH; i++) {
               if (snake.locations[i].x == 0 && snake.locations[i].y == 0) {
                    
                    // if snake is upright
                  if ((snake.body_y + 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y + 1; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y + 1; // this updates the new tail location
                  }
                    
                  if ((snake.body_x + 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x + 1;
                     snake.locations[i].y = snake.body_y; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x + 1;
                     snake.tail_y = snake.tail_y; // this updates the new tail location
                  }
                    
                  if ((snake.body_x - 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x - 1;
                     snake.locations[i].y = snake.body_y; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x - 1;
                     snake.tail_y = snake.tail_y; // this updates the new tail location
                  }
                    
                    
                  pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                  bodyLength++;
                    
                  pc.printf("body length: %d\n", bodyLength);
                  break;
               }
               pc.printf("i: %d\n", i);
            }
         }
        }
        
         if (nextHead->type == SNOWFLAKE) {
            slowflakeCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         } 
        
         if (nextHead->type == SWORD && shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               if (shieldCounter == 0) {
               lives--; 
               } 
            }
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y);
         }
         
         if (nextHead->type == REVERSE) {
            reverseCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
         
         if (nextHead->type == LIGHTSPEED) {
            speedCounter = 50; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
         
         if (nextHead->type == SHIELD) {
            shieldCounter = 15; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
         
        if (nextHead->type == BLUEPOTION) {
            blueCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
         if (nextHead->type == REDPOTION) {
            redCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y - 1);
         }
         break;
        
        
      case GO_DOWN:
         nextHead = get_south(snake.head_x, snake.head_y);
         pc.printf("GO DOWN\n");
         if (nextHead->walkable && nextHead->type != LIFE && nextHead->type != GOODIE && nextHead->type != SWORD && nextHead->type != REVERSE && nextHead->type != LIGHTSPEED && nextHead->type != SHIELD && nextHead->type != SNOWFLAKE && nextHead->type != BLUEPOTION && nextHead->type != REDPOTION) {
            pc.printf("Before:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            pc.printf("reverseCounter: %d\n\n", reverseCounter);
            pc.printf("speedCounter: %d\n\n", speedCounter);
            pc.printf("shieldCounter: %d\n\n", shieldCounter);
            pc.printf("slowflakeCounter: %d", slowflakeCounter);
            pc.printf("blueCounter: %d", blueCounter);
            pc.printf("redCounter: %d", redCounter);
            if (reverseCounter == 0) {
            go_down2();
            draw_arrow_down(113, 100);
            }
            if (reverseCounter <= 20 && reverseCounter !=0) {
            go_up2();    
            draw_arrow_up(113, 100);
            pc.printf("reverseCounter: %d", reverseCounter);
            reverseCounter--;
            }
            //draw_snake_head(snake.head_pi, snake.head_pj);
           //draw_snake_body(snake.body_pi, snake.body_pj);
           //draw_snake_tail(snake.tail_pi, snake.tail_pj);
            updateY();
            pc.printf("After:\n");
            pc.printf("head_x: %d, head_y: %d\n", snake.head_x, snake.head_y);
            pc.printf("body_x: %d, body_y: %d\n", snake.body_x, snake.body_y);
            pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
            if (shieldCounter <= 15 && shieldCounter != 0) {
             shieldCounter--;
             }
            if (blueCounter <= 20 && blueCounter != 0) {
              blueCounter--;  
            }
            if (redCounter <= 20 && redCounter != 0) {
              redCounter--;  
            }
         }
         
         if (!nextHead->walkable && invincibility == false) {
            if (shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               lives--;  
                }
            }
         }
      
         if (nextHead->type == LIFE) {
            lives++;
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y+1);
         }
        
         if (nextHead->type == GOODIE) {
            
            if (redCounter == 0) {
            score++;
            }
            
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1); // eat the goodie
            
            if (blueCounter == 0) {
            // if the tail is to the left of the body
            if ((snake.body_x - 1) == snake.tail_x) {
               add_snake_body(snake.body_x - 1, snake.body_y);
               add_snake_tail(snake.tail_x - 1, snake.tail_y);
            }
            
            // if the tail is to the right of the body
            if ((snake.body_x + 1) == snake.tail_x) {
               add_snake_body(snake.body_x + 1, snake.body_y);
               add_snake_tail(snake.tail_x + 1, snake.tail_y);
            }
            
            // if the snake is upright
            if ((snake.body_y - 1) == snake.tail_y) {
               add_snake_body(snake.body_x, snake.body_y + 1);
               add_snake_tail(snake.tail_x, snake.tail_y + 1);
            }
            
            // this places a new body coordinate before the main body, this is go right function
            for (int i = 0; i < SNAKE_MAX_LENGTH; i++) {
               if (snake.locations[i].x == 0 && snake.locations[i].y == 0) {
                    
                    // if snake is upright
                  if ((snake.body_y - 1) == snake.tail_y) {
                     snake.locations[i].x = snake.body_x;
                     snake.locations[i].y = snake.body_y - 1; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x;
                     snake.tail_y = snake.tail_y - 1; // this updates the new tail location
                  }
                    
                  if ((snake.body_x + 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x + 1;
                     snake.locations[i].y = snake.body_y; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x + 1;
                     snake.tail_y = snake.tail_y; // this updates the new tail location
                  }
                    
                  if ((snake.body_x - 1) == snake.tail_x) {
                     snake.locations[i].x = snake.body_x - 1;
                     snake.locations[i].y = snake.body_y; // this stores the snake new body location into a non-filled array
                    
                     pc.printf("snake.locations[%d].x: %d, snake.locations[%d].y: %d\n", i, snake.locations[i].x, i, snake.locations[i].y);
                     pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                     snake.tail_x = snake.tail_x - 1;
                     snake.tail_y = snake.tail_y; // this updates the new tail location
                  }
                    
                    
                  pc.printf("tail_x: %d, tail_y: %d\n", snake.tail_x, snake.tail_y);
                    
                  bodyLength++;
                    
                  pc.printf("body length: %d\n", bodyLength);
                  break;
               }
               pc.printf("i: %d\n", i);
            }
        }
     }
        
         if (nextHead->type == SNOWFLAKE) {
            slowflakeCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x - 1, snake.head_y);
         } 
        
         if (nextHead->type == SWORD && shieldCounter == 0) {
            if (lives == 0) {
               draw_game(GAME_OVER);
            }
            else {
               if (shieldCounter == 0) {
               lives--; 
               } 
            }
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y+1);
         }
         
         if (nextHead->type == REVERSE) {
            reverseCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1);
         }
         
         if (nextHead->type == LIGHTSPEED) {
            speedCounter = 50; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1);
         }
         
         if (nextHead->type == SHIELD) {
            shieldCounter = 15; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1);
         }
         
         if (nextHead->type == REDPOTION) {
            redCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1);
         }
         
         if (nextHead->type == BLUEPOTION) {
            blueCounter = 20; 
            map_erase(snake.head_x, snake.head_y);
            add_nothing(snake.head_x, snake.head_y + 1);
         }
         
         break;
        
      case HAX: 
         invincibility = true;
         break;
         
      case PAUSE:
        uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
        uLCD.filled_rectangle(0,     9, 127,  14, 0xFFFFFF); // Top
        uLCD.filled_rectangle(0,    13,   2, 114, 0xFFFFFF); // Left
        uLCD.filled_rectangle(0,   114, 127, 117, 0xFFFFFF); // Bottom
        uLCD.filled_rectangle(124,  14, 127, 117, 0xFFFFFF); // Right();
        
      int u = 58;
      int v = 56;
      uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(5,7);
      uLCD.color(RED);
      uLCD.printf("PAUSING...\n");
      draw_snake_head(u+11, v+11);
      draw_snake_body(u, v+11);
      draw_snake_tail(u-11, v+11);
        
      uLCD.textbackground_color(BLACK);
      uLCD.color(0xFFFFFF);
      uLCD.text_width(1);
      uLCD.text_height(1);
      uLCD.locate(4, 10);
      uLCD.printf("Press  'B2'\n");
      uLCD.locate(5, 11);
      uLCD.printf("to unpause!\n");
      uLCD.locate(0, 0);
      uLCD.color(0xFFFFFF);
      uLCD.printf("STATUS:");
     
      if (shieldCounter == 0) {
        draw_nothing(0, 11);
        }
      else {
        draw_shield(0, 11);
        }
        
      if (speedCounter == 0) {
        draw_nothing(11, 11);
        }
      else {
        draw_lightspeed(11, 11);
        }
        
      if (redCounter == 0) {
        draw_nothing(22, 11);
        }
      else {
        draw_red_potion(22, 11);
        }
        
       if (blueCounter == 0) {
        draw_nothing(33, 11);
        }
      else {
        draw_blue_potion(33, 11);
        }
        
       if (slowflakeCounter == 0) {
        draw_nothing(44, 11);
        }
      else {
        draw_snowflake(44, 11);
        }
         
      do {
        input = read_inputs();    
      } while(input.b2);
      
        uLCD.filled_rectangle(0,     9, 127,  14, 0xFFFFFF); // Top
        uLCD.filled_rectangle(0,    13,   2, 114, 0xFFFFFF); // Left
        uLCD.filled_rectangle(0,   114, 127, 117, 0xFFFFFF); // Bottom
        uLCD.filled_rectangle(124,  14, 127, 117, 0xFFFFFF); // Right
        uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
        break;
        
      default: 
         break;
   }
        
        
        
   return NO_RESULT;
}


/**
 * Program entry point! This is where it all begins.
 * This function or all the parts of the game. Most of your
 * implementation should be elsewhere - this holds the game loop, and should
 * read like a road map for the rest of the code.
 */
int main()
{
    // First things first: initialize hardware
   ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
    
    //start_game();
    //title_page();
    //helpful_items();
    //harmful_items();
    //additional_info();
    
    // loading screen
    //uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    //uLCD.textbackground_color(BLACK);
    //uLCD.color(0xFFFFFF);
    //uLCD.locate(4,7);
    //uLCD.printf("GOOD LUCK!");
    //uLCD.locate(4,8);
    //uLCD.printf("Loading...");
    //wait(4);
    //uLCD.filled_rectangle(0, 0, 255, 255, BLACK);
    
   snake_init(&snake);
    // 0. Initialize the maps -- implement this function:
   maps_init();
    

    
   init_main_map();
        //init_map_2();
    

    // Initialize game state
   set_active_map(0);
   snake.head_x = snake.head_y = 5;
   snake.body_x = 4;
   snake.body_y = 5;
   snake.tail_x = 3;
   snake.tail_y = 5;
    // Initial drawing
   draw_game(FULL_DRAW);
    // Main game loop
   while(1) {
        // Timer to measure game update speed
      Timer t;
      t.start();
   
        // 1. Read inputs -- implement this function:
      GameInputs inputs = read_inputs();
        
        // 2. Determine action (move, act, menu, etc.) -- implement this function:
      int action = get_action(inputs);
        
        // 3. Update game -- implement this function:
      int result = update_game(action);
        
        // 3b. Check for game over based on result
        // and if so, handle game over -- implement this.
                
        // 4. Draw screen -- provided:
      draw_game(result);
        
        // Compute update time
      t.stop();
      int dt = t.read_ms();
   
        // Display and wait
        // NOTE: Text is 8 pixels tall
      if (dt < 100) wait_ms(100 - dt);
   }
}

int main2() {
    // First things first: initialize hardware
   ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
    
   snake_init(&snake);
    // 0. Initialize the maps -- implement this function:
   maps_init();
    

    
   //init_main_map();
   init_map_2();
    

    // Initialize game state
   set_active_map(0);
   snake.head_x = snake.head_y = 5;
   snake.body_x = 4;
   snake.body_y = 5;
   snake.tail_x = 3;
   snake.tail_y = 5;
   //snake.length = bodyLength;
    // Initial drawing
   draw_game(FULL_DRAW);
    // Main game loop
   while(1) {
        // Timer to measure game update speed
      Timer t;
      t.start();
   
        // 1. Read inputs -- implement this function:
      GameInputs inputs = read_inputs();
        
        // 2. Determine action (move, act, menu, etc.) -- implement this function:
      int action = get_action(inputs);
        
        // 3. Update game -- implement this function:
      int result = update_game(action);
        
        // 3b. Check for game over based on result
        // and if so, handle game over -- implement this.
                
        // 4. Draw screen -- provided:
      draw_game(result);
        
        // Compute update time
      t.stop();
      int dt = t.read_ms();
   
        // Display and wait
        // NOTE: Text is 8 pixels tall
      if (dt < 100) wait_ms(100 - dt);
   }

}

// Plays a wavfile
void playSound(char* wav)
{
    
}