Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed wave_player 4DGL-uLCD-SE MMA8452
Revision 4:e3fbc74a3783, committed 2019-11-14
- Comitter:
- zkang0729
- Date:
- Thu Nov 14 17:14:37 2019 +0000
- Parent:
- 3:e4690ad5a4d2
- Commit message:
- Initial Commit;
Changed in this revision
--- a/hash_table.cpp Mon Oct 28 05:26:35 2019 +0000
+++ b/hash_table.cpp Thu Nov 14 17:14:37 2019 +0000
@@ -1,6 +1,6 @@
/*
- Student Name:
- Date:
+ Student Name: Zixuan Kang
+ Date: 2019-10-25
=======================
ECE 2035 Project 2-1:
@@ -126,7 +126,16 @@
* @return The pointer to the hash table entry
*/
static HashTableEntry* createHashTableEntry(unsigned int key, void* value) {
+ //Allocate memort for the new HashTableEntry struct on heap
+ HashTableEntry* newHashTableEntry = (HashTableEntry*)malloc(sizeof(HashTableEntry));
+
+ //Initialize the components of the new HashTableEntry stuct
+ newHashTableEntry->key = key;
+ newHashTableEntry->value = value;
+ newHashTableEntry->next = NULL;
+ //Return the HashTableEntry struct.
+ return newHashTableEntry;
}
/**
@@ -140,7 +149,19 @@
* @return The pointer to the hash table entry, or NULL if key does not exist
*/
static HashTableEntry* findItem(HashTable* hashTable, unsigned int key) {
-
+ int i;
+ HashTableEntry *thisHashTableEntry;
+ for(i = 0; i < hashTable->num_buckets; i++) { // Go through each linked lsit
+ thisHashTableEntry = hashTable->buckets[i];
+ while (thisHashTableEntry) {
+ if (thisHashTableEntry->key != key) {
+ thisHashTableEntry = thisHashTableEntry->next; // If the keys don't match go to the next one
+ } else {
+ return thisHashTableEntry;
+ }
+ }
+ }
+ return NULL;
}
/****************************************************************************
@@ -167,7 +188,7 @@
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;
@@ -178,21 +199,71 @@
}
void destroyHashTable(HashTable* hashTable) {
-
+ int i;
+ HashTableEntry *t1, *t2;
+ for (i = 0; i < hashTable->num_buckets; i++) {
+ t1 = hashTable->buckets[i];
+ while (t1) {
+ t2 = t1; // Sign it to a temporary variable
+ t1 = t1->next; // Assign the next one to t1
+ free(t2->value); // Free the value
+ free(t2); // Free the node
+ }
+ }
+ free(hashTable->buckets); // Free the bucket
+ free(hashTable); // Free the hashtable
}
void* insertItem(HashTable* hashTable, unsigned int key, void* value) {
-
+ HashTableEntry *thisHashTableEntry;
+ if ((thisHashTableEntry = findItem(hashTable, key))) {
+ //Key in list
+ void *temp = thisHashTableEntry->value; // Get the initial value of the entry point
+ thisHashTableEntry->value = value;
+ return temp;
+ }
+ //Key not in list
+ thisHashTableEntry = createHashTableEntry(key, value);
+ if (!thisHashTableEntry) return NULL; //Malloc failed
+ thisHashTableEntry->next = hashTable->buckets[hashTable->hash(key)];
+ hashTable->buckets[hashTable->hash(key)] = thisHashTableEntry; // Insert the node at the head of the linked list
+ return thisHashTableEntry->value;
}
void* getItem(HashTable* hashTable, unsigned int key) {
-
+ if (findItem(hashTable, key) == NULL) {
+ return NULL;
+ } else {
+ return findItem(hashTable, key)->value; // return the value of the elemnt that has the key
+ }
}
void* removeItem(HashTable* hashTable, unsigned int key) {
-
+ HashTableEntry *thisHashTableEntry = hashTable->buckets[hashTable->hash(key)];
+ HashTableEntry *temp;
+ if (!thisHashTableEntry) return NULL;
+ //If the node is at the head of the linked list
+ if (thisHashTableEntry->key == key) {
+ hashTable->buckets[hashTable->hash(key)] = thisHashTableEntry->next;
+ temp = thisHashTableEntry;
+ free(thisHashTableEntry);
+ return temp->value;
+ }
+ // If the node is not at the head of the linked list
+ while (thisHashTableEntry->next) {
+ if (thisHashTableEntry->next->key == key) {
+ //Split the linked list
+ temp = thisHashTableEntry->next;
+ thisHashTableEntry->next = thisHashTableEntry->next->next;
+ free(thisHashTableEntry->next);
+ return temp->value;
+ }
+ thisHashTableEntry = thisHashTableEntry->next;
+ }
+ return NULL;
}
void deleteItem(HashTable* hashTable, unsigned int key) {
-
-}
\ No newline at end of file
+ free(removeItem(hashTable, key));
+ return;
+}
--- a/main.cpp Mon Oct 28 05:26:35 2019 +0000
+++ b/main.cpp Thu Nov 14 17:14:37 2019 +0000
@@ -6,21 +6,22 @@
#include "speech.h"
// Functions in this file
-int get_action (GameInputs inputs);
-int update_game (int action);
-void draw_game (int init);
-void init_main_map ();
-int main ();
+int get_action(GameInputs inputs);
+int update_game(int action);
+void draw_game(int init);
+void init_main_map();
+int main();
/**
* The main game state. Must include Player locations and previous locations for
* drawing to work properly. Other items can be added as needed.
*/
-struct {
- int x,y; // Current locations
- int px, py; // Previous locations
- int has_key;
- // You can add other properties for the player here
+struct
+{
+ int x, y; // Current locations
+ int px, py; // Previous locations
+ int has_key;
+ // You can add other properties for the player here
} Player;
/**
@@ -36,7 +37,7 @@
#define GO_DOWN 6
int get_action(GameInputs inputs)
{
- return NO_ACTION;
+ return NO_ACTION;
}
/**
@@ -53,23 +54,34 @@
#define FULL_DRAW 2
int update_game(int action)
{
- // Save player previous location before updating
- Player.px = Player.x;
- Player.py = Player.y;
-
- // Do different things based on the each action.
- // You can define functions like "go_up()" that get called for each case.
- switch(action)
- {
- case GO_UP: break;
- case GO_LEFT: break;
- case GO_DOWN: break;
- case GO_RIGHT: break;
- case ACTION_BUTTON: break;
- case MENU_BUTTON: break;
- default: break;
- }
- return NO_RESULT;
+ // Save player previous location before updating
+ Player.px = Player.x;
+ Player.py = Player.y;
+
+ // Do different things based on the each action.
+ // You can define functions like "go_up()" that get called for each case.
+ switch (action)
+ {
+ case GO_UP:
+ Player.y != 0 && Player.y - 1;
+ break;
+ case GO_LEFT:
+ Player.x != 0 && Player.x - 1;
+ break;
+ case GO_DOWN:
+ Player.y != map_height() && Player.y + 1;
+ break;
+ case GO_RIGHT:
+ Player.x != map_width() && Player.x + 1;
+ break;
+ case ACTION_BUTTON:
+ break;
+ case MENU_BUTTON:
+ break;
+ default:
+ break;
+ }
+ return NO_RESULT;
}
/**
@@ -80,67 +92,68 @@
*/
void draw_game(int init)
{
- // Draw game border first
- if(init) draw_border();
-
- // Iterate over all visible map tiles
- for (int i = -5; i <= 5; i++) // Iterate over columns of tiles
+ // Draw game border first
+ if (init)
+ draw_border();
+
+ // 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
{
- 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 + Player.x;
+ int y = j + Player.y;
+
+ // Compute the previous map (px, py) of this tile
+ int px = i + Player.px;
+ int py = j + Player.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 (init && i == 0 && j == 0) // Only draw the player on init
+ {
+ draw_player(u, v, Player.has_key);
+ continue;
+ }
+ else 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 (init || curr_item != prev_item) // Only draw if they're different
{
- // Here, we have a given (i,j)
-
- // Compute the current map (x,y) of this tile
- int x = i + Player.x;
- int y = j + Player.y;
-
- // Compute the previous map (px, py) of this tile
- int px = i + Player.px;
- int py = j + Player.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 (init && i == 0 && j == 0) // Only draw the player on init
- {
- draw_player(u, v, Player.has_key);
- continue;
- }
- else 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 (init || 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 (init) // If doing a full draw, but we're out of bounds, draw the walls.
- {
- draw = draw_wall;
- }
+ 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 (init) // 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);
- }
+ // Actually draw the tile
+ if (draw)
+ draw(u, v);
}
+ }
- // Draw status bars
- draw_upper_status();
- draw_lower_status();
+ // 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. Note: using the similar
@@ -148,22 +161,22 @@
*/
void init_main_map()
{
- // "Random" plants
- Map* map = set_active_map(0);
- for(int i = map_width() + 3; i < map_area(); i += 39)
- {
- add_plant(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());
- add_wall(0, 0, VERTICAL, map_height());
- add_wall(map_width()-1, 0, VERTICAL, map_height());
- pc.printf("Walls done!\r\n");
+ // "Random" plants
+ Map *map = set_active_map(0);
+ for (int i = map_width() + 3; i < map_area(); i += 39)
+ {
+ add_plant(i % map_width(), i / map_width());
+ }
+ pc.printf("plants\r\n");
- print_map();
+ 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");
+
+ print_map();
}
/**
@@ -174,36 +187,49 @@
*/
int main()
{
- // First things first: initialize hardware
- ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
+ //Game Over Indication
+ unsigned int GameOver = 0;
+
+ // First things first: initialize hardware
+ ASSERT_P(hardware_init() == ERROR_NONE, "Hardware init failed!");
- // Initialize the maps
- maps_init();
- init_main_map();
-
- // Initialize game state
- set_active_map(0);
- Player.x = Player.y = 5;
+ // Initialize the maps
+ maps_init();
+ init_main_map();
- // Initial drawing
- draw_game(true);
+ // Initialize game state
+ set_active_map(0);
+ Player.x = Player.y = 5;
+
+ // Initial drawing
+ draw_game(true);
- // Main game loop
- while(1)
- {
- // Timer to measure game update speed
- Timer t; t.start();
-
- // Actuall do the game update:
- // 1. Read inputs
- // 2. Determine action (get_action)
- // 3. Update game (update_game)
- // 3b. Check for game over
- // 4. Draw frame (draw_game)
-
- // 5. Frame delay
- t.stop();
- int dt = t.read_ms();
- if (dt < 100) wait_ms(100 - dt);
- }
+ // Main game loop
+ while (!GameOver)
+ {
+ // Timer to measure game update speed
+ Timer t;
+ t.start();
+
+ // Actuall do the game update:
+ // 1. Read inputs
+ //inputs = read_inputs();
+
+ // 2. Determine action (get_action)
+ //action = get_action(input);
+
+ // 3. Update game (update_game)
+ //next_state = update_game(action);
+
+ // 3b. Check for game over
+
+
+ // 4. Draw frame (draw_game)
+
+ // 5. Frame delay
+ t.stop();
+ int dt = t.read_ms();
+ if (dt < 100)
+ wait_ms(100 - dt);
+ }
}
--- a/map.cpp Mon Oct 28 05:26:35 2019 +0000
+++ b/map.cpp Thu Nov 14 17:14:37 2019 +0000
@@ -7,9 +7,10 @@
* The Map structure. This holds a HashTable for all the MapItems, along with
* values for the width and height of the Map.
*/
-struct Map {
- HashTable* items;
- int w, h;
+struct Map
+{
+ HashTable *items;
+ int w, h;
};
/**
@@ -25,8 +26,9 @@
* key information (x, y) into a one-dimensional unsigned integer.
* This function should uniquely map (x,y) onto the space of unsigned integers.
*/
-static unsigned XY_KEY(int X, int Y) {
- // TODO: Fix me!
+static unsigned XY_KEY(int X, int Y)
+{
+ return Y * map_width() + X;
}
/**
@@ -36,103 +38,116 @@
*/
unsigned map_hash(unsigned key)
{
- // TODO: Fix me!
+ return key % map_width();
}
void maps_init()
{
- // TODO: Implement!
- // Initialize hash table
- // Set width & height
+ HashTable *hash_map = createHashTable(map_hash, 50);
+ map.items = hash_map;
+ map.w = 50;
+ map.h = 50;
}
-Map* get_active_map()
+Map *get_active_map()
{
- // There's only one map
- return ↦
+ // There's only one map
+ return ↦
}
-Map* set_active_map(int m)
+Map *set_active_map(int m)
{
- active_map = m;
- return ↦
+ active_map = m;
+ return ↦
}
void print_map()
{
- // As you add more types, you'll need to add more items to this array.
- char lookup[] = {'W', 'P'};
- for(int y = 0; y < map_height(); y++)
+ // As you add more types, you'll need to add more items to this array.
+ char lookup[] = {'W', 'P'};
+ for (int y = 0; y < map_height(); y++)
+ {
+ for (int x = 0; x < map_width(); x++)
{
- for (int x = 0; x < map_width(); x++)
- {
- MapItem* item = get_here(x,y);
- if (item) pc.printf("%c", lookup[item->type]);
- else pc.printf(" ");
- }
- pc.printf("\r\n");
+ MapItem *item = get_here(x, y);
+ if (item)
+ pc.printf("%c", lookup[item->type]);
+ else
+ pc.printf(" ");
}
+ pc.printf("\r\n");
+ }
}
int map_width()
{
+ return map.w;
}
int map_height()
{
+ return map.h;
}
int map_area()
{
+ return map_height() * map_width();
}
-MapItem* get_north(int x, int y)
+MapItem *get_north(int x, int y)
{
+ return (MapItem *)getItem(map.items, XY_KEY(x, y - 1));
}
-MapItem* get_south(int x, int y)
+MapItem *get_south(int x, int y)
{
+ return (MapItem *)getItem(map.items, XY_KEY(x, y + 1));
}
-MapItem* get_east(int x, int y)
+MapItem *get_east(int x, int y)
{
+ return (MapItem *)getItem(map.items, XY_KEY(x + 1, y));
}
-MapItem* get_west(int x, int y)
+MapItem *get_west(int x, int y)
{
+ return (MapItem *)getItem(map.items, XY_KEY(x - 1, y));
}
-MapItem* get_here(int x, int y)
+MapItem *get_here(int x, int y)
{
+ return (MapItem *)getItem(map.items, XY_KEY(x, y));
}
-
void map_erase(int x, int y)
{
+ removeItem(map.items, XY_KEY(x, y));
}
void add_wall(int x, int y, int dir, int len)
{
- for(int i = 0; i < len; i++)
- {
- MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
- w1->type = WALL;
- w1->draw = draw_wall;
- w1->walkable = false;
- w1->data = NULL;
- unsigned key = (dir == HORIZONTAL) ? XY_KEY(x+i, y) : XY_KEY(x, y+i);
- void* val = insertItem(get_active_map()->items, key, w1);
- if (val) free(val); // If something is already there, free it
- }
+ for (int i = 0; i < len; i++)
+ {
+ MapItem *w1 = (MapItem *)malloc(sizeof(MapItem));
+ w1->type = WALL;
+ w1->draw = draw_wall;
+ w1->walkable = false;
+ w1->data = NULL;
+ unsigned key = (dir == HORIZONTAL) ? XY_KEY(x + i, y) : XY_KEY(x, y + i);
+ void *val = insertItem(get_active_map()->items, key, w1);
+ if (val)
+ free(val); // If something is already there, free it
+ }
}
void add_plant(int x, int y)
{
- MapItem* w1 = (MapItem*) malloc(sizeof(MapItem));
- w1->type = PLANT;
- w1->draw = draw_plant;
- 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
+ MapItem *w1 = (MapItem *)malloc(sizeof(MapItem));
+ w1->type = PLANT;
+ w1->draw = draw_plant;
+ 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/speech.cpp Mon Oct 28 05:26:35 2019 +0000
+++ b/speech.cpp Thu Nov 14 17:14:37 2019 +0000
@@ -18,9 +18,9 @@
* @param line The text to display
* @param which If TOP, the first line; if BOTTOM, the second line.
*/
-#define TOP 0
+#define TOP 0
#define BOTTOM 1
-static void draw_speech_line(const char* line, int which);
+static void draw_speech_line(const char *line, int which);
/**
* Delay until it is time to scroll.
@@ -29,29 +29,60 @@
void draw_speech_bubble()
{
+ uLCD.filled_rectangle(3, 93, 123, 113, GREEN);
+ uLCD.filled_rectangle(4, 94, 122, 112, RED);
}
void erase_speech_bubble()
{
}
-void draw_speech_line(const char* line, int which)
+void draw_speech_line(const char *line, int which)
+{
+}
+
+int readPB1(int pb1)
{
+ GameInputs inputs;
+ inputs = read_inputs();
+ if (inputs.b1 == 0)
+ pb1 = 0;
+ return pb1;
}
void speech_bubble_wait()
{
+ int pb1 = 1;
+ while (pb1 == 1)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ uLCD.filled_circle(120, 15, 4, RED);
+ wait(0.1);
+ pb1 = readPB1(pb1);
+ }
+
+ if (pb1 == 0)
+ break;
+
+ for (int i = 0; i < 4; i++)
+ {
+ uLCD.filled_circle(120, 15, 4, BLACK);
+ wait(0.1);
+ pb1 = readPB1(pb1);
+ }
+ }
}
-void speech(const char* line1, const char* line2)
+void speech(const char *line1, const char *line2)
{
- draw_speech_bubble();
- draw_speech_line(line1, TOP);
- draw_speech_line(line2, BOTTOM);
- speech_bubble_wait();
- erase_speech_bubble();
+ draw_speech_bubble();
+ draw_speech_line(line1, TOP);
+ draw_speech_line(line2, BOTTOM);
+ speech_bubble_wait();
+ erase_speech_bubble();
}
-void long_speech(const char* lines[], int n)
+void long_speech(const char *lines[], int n)
{
}