P2-2 Harris Barton

Dependencies:   mbed wave_player 4DGL-uLCD-SE MMA8452

Files at this revision

API Documentation at this revision

Comitter:
hbarton7
Date:
Wed Nov 25 01:17:39 2020 +0000
Parent:
2:4947d6a82971
Commit message:
P2-2 Harris Barton;

Changed in this revision

Speaker.h Show annotated file Show diff for this revision Revisions of this file
graphics.cpp Show annotated file Show diff for this revision Revisions of this file
graphics.h Show annotated file Show diff for this revision Revisions of this file
hardware.cpp Show annotated file Show diff for this revision Revisions of this file
hash_table.cpp Show annotated file Show diff for this revision Revisions of this file
hash_table.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
map.cpp Show annotated file Show diff for this revision Revisions of this file
map.h 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Speaker.h	Wed Nov 25 01:17:39 2020 +0000
@@ -0,0 +1,19 @@
+#include "mbed.h"
+// new class to play a note on Speaker based on PwmOut class
+class Speaker
+{
+public:
+    Speaker(PinName pin) : _pin(pin) {
+// _pin(pin) means pass pin to the Speaker Constructor
+    }
+// class method to play a note based on PwmOut class
+    void PlayNote(float frequency, float duration, float volume) {
+        _pin.period(1.0/frequency);
+        _pin = volume/2.0;
+        wait(duration);
+        _pin = 0.0;
+    }
+
+private:
+    PwmOut _pin;
+};
\ No newline at end of file
--- a/graphics.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/graphics.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -8,6 +8,150 @@
 
 #include "globals.h"
 
+#define YELLOW 0xFFFF00
+#define BROWN  0xD2691E
+#define DIRT   BROWN
+
+const char head[121] = {
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','R','R','R','G','G','R','R','R','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    };
+ 
+const char tail[121] = {
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','Y','Y','Y','G','G','G','Y','Y','Y','G',
+    'G','Y','Y','Y','G','G','G','Y','Y','Y','G',
+    'G','Y','Y','Y','G','G','G','Y','Y','Y','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    'G','Y','Y','Y','G','G','Y','Y','Y','G','G',
+    'G','Y','Y','Y','G','G','Y','Y','Y','G','G',
+    'G','Y','Y','Y','G','G','Y','Y','Y','G','G',
+    'G','G','G','G','G','G','G','G','G','G','G',
+    }; 
+    
+const char poison[121] = {
+    'Y','3','3','3','3','3','3','3','3','3','Y',
+    '3','Y','3','3','3','3','3','3','3','Y','3',
+    '3','3','Y','3','3','3','3','3','Y','3','3',
+    '3','3','3','Y','3','3','3','Y','3','3','3',
+    '3','3','3','3','Y','3','Y','3','3','3','3',
+    '3','3','3','3','3','Y','3','3','3','3','3',
+    '3','3','3','3','Y','3','Y','3','3','3','3',
+    '3','3','3','Y','3','3','3','Y','3','3','3',
+    '3','3','Y','3','3','3','3','3','Y','3','3',
+    '3','Y','3','3','3','3','3','3','3','Y','3',
+    'Y','3','3','3','3','3','3','3','3','3','Y',
+    }; 
+    
+const char speedup[121] = {
+    '3','3','3','3','3','G','3','3','3','3','3',
+    '3','3','3','3','G','3','G','3','3','3','3',
+    '3','3','3','G','3','3','3','G','3','3','3',
+    '3','3','G','3','3','3','3','3','G','3','3',
+    '3','G','3','3','3','3','3','3','3','G','3',
+    'G','3','3','3','3','3','3','3','3','3','G',
+    '3','3','3','3','3','G','3','3','3','3','3',
+    '3','3','3','3','G','3','G','3','3','3','3',
+    '3','3','3','G','3','3','3','G','3','3','3',
+    '3','3','G','3','3','3','3','3','G','3','3',
+    '3','G','3','3','3','3','3','3','3','G','3',
+    }; 
+    
+const char slowdown[121] = {
+    'G','3','3','3','3','3','3','3','3','3','G',
+    '3','G','3','3','3','3','3','3','3','G','3',
+    '3','3','G','3','3','3','3','3','G','3','3',
+    '3','3','3','G','3','3','3','G','3','3','3',
+    '3','3','3','3','G','3','G','3','3','3','3',
+    '3','3','3','3','3','G','3','3','3','3','3',
+    'G','3','3','3','3','3','3','3','3','3','G',
+    '3','G','3','3','3','3','3','3','3','G','3',
+    '3','3','G','3','3','3','3','3','G','3','3',
+    '3','3','3','G','3','3','3','G','3','3','3',
+    '3','3','3','3','G','3','G','3','3','3','3',
+    }; 
+    
+const char decrease_length[121] = {
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','Y','Y','3','3','3','3','3',
+    '3','3','3','Y','3','3','Y','Y','Y','3','3',
+    '3','3','3','Y','3','3','Y','3','3','3','3',
+    '3','3','3','3','Y','Y','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    '3','3','3','3','3','3','3','3','3','3','3',
+    }; 
+    
+const char random[121] = {
+    '5','5','5','5','5','G','5','5','5','5','5',
+    '5','5','5','5','G','5','G','5','5','5','5',
+    '5','5','5','G','5','5','5','G','5','5','5',
+    '5','5','5','5','5','5','5','G','5','5','5',
+    '5','5','5','5','5','5','5','G','5','5','5',
+    '5','5','5','5','5','5','G','5','5','5','5',
+    '5','5','5','5','5','G','5','5','5','5','5',
+    '5','5','5','5','5','G','5','5','5','5','5',
+    '5','5','5','5','5','G','5','5','5','5','5',
+    '5','5','5','5','5','5','5','5','5','5','5',
+    '5','5','5','5','5','G','5','5','5','5','5',
+    }; 
+    
+const char moving[121] = {
+    '5','5','5','5','5','D','5','5','5','5','5',
+    '5','5','5','5','D','5','D','5','5','5','5',
+    '5','5','5','D','5','5','5','D','5','5','5',
+    '5','5','5','5','5','5','5','D','5','5','5',
+    '5','5','5','5','5','5','5','D','5','5','5',
+    '5','5','5','5','5','5','D','5','5','5','5',
+    '5','5','5','5','5','D','5','5','5','5','5',
+    '5','5','5','5','5','D','5','5','5','5','5',
+    '5','5','5','5','5','D','5','5','5','5','5',
+    '5','5','5','5','5','5','5','5','5','5','5',
+    '5','5','5','5','5','D','5','5','5','5','5',
+    }; 
+    
+const char invinc[121] = {
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    'R','R','R','R','R','R','R','R','R','R','R',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    '3','3','3','3','3','R','3','3','3','3','3',
+    }; 
+    
+const char megaGoodie[121] = {
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y',
+    }; 
+    
 void draw_nothing(int u, int v)
 {
     uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
@@ -32,7 +176,7 @@
 
 void draw_wall(int u, int v)
 {
-    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    uLCD.filled_rectangle(u, v, u+10, v+10, LGREY);
 }
 
 void draw_plant(int u, int v)
@@ -42,7 +186,7 @@
 
 void draw_goodie(int u, int v)
 {
-    uLCD.filled_rectangle(u, v, u+10, v+10, GREEN);
+    uLCD.filled_rectangle(u, v, u+10, v+10, 0xD2691E); //DIRT
 }
 
 void draw_snake_body(int u, int v)
@@ -54,15 +198,66 @@
 {
      //May need to design a snake head sprite
      //Tile still need to be designed on paper
-
+    
     uLCD.filled_rectangle(u, v, u+10, v+10, GREEN);
+    draw_img(u,v, head);
+//    uLCD.filled_rectangle(u+1, v+1, u+3, v+3, RED);
+//    uLCD.filled_rectangle(u+7, v+1, u+9, v+3, RED);
+//    uLCD.filled_rectangle(u+1, v+7, u+3, v+9, RED);
+//    uLCD.filled_rectangle(u+7, v+7, u+9, v+9, RED);
+    
 }
 
 void draw_snake_tail(int u, int v)
 {
      //May need to design a snake tail sprite
      //Tile still need to be designed on paper
+    
     uLCD.filled_rectangle(u, v, u+10, v+10, GREEN);
+    draw_img(u,v, tail); 
+//    uLCD.filled_rectangle(u+1, v+1, u+3, v+3, 0xFFFF00); //YELLOW
+//    uLCD.filled_rectangle(u+7, v+1, u+9, v+3, 0xFFFF00);
+//    uLCD.filled_rectangle(u+1, v+7, u+3, v+9, 0xFFFF00);
+//    uLCD.filled_rectangle(u+7, v+7, u+9, v+9, 0xFFFF00);
+}
+
+void draw_poison(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, poison);
+}
+
+void draw_speedup(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, speedup);
+}
+
+void draw_slowdown(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, slowdown);
+}
+
+void draw_decrease_length(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, decrease_length);
+}
+
+void draw_random(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, random);
+}
+
+void draw_moving(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, moving);
+}
+
+void draw_invinc(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, invinc);
+}
+void draw_megaGoodie(int u, int v) {
+    uLCD.filled_rectangle(u, v, u+10, v+10, BLACK);
+    draw_img(u, v, megaGoodie);
 }
 
 
--- a/graphics.h	Fri Oct 23 16:30:18 2020 -0400
+++ b/graphics.h	Wed Nov 25 01:17:39 2020 +0000
@@ -34,6 +34,15 @@
 void draw_snake_body(int u, int v);
 void draw_snake_head(int u, int v);
 void draw_snake_tail(int u, int v);
+//new buffs/debuffs/extra stuff below
+void draw_poison(int u, int v);
+void draw_speedup(int u, int v);
+void draw_slowdown(int u, int v);
+void draw_decrease_length(int u, int v);
+void draw_random(int u, int v);
+void draw_moving(int u, int v);
+void draw_invinc(int u, int v);
+void draw_megaGoodie(int u, int v);
 
 
 #endif // GRAPHICS_H
\ No newline at end of file
--- a/hardware.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/hardware.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -29,6 +29,7 @@
 
 // Some hardware also needs to have functions called before it will set up
 // properly. Do that here.
+
 int hardware_init()
 {
     // Crank up the speed
@@ -49,5 +50,19 @@
 GameInputs read_inputs() 
 {
     GameInputs in;
+
+    // Read the values and store them in in
+    //tilting board left = -x
+    //tilting board down towards table = +y
+
+    in.b1 = button3; //top button on breadboard is  connected to p23
+    in.b2 = button2; //middle button on breadboard is  connected to p22
+    in.b3 = button1; //bottom button ob breadboard is  connected to p21
+    
+    acc.readXGravity(&in.ax);
+    acc.readYGravity(&in.ay);
+    acc.readZGravity(&in.az);
+    
+    //pc.printf("xAccel: %f   yAccel: %f   zAccel: %f\n",in.ax,in.ay,in.az);
     return in;
 }
--- a/hash_table.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/hash_table.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -1,55 +1,3 @@
-// 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.
-/*
- Student Name:
- Date:
- 
-=======================
-ECE 2035 Project 2-1:
-=======================
-This file provides definition for the structs and functions declared in the
-header file. It also contains helper functions that are not accessible from
-outside of the file.
- 
-FOR FULL CREDIT, BE SURE TO TRY MULTIPLE TEST CASES and DOCUMENT YOUR CODE.
- 
-===================================
-Naming conventions in this file:
-===================================
-1. All struct names use camel case where the first letter is capitalized.
-  e.g. "HashTable", or "HashTableEntry"
- 
-2. Variable names with a preceding underscore "_" will not be called directly.
-  e.g. "_HashTable", "_HashTableEntry"
- 
-  Recall that in C, we have to type "struct" together with the name of the struct
-  in order to initialize a new variable. To avoid this, in hash_table.h
-  we use typedef to provide new "nicknames" for "struct _HashTable" and
-  "struct _HashTableEntry". As a result, we can create new struct variables
-  by just using:
-    - "HashTable myNewTable;"
-     or
-    - "HashTableEntry myNewHashTableEntry;"
- 
-  The preceding underscore "_" simply provides a distinction between the names
-  of the actual struct defition and the "nicknames" that we use to initialize
-  new structs.
-  [See Hidden Definitions section for more information.]
- 
-3. Functions, their local variables and arguments are named with camel case, where
-  the first letter is lower-case.
-  e.g. "createHashTable" is a function. One of its arguments is "numBuckets".
-       It also has a local variable called "newTable".
- 
-4. The name of a struct member is divided by using underscores "_". This serves
-  as a distinction between function local variables and struct members.
-  e.g. "num_buckets" is a member of "HashTable".
- 
-*/
- 
 /****************************************************************************
 * Include the Public Interface
 *
@@ -59,8 +7,8 @@
 * correctness, but it is better than nothing!
 ***************************************************************************/
 #include "hash_table.h"
- 
- 
+
+
 /****************************************************************************
 * Include other private dependencies
 *
@@ -69,8 +17,8 @@
 ***************************************************************************/
 #include <stdlib.h>   // For malloc and free
 #include <stdio.h>    // For printf
- 
- 
+
+
 /****************************************************************************
 * Hidden Definitions
 *
@@ -80,39 +28,37 @@
 ***************************************************************************/
 /**
  * This structure represents an a hash table.
- * Use "HashTable" instead when you are creating a new variable. [See top comments]
  */
 struct _HashTable {
   /** The array of pointers to the head of a singly linked list, whose nodes
       are HashTableEntry objects */
   HashTableEntry** buckets;
- 
+
   /** The hash function pointer */
   HashFunction hash;
- 
+
   /** The number of buckets in the hash table */
   unsigned int num_buckets;
 };
- 
+
 /**
  * This structure represents a hash table entry.
- * Use "HashTableEntry" instead when you are creating a new variable. [See top comments]
  */
 struct _HashTableEntry {
   /** The key for the hash table entry */
   unsigned int key;
- 
+
   /** The value associated with this hash table entry */
   void* value;
- 
+
   /**
   * A pointer pointing to the next hash table entry
   * NULL means there is no next entry (i.e. this is the tail)
   */
   HashTableEntry* next;
 };
- 
- 
+
+
 /****************************************************************************
 * Private Functions
 *
@@ -131,23 +77,39 @@
 * @return The pointer to the hash table entry
 */
 static HashTableEntry* createHashTableEntry(unsigned int key, void* value) {
- 
+  // Create an initialize a new hash table entry.
+  HashTableEntry* newEntry = (HashTableEntry*)malloc(sizeof(HashTableEntry));
+  newEntry->key = key;
+  newEntry->value = value;
+  newEntry->next = NULL;
+
+  return newEntry;
 }
- 
+
 /**
 * findItem
 *
 * Helper function that checks whether there exists the hash table entry that
 * contains a specific key.
 *
-* @param hashTable The pointer to the hash table.
+* @param myHashTable The pointer to the hash table.
 * @param key The key corresponds to the hash table entry
 * @return The pointer to the hash table entry, or NULL if key does not exist
 */
-static HashTableEntry* findItem(HashTable* hashTable, unsigned int key) {
- 
+static HashTableEntry* findItem(HashTable* myHashTable, unsigned int key) {
+  unsigned int bucketNum = myHashTable->hash(key);  // Get the bucket number.
+  HashTableEntry* temp = myHashTable->buckets[bucketNum]; // Get the head entry.
+
+  if (temp == NULL) return NULL;  // If there's nothing in the bucket, return NULL.
+
+  while (temp!=NULL) {
+    if (temp->key==key) return temp; // Return the hash table entry if the key is found.
+    temp = temp->next;  // Otherwise, move to next node.
+  }
+
+  return NULL;  // Return NULL if key is not present.
 }
- 
+
 /****************************************************************************
 * Public Interface Functions
 *
@@ -155,48 +117,117 @@
 * file, and make use of the private functions and hidden definitions in the
 * above sections.
 ****************************************************************************/
-// The createHashTable is provided for you as a starting point.
-HashTable* createHashTable(HashFunction hashFunction, unsigned int numBuckets) {
+HashTable* createHashTable(HashFunction myHashFunc, unsigned int numBuckets) {
   // The hash table has to contain at least one bucket. Exit gracefully if
   // this condition is not met.
   if (numBuckets==0) {
     printf("Hash table has to contain at least 1 bucket...\n");
     exit(1);
   }
- 
+
   // Allocate memory for the new HashTable struct on heap.
   HashTable* newTable = (HashTable*)malloc(sizeof(HashTable));
- 
+
   // Initialize the components of the new HashTable struct.
-  newTable->hash = hashFunction;
+  newTable->hash = myHashFunc;
   newTable->num_buckets = numBuckets;
   newTable->buckets = (HashTableEntry**)malloc(numBuckets*sizeof(HashTableEntry*));
- 
-  // As the new buckets are empty, init each bucket as NULL.
+
+  // As the new buckets contain indeterminant values, init each bucket as NULL.
   unsigned int i;
   for (i=0; i<numBuckets; ++i) {
     newTable->buckets[i] = NULL;
   }
- 
-  // Return the new HashTable struct.
+
+  // Return the newly created hash table.
   return newTable;
 }
- 
-void destroyHashTable(HashTable* hashTable) {
- 
+
+void destroyHashTable(HashTable* myHashTable) {
+  unsigned int i;
+  HashTableEntry* temp;
+  HashTableEntry* next;
+
+  // Loop through each bucket of the hash table to remove all items.
+  for (i=0; i<myHashTable->num_buckets; ++i) {
+     temp = myHashTable->buckets[i];  // set temp to be the first entry of the ith bucket
+
+    // delete all entries
+    while (temp != NULL) {
+      next = temp->next;
+      free(temp->value);
+      free(temp);
+      temp = next;
+    }
+  }
+
+  // free buckets
+  free(myHashTable->buckets);
+
+  // free hash table
+  free(myHashTable);
 }
- 
-void* insertItem(HashTable* hashTable, unsigned int key, void* value) {
+
+void* insertItem(HashTable* myHashTable, unsigned int key, void* value) {
+  // First, we want to check if the key is present in the hash table.
+  HashTableEntry* temp = findItem(myHashTable, key);
+
+  if (temp) {
+    // The key is present in the hash table.
+    void* oldValue = temp->value;
+    temp->value = value;
+    return oldValue;
+  } else {
+    // The key is not present in the hash table.
+    temp = createHashTableEntry(key, value);
+    temp->next = myHashTable->buckets[myHashTable->hash(key)];
+    myHashTable->buckets[myHashTable->hash(key)] = temp;
+    return NULL;  // Return NULL as nothing is overwritten.
+  }
 }
- 
-void* getItem(HashTable* hashTable, unsigned int key) {
- 
+
+void* getItem(HashTable* myHashTable, unsigned int key) {
+  // First, we want to check if the key is present in the hash table.
+  HashTableEntry* temp = findItem(myHashTable, key);
+
+  if (temp) // if the key exists
+    return temp->value;
+  else  // return NULL if the key does not exist
+    return NULL;
 }
- 
-void* removeItem(HashTable* hashTable, unsigned int key) {
- 
+
+void* removeItem(HashTable* myHashTable, unsigned int key) {
+  // Reference: https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/
+  unsigned int bucketNum = myHashTable->hash(key);  // get the bucket number
+  HashTableEntry* temp = myHashTable->buckets[bucketNum]; // get the head entry
+  HashTableEntry* prev;
+
+  // If head holds the key
+  if (temp != NULL && temp->key == key) {
+    myHashTable->buckets[bucketNum] = temp->next;  // Change head
+    void* oldValue = temp->value; // hold the old value
+    free(temp);
+    return oldValue;
+  }
+
+  // Search for the key to be removed
+  while (temp != NULL && temp->key != key) {
+    prev = temp;
+    temp = temp->next;
+  }
+
+  // If the key is not present in the list
+  if (temp == NULL) return NULL;
+
+  // Unlink the node from list
+  prev->next = temp->next;
+  void* oldValue = temp->value; // hold the old value
+  free(temp);
+
+  return oldValue;
 }
- 
-void deleteItem(HashTable* hashTable, unsigned int key) {
- 
+
+void deleteItem(HashTable* myHashTable, unsigned int key) {
+  // remove the entry and free the returned data
+  free(removeItem(myHashTable, key));
 }
\ No newline at end of file
--- a/hash_table.h	Fri Oct 23 16:30:18 2020 -0400
+++ b/hash_table.h	Wed Nov 25 01:17:39 2020 +0000
@@ -1,8 +1,10 @@
+//=================================================================
 // 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.
+//=================================================================
 
 /****************************************************************************
  * Include guards
@@ -130,4 +132,4 @@
  */
 void deleteItem(HashTable* myHashTable, unsigned int key);
 
-#endif
\ No newline at end of file
+#endif
--- a/main.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/main.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -7,36 +7,46 @@
 // 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 "mbed.h"
+#include "Speaker.h"
 
+ 
+//#include "wave_player.h"
+#include "SDFileSystem.h"
 #include <math.h>
 #include<stdio.h>
-
+ 
 #define CITY_HIT_MARGIN 1
 #define CITY_UPPER_BOUND (SIZE_Y-(LANDSCAPE_HEIGHT+MAX_BUILDING_HEIGHT))
-
+int go_right(int x, int y);
+int go_left(int x, int y);
+int go_up(int x, int y);
+int go_down(int x, int y);
 // Helper function declarations
 void playSound(char* wav);
-
+ 
+ 
+Speaker mySpeaker(p26);
 /**
  * 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;
-
+ 
 // Function prototypes
-
+ 
 /**
  * Given the game inputs, determine what kind of update needs to happen.
  * Possible return values are defined below.
@@ -51,13 +61,114 @@
 #define GO_DOWN 6
 #define GAME_OVER 7
 #define FULL_DRAW 8
+#define WON 9
+#define FOODN 10
+#define FOODS 11
+#define FOODW 12
+#define FOODE 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)
 {
-    return 0;
+    MapItem* N=get_north(snake.head_x,snake.head_y);
+    MapItem* S=get_south(snake.head_x,snake.head_y);
+    MapItem* W=get_east(snake.head_x, snake.head_y);
+    MapItem* E=get_west(snake.head_x, snake.head_y);
+    
+    
+    if(button3 == 0){
+        while(button3 == 0)
+        {}
+        }
+    
+    if (button2 == 0) {
+        if (snake.invincTimer == 0)
+            snake.invincible = !snake.invincible;
+        else
+            snake.invincible = 1;
+    }
+    if ((E->type==WALL || N->type==WALL || S->type==WALL ||W->type==WALL) && !snake.invincible)   return GAME_OVER;
+    if (inputs.ay >= 0.20) return GO_DOWN;
+    if (inputs.ay < -0.20) return GO_UP;
+    if (inputs.ax < -0.20) return GO_RIGHT;
+    if (inputs.ax >= 0.20) return GO_LEFT;
+    else return NO_ACTION;
 }
+ 
+void checkCollisions() {
+    //Check Objects here
+    if (get_here(snake.head_x,snake.head_y)->type == RANDOM) {
+        void* d = get_here(snake.head_x,snake.head_y)->data;
+        if (((int)d % 4) + 13 == 13)
+            snake.pointLockTime = 10000;
+        if (((int)d % 4) + 13  == 14)
+            snake.speedupTime = 10000;
+        if (((int)d % 4) + 13  == 15)
+            snake.slowdownTime = 10000;
+        if (((int)d % 4) + 13  == 16) {
+            if (snake.length > 1) {
+            map_erase(snake.locations[snake.length - 2].x, snake.locations[snake.length - 2].y);
+            map_erase(snake.locations[snake.length - 1].x, snake.locations[snake.length - 1].y);
+            snake.length -= 2;
+            }
+        }
+        else
+            snake.pointLockTime = 10000;
+        return;
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == INVINC) {
+        snake.invincTimer = 10000;
+        snake.invincible = 1;
+    }
+    
+    //Check Goodie
+    
+    if (get_here(snake.head_x,snake.head_y)->type == GOODIE) {
+        snake.length++;
+        mySpeaker.PlayNote(440.0,2,0.3);
+        if (snake.pointLockTime == 0) //If snake hasn't hit poison in last 10 sec
+            snake.score++;
+    }
+    
+    
+    if (get_here(snake.head_x,snake.head_y)->type == MEGAGOODIE) {
+        snake.length += 3;
+        mySpeaker.PlayNote(440.0,2,0.3);
+        if (snake.pointLockTime == 0) //If snake hasn't hit poison in last 10 sec
+            snake.score += 3;
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == MOVING) {
+        snake.score += 10;
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == POISON) {
+        mySpeaker.PlayNote(65.0,2,0.3);
+        snake.pointLockTime += 10000; //10 sec
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == SPEEDUP) {
+        mySpeaker.PlayNote(65.0,0.2,0.3);
+        snake.speedupTime += 10000; //10 sec
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == SLOWDOWN) {
+        snake.slowdownTime += 10000; //10 sec
+    }
+    
+    if (get_here(snake.head_x,snake.head_y)->type == DECLENGTH) {
+        if (snake.length > 1) {
+            map_erase(snake.locations[snake.length - 2].x, snake.locations[snake.length - 2].y);
+            map_erase(snake.locations[snake.length - 1].x, snake.locations[snake.length - 1].y);
+            snake.length -= 2;
+        }
+            
+    }
+}
+ 
 /**
  * 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
@@ -69,17 +180,204 @@
  */
 int update_game(int action)
 {
-    return 0;
+     
+   snake.head_px = snake.head_x;
+   snake.head_py = snake.head_y;   
+   
+   int oldx = snake.head_px;
+   int oldy = snake.head_py;
+   
+   map_erase(oldx, oldy);
+    
+    switch(action) {
+        case GO_UP:
+                snake.head_y -= 1;  
+                
+                checkCollisions();
+                //Check un-walkable object
+                if (get_here(snake.head_x, snake.head_y)->type != SNAKE_HEAD &&
+                get_here(snake.head_x, snake.head_y)->walkable == 0
+                && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+                //Add snake head now
+                add_snake_head(snake.head_x, snake.head_y);
+                //Check max length
+                if (snake.length == SNAKE_MAX_LENGTH && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+            for (int i = 0; i < snake.length; i++) {
+                map_erase(oldx, oldy);
+                int tempy = snake.locations[i].y;
+                snake.locations[i].y = oldy;
+                
+                int tempx = snake.locations[i].x;
+                snake.locations[i].x = oldx;
+                
+                oldy = tempy;
+                oldx = tempx;
+                map_erase(oldx, oldy);
+                
+                if (i < snake.length - 1)
+                    add_snake_body(snake.locations[i].x, snake.locations[i].y);
+                else
+                    add_snake_tail(snake.locations[i].x, snake.locations[i].y);
+            } 
+                 return ACTION_BUTTON;
+        case GO_LEFT:
+               snake.head_x -= 1;  
+               
+               checkCollisions();
+               
+               //Check un-walkable object
+                if (get_here(snake.head_x, snake.head_y)->type != SNAKE_HEAD &&
+                get_here(snake.head_x, snake.head_y)->walkable == 0
+                && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+                
+               add_snake_head(snake.head_x, snake.head_y);
+               //Check max length
+                if (snake.length == SNAKE_MAX_LENGTH && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+            for (int i = 0; i < snake.length; i++) {
+                map_erase(oldx, oldy);
+                int tempy = snake.locations[i].y;
+                snake.locations[i].y = oldy;
+                
+                int tempx = snake.locations[i].x;
+                snake.locations[i].x = oldx;
+                
+                oldy = tempy;
+                oldx = tempx;
+                map_erase(oldx, oldy);
+                
+                if (i < snake.length - 1)
+                    add_snake_body(snake.locations[i].x, snake.locations[i].y);
+                else
+                    add_snake_tail(snake.locations[i].x, snake.locations[i].y);
+            } 
+                 return ACTION_BUTTON;
+        case GO_DOWN:
+                snake.head_y += 1;  
+                
+                checkCollisions();
+                
+                //Check un-walkable object
+                if (get_here(snake.head_x, snake.head_y)->type != SNAKE_HEAD &&
+                get_here(snake.head_x, snake.head_y)->walkable == 0
+                && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+                
+                add_snake_head(snake.head_x, snake.head_y);
+                //Check max length
+                if (snake.length == SNAKE_MAX_LENGTH && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+            for (int i = 0; i < snake.length; i++) {
+                int tempy = snake.locations[i].y;
+                snake.locations[i].y = oldy;
+                
+                int tempx = snake.locations[i].x;
+                snake.locations[i].x = oldx;
+                
+                oldy = tempy;
+                oldx = tempx;
+                map_erase(oldx, oldy);
+                
+                if (i < snake.length - 1)
+                    add_snake_body(snake.locations[i].x, snake.locations[i].y);
+                else
+                    add_snake_tail(snake.locations[i].x, snake.locations[i].y);
+            }         
+                 return ACTION_BUTTON;
+                 
+        case GO_RIGHT:
+               snake.head_x += 1;  
+               
+               checkCollisions();
+               
+               //Check un-walkable object
+                if (get_here(snake.head_x, snake.head_y)->type != SNAKE_HEAD &&
+                get_here(snake.head_x, snake.head_y)->walkable == 0
+                && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+                
+               add_snake_head(snake.head_x, snake.head_y);
+               //Check max length
+                if (snake.length == SNAKE_MAX_LENGTH && !snake.invincible) {
+                    action = GAME_OVER;
+                    break;
+                }
+            for (int i = 0; i < snake.length; i++) {
+                int tempy = snake.locations[i].y;
+                snake.locations[i].y = oldy;
+                
+                int tempx = snake.locations[i].x;
+                snake.locations[i].x = oldx;
+                
+                oldy = tempy;
+                oldx = tempx;
+                map_erase(oldx, oldy);
+                
+                if (i < snake.length - 1)
+                    add_snake_body(snake.locations[i].x, snake.locations[i].y);
+                else
+                    add_snake_tail(snake.locations[i].x, snake.locations[i].y);
+            } 
+                return ACTION_BUTTON;
+           
+        case GAME_OVER:
+            {uLCD.color(RED);
+            uLCD.cls();
+            uLCD.text_width(3);
+            uLCD.text_height(3);
+            uLCD.printf("GAME\nOVER");
+            uLCD.color(GREEN);
+            uLCD.text_width(1);
+            uLCD.text_height(1);
+            uLCD.printf("\n\n\n\n\nScore %d", snake.score);
+            uLCD.color(GREEN);}
+            while(1 == 1);
+            }
+ 
+    if (action == GAME_OVER) {
+            uLCD.color(RED);
+            uLCD.cls();
+            uLCD.text_width(3);
+            uLCD.text_height(3);
+            uLCD.printf("GAME\nOVER");
+            uLCD.color(GREEN);
+            uLCD.text_width(1);
+            uLCD.text_height(1);
+            uLCD.printf("\n\n\n\n\nScore %d", snake.score);
+            uLCD.color(GREEN);
+            while(1 == 1);
+        }
+        
+    return NO_RESULT;
+    
 }
-
+ 
 /**
  * Draw the upper status bar.
  */
 void draw_upper_status()
 {
     uLCD.line(0, 9, 127, 9, GREEN);
+ 
 }
-
+ 
 /**
  * Draw the lower status bar.
  */
@@ -87,7 +385,7 @@
 {
     uLCD.line(0, 118, 127, 118, GREEN);
 }
-
+ 
 /**
  * Draw the border for the map.
  */
@@ -98,7 +396,7 @@
     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
@@ -107,34 +405,56 @@
  */
 void draw_game(int draw_option)
 {
+    uLCD.locate(0, 0);
+    uLCD.text_width(1);
+    uLCD.text_height(1);
+    uLCD.printf("Score %d", snake.score);
+    uLCD.color(GREEN);
+    
+    uLCD.locate(8, 0);
+    uLCD.text_width(1);
+    uLCD.text_height(1);
+    uLCD.printf("Loc: %d,%d ", snake.head_x, snake.head_y);
+    uLCD.color(GREEN);
+    
     // Draw game border first
-    if(draw_option == FULL_DRAW) 
-    {
+    if(draw_option == FULL_DRAW) {
         draw_border();
         int u = 58;
-        int v = 56;
+        int v = 59;
         draw_snake_head(u, v);
         draw_snake_body(u-11, v);
         draw_snake_tail(u-22, v);
-        return;
+        int i = 1;
+        for (; i < snake.length; i++) {
+            int x = u - (11 * (snake.head_x - snake.locations[i].x));
+            int y = v - (11 * (snake.head_y - snake.locations[i].y));
+            if (i < snake.length - 1) {
+                add_snake_body(snake.locations[i].x, snake.locations[i].y);
+                draw_snake_body(x, y);
+            }
+            else {
+                add_snake_tail(snake.locations[i].x, snake.locations[i].y);
+                draw_snake_tail(x, y);
+            }
+        }
     }
+    
     // 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
@@ -153,30 +473,37 @@
             } 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();
     draw_lower_status();
 }
-
+ 
 /**
  * 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()
 {
+    Timer t;
+    t.start();
+    uLCD.text_width(1);
+    uLCD.text_height(1);
+    uLCD.printf("Score %d", snake.score);
+    uLCD.color(GREEN);
     // "Random" plants
     Map* map = set_active_map(0);
     for(int i = map_width() + 3; i < map_area(); i += 39) {
         add_goodie(i % map_width(), i / map_width());
     }
+    
     pc.printf("plants\r\n");
-
+ 
     pc.printf("Adding walls!\r\n");
     add_wall(0,              0,              HORIZONTAL, map_width());
     add_wall(0,              map_height()-1, HORIZONTAL, map_width());
@@ -193,15 +520,41 @@
     add_wall(30, 10, HORIZONTAL, 10);
     add_wall(39, 0, VERTICAL, 10);
     pc.printf("Added!\r\n");
-
-
+ 
+    //ADD POISON, ANY OTHER BUFFS/DEBUFFS HERE!!*******************************************************
+    //Buffs: Decrement length, Slow (slows time)
+    //Debuffs: Poison (prevents gaining points for certain time), Speedup thing (literally just 1.5x time or something), 
+    //Extra:  Random, Strength (prevent death once or something), Pause button (just pause time), Moving object, multiple lives
+    //Also: Button or sprite to invert controls
+   for(int i = map_width() + 8; i < map_area(); i += 31) {
+        add_poison(i % map_width() + 4, i / map_width());
+    }
+    
+    
+   for(int i = map_width() + 8; i < map_area(); i += 32) {
+        add_megaGoodie(i % map_width() + 4, i / map_width());
+    }
+    
+    
+   for(int i = map_width() + 8; i < map_area(); i += 44) {
+        add_speedup(i % map_width() + 4, i / map_width());
+    }
+    
+   for(int i = map_width() + 8; i < map_area(); i += 52) {
+        add_slowdown(i % map_width() + 4, i / map_width());
+    }
+    
+       for(int i = map_width() + 8; i < map_area(); i += 64) {
+        add_decrease_length(i % map_width() + 4, i / map_width());
+    }
+    
     // Add stairs to chamber (map 1)
     //add_stairs(15, 5, 1, 5, 5);
-
+ 
 //    profile_hashtable();
     print_map();
 }
-
+ 
 /**
  * Program entry point! This is where it all begins.
  * This function or all the parts of the game. Most of your
@@ -212,15 +565,17 @@
 {
     // 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();
-
+     playSound("/sd/wavfiles/track.wav");
+ 
     // Initialize game state
     set_active_map(0);
-    snake.head_x = snake.head_y = 5;
+    //snake.head_x = snake.head_y = 5 ;
+    
     // Initial drawing
     draw_game(FULL_DRAW);
     // Main game loop
@@ -228,7 +583,7 @@
         // Timer to measure game update speed
         Timer t;
         t.start();
-
+ 
         // 1. Read inputs -- implement this function:
         GameInputs inputs = read_inputs();
         
@@ -247,15 +602,61 @@
         // Compute update time
         t.stop();
         int dt = t.read_ms();
-
+        
+        //Add boolean on snake, check boolean, make dt 75 instead of 100. Boom, speedup debuff.
+        //Do same thing for slow buff essentially.
+        if (dt % 8 == 0 || dt % 8 == 1) {
+            map_erase(5, 5);
+            add_moving(45, 45);
+        }
+        else if (dt % 8 == 2 || dt % 8 == 3) {
+            map_erase(45, 45);
+            add_moving(5, 45);
+        }
+        else if (dt % 8 == 4 || dt % 8 == 5) {
+            map_erase(5, 45);
+            add_moving(45, 5);
+        }
+        else {
+            map_erase(45, 5);
+            add_moving(5, 5);
+        }
+        
+        if (snake.invincTimer > 0) {
+            snake.invincTimer -= 100;
+            if (snake.invincTimer == 0)
+                snake.invincible = 0;
+        }
+        
         // Display and wait
         // NOTE: Text is 8 pixels tall
-        if (dt < 100) wait_ms(100 - dt);
+        if (snake.speedupTime > 0 && snake.slowdownTime > 0) {
+            if (dt < 100) wait_ms(100 - dt);
+            snake.speedupTime -= 100;
+            snake.slowdownTime -= 100;
+        }
+        else if (snake.speedupTime > 0) {
+            if (dt < 80) wait_ms(80 - dt);
+            snake.speedupTime -= 100;
+        }
+        else if (snake.slowdownTime > 0) {
+            if (dt < 125) wait_ms(125 - dt);
+            snake.slowdownTime -= 100;
+        }
+        else
+            if (dt < 100) wait_ms(100 - dt);
+        
+        //Subtract from point lock time, if it's on
+        if (snake.pointLockTime > 0) 
+            snake.pointLockTime -= 100;
+            
     }
 }
-
+ 
 // Plays a wavfile
 void playSound(char* wav)
 {
-    
-}
\ No newline at end of file
+   
+}
+ 
+            
\ No newline at end of file
--- a/map.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/map.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -19,6 +19,8 @@
 };
 
 #define NUM_MAPS 1
+#define MAP_WIDTH   50
+#define MAP_HEIGHT  50
 static Map maps[NUM_MAPS];
 static int active_map;
 
@@ -33,7 +35,9 @@
  * This function should uniquely map (x,y) onto the space of unsigned integers.
  */
 static unsigned XY_KEY(int X, int Y) {
-     // TODO: Fix me!
+     
+     return X*maps[0].h + Y;
+     
 }
 
 /**
@@ -43,14 +47,14 @@
  */
 unsigned map_hash(unsigned key)
 {
-    // TODO: Fix me!
+    return key%(NUM_MAPS);
 }
 
 void maps_init()
 {
-    // TODO: Implement!    
-    // Initialize hash table
-    // Set width & height
+    maps[0].items = createHashTable(map_hash, NUM_MAPS);
+    maps[0].w = MAP_WIDTH;
+    maps[0].h = MAP_HEIGHT;
 }
 
 Map* get_active_map()
@@ -82,51 +86,51 @@
 
 int map_width()
 {
-
+    return get_active_map()->w;
 }
 
 int map_height()
 {
-
+    return get_active_map()->h;
 }
 
 int map_area()
 {
-
+    return map_width() * map_height();
 }
-MapItem* get_current(int x, int y)
-{
-    
-}
+
 MapItem* get_north(int x, int y)
 {
-    
+    return get_here(x, y-1);
 }
+
 MapItem* get_south(int x, int y)
 {
-    
+    return get_here(x, y+1);
 }
 
 MapItem* get_east(int x, int y)
 {
-    
+    return get_here(x+1, y);
 }
 
 MapItem* get_west(int x, int y)
 {
-
+    return get_here(x-1, y);
 }
 
 MapItem* get_here(int x, int y)
 {
-
+    return (MapItem*) getItem(get_active_map()->items, XY_KEY(x, y));
 }
 
 void map_erase(int x, int y)
 {
-
+    MapItem* item = get_here(x, y);
+    if (item && item->data)
+        free(item->data);
+    deleteItem(get_active_map()->items, XY_KEY(x, y));
 }
-
 void add_wall(int x, int y, int dir, int len)
 {
     for(int i = 0; i < len; i++)
@@ -189,7 +193,7 @@
 void add_snake_head(int x, int y)
 {
     MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
-    w1->type = SNAKE_BODY;
+    w1->type = SNAKE_HEAD;
     w1->draw = draw_snake_head;
     w1->walkable = false;
     w1->data = NULL;
@@ -207,3 +211,103 @@
     void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
     if (val) free(val); // If something is already there, free it
 }
+
+void add_poison(int x, int y)
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = POISON;
+    w1->draw = draw_poison;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
+
+void add_speedup(int x, int y) 
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = SPEEDUP;
+    w1->draw = draw_speedup;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+    
+}
+
+void add_slowdown(int x, int y) 
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = SLOWDOWN;
+    w1->draw = draw_slowdown;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+    
+}
+
+void add_decrease_length(int x, int y) 
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = DECLENGTH;
+    w1->draw = draw_decrease_length;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+    
+}
+
+void add_random(int x, int y, int d) 
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = RANDOM;
+    w1->draw = draw_random;
+    w1->walkable = true;
+    d = d % 4;
+    w1->data = (int*)(d + 13);
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
+
+void add_moving(int x, int y) {
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = MOVING;
+    w1->draw = draw_moving;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
+
+void add_invinc(int x, int y) {
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = INVINC;
+    w1->draw = draw_invinc;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
+
+void add_megaGoodie(int x, int y)
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = GOODIE;
+    w1->draw = draw_megaGoodie;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
+void add_nothing(int x, int y)
+{
+    MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
+    w1->type = CLEAR;
+    w1->draw = draw_nothing;
+    w1->walkable = true;
+    w1->data = NULL;
+    void* val = insertItem(get_active_map()->items, XY_KEY(x, y), w1);
+    if (val) free(val); // If something is already there, free it
+}
\ No newline at end of file
--- a/map.h	Fri Oct 23 16:30:18 2020 -0400
+++ b/map.h	Wed Nov 25 01:17:39 2020 +0000
@@ -71,6 +71,15 @@
 #define SONAR  9
 #define PUZZLE 10
 #define NPC 11
+#define SNAKE_HEAD   12
+#define POISON   13
+#define SPEEDUP   14
+#define SLOWDOWN   15
+#define DECLENGTH 16
+#define RANDOM 17
+#define MOVING 18
+#define INVINC 19
+#define MEGAGOODIE 20
 
 
 /**
@@ -178,6 +187,16 @@
 void add_snake_body(int x, int y);
 void add_snake_head(int x, int y);
 void add_snake_tail(int x, int y);
+void add_nothing(int x, int y);
+//Added buffs/debuffs/extra stuff below
+void add_poison(int x, int y);
+void add_speedup(int x, int y);
+void add_slowdown(int x, int y);
+void add_decrease_length(int x, int y);
+void add_random(int x, int y, int d);
+void add_moving(int x, int y);
+void add_invinc(int x, int y);
+void add_megaGoodie(int x, int y);
 
 
 #endif //MAP_H
\ No newline at end of file
--- a/snake.cpp	Fri Oct 23 16:30:18 2020 -0400
+++ b/snake.cpp	Wed Nov 25 01:17:39 2020 +0000
@@ -8,5 +8,21 @@
 
 void snake_init (Snake * s)
 {
-
-}
+    s->head_x = 5;
+    s->head_px =0;
+    s->head_y = 5;
+    s->head_py =0;
+    s->length = 3; 
+    
+    for (int i = 0; i < SNAKE_MAX_LENGTH; i++) {
+        s->locations[i].x = s->head_x - i;
+        s->locations[i].y = s->head_y;
+    }  
+    
+    s->pointLockTime = 0; //Time that snake can't gain points
+    s->speedupTime = 0;
+    s->slowdownTime = 0;
+    s->score = 0; //Current score of the snake
+    s->invincible = false;
+    s->invincTimer = 0;
+}
\ No newline at end of file
--- a/snake.h	Fri Oct 23 16:30:18 2020 -0400
+++ b/snake.h	Wed Nov 25 01:17:39 2020 +0000
@@ -18,6 +18,12 @@
     int length; // length of the snake
     Coordinate locations[SNAKE_MAX_LENGTH]; // Snake body locations
     int score; //Current score of the snake
+    int pointLockTime;
+    int speedupTime;
+    int slowdownTime;
+    bool invincible;
+    int invincTimer;
+    int lives;
 } Snake;
 
 // Initialize a snake structure