[Tux4kids-commits] [SCM] tuxhistory - Educational history game branch, master, updated. d4436e475ff1a604024f4908332ded38027491bb

julio (none) julio at julio-desktop.
Sun Jul 11 01:08:43 UTC 2010


The following commit has been merged in the master branch:
commit d4436e475ff1a604024f4908332ded38027491bb
Author: julio <julio at julio-desktop.(none)>
Date:   Sat Jul 10 20:07:44 2010 -0500

    Adding Hash Tables...

diff --git a/src/Makefile.am b/src/Makefile.am
index c579d16..1ef7009 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,7 @@ tuxhistory_SOURCES = tuxhistory.c \
 	fileops_media.c \
 	options.c	\
 	credits.c	\
+	hashtable.c \
 	highscore.c	\
 	llist.c		\
 	linewrap.c	\
@@ -57,6 +58,7 @@ EXTRA_DIST = 	credits.h 	\
 	game.h		\
 	menu.h		\
 	globals.h	\
+	hashtable.h \
 	highscore.h 	\
 	linewrap.h	\
 	llist.h		\
diff --git a/src/fileops.h b/src/fileops.h
index 5be6b8e..10b060c 100644
--- a/src/fileops.h
+++ b/src/fileops.h
@@ -359,15 +359,16 @@ enum {
 };
 
 enum{
-    OBJ_MIXED, // Forest images
-    OBJ_TROPICAL,
-    OBJ_CONIFER,
-    OBJ_SCRUB,
-    OBJ_BOREAL,
-    OBJ_WETLAND,
-    OBJ_RAIN,
-    OBJ_BROADLEAF,
-    NUM_OBJECTS // Must at the end.
+    FOREST_MIXED, // Forest images
+    FOREST_TROPICAL,
+    FOREST_CONIFER,
+    FOREST_SCRUB,
+    FOREST_BOREAL,
+    FOREST_WETLAND,
+    FOREST_RAIN,
+    FOREST_BROADLEAF,
+    FOREST_OBJECTS, // Must be at end of forest enums
+    NUM_OBJECTS // Must be at the end.
 };
 
 /* Names for game sounds (formerly in sounds.h): */
diff --git a/src/hashtable.c b/src/hashtable.c
new file mode 100644
index 0000000..0d28004
--- /dev/null
+++ b/src/hashtable.c
@@ -0,0 +1,187 @@
+#include <stdlib.h>
+#include <string.h>
+#include "hashtable.h"
+
+/** \file
+* Hashtable implementation internals.
+*
+* <em>This file contains the full documentation of all functions, types,
+* constants, and variables used in the hashtable implementation, including
+* those that are intended only for internal use. For the public interface
+* to hash tables, see \ref hashtable.h.</em>
+*/
+
+/** Allocate memory for some type.
+* @param T The type to allocate memory for.
+* @return A pointer to the newly allocated storage.
+*/
+#define NEW(T) (T*) malloc(sizeof(T))
+
+/** Allocate memory for an array.
+* @param T The type of the elements of the array.
+* @param N The number of elements in the array.
+* @return A pointer to the array.
+*/
+#define NEWARRAY(T, N) (T*) calloc((N), sizeof(T))
+
+/** Hash a key using a table's hash function.
+* @param table The table whose hash function to use.
+* @param key The key to hash.
+* @return The hash of the key, clipped to the number of buckets in the table.
+*/
+static inline unsigned int compute_hash(const struct hashtable *table,
+                                        const char *key)
+{
+    unsigned int n = table->hash(key);
+    return (n < table->nbuckets) ? n : (n % table->nbuckets);
+}
+
+/** Add an entry to a hash table.
+* @param table The hash table the entry is to be added to.
+* @param key The key for the entry.
+* @param value The value for the entry.
+* @return Nonzero on success, 0 on failure.
+*/
+int hashtable_add(struct hashtable *table, char *key, void *value)
+{
+    unsigned int n;
+    struct hashtable_entry *entry = NEW(struct hashtable_entry);
+    struct hashtable_entry *entries;
+    
+    if(entry) {
+        entry->key = key;
+        entry->value = value;
+        entry->next = NULL;
+        n = compute_hash(table, key);
+        entries = table->bucket[n];
+        if(!entries) table->bucket[n] = entry;
+        else {
+            while(entries->next) entries = entries->next;
+            entries->next = entry;
+        }
+        return 1;
+    }
+    
+    return 0;
+}
+
+/** Insert all elements from one hash table into another.
+* @param dest The hash table to insert elements into.
+* @param src The hash table whose elements are to be inserted.
+* @return \a dest
+*/
+struct hashtable *copy_hashtable(struct hashtable *dest, struct hashtable *src) {
+    unsigned int i;
+    struct hashtable_entry *entry;
+    
+    for(i = 0; i < src->nbuckets; i++) {
+        for(entry = src->bucket[i]; entry; entry = entry->next) {
+            hashtable_add(dest, entry->key, entry->value);
+        }
+    }  
+}
+
+/** The default hash function.
+* This function can be used as the \c hash parameter
+* to \c make_hash_table().
+*
+* @param key The key to be hashed.
+* @returns The hash for the key.
+*/
+unsigned int hashtable_default_hash(const char *key) {
+    unsigned int hash = 0;
+    unsigned char *p = (unsigned char*) key;
+    
+    while(*p) {
+        hash = (hash * 33) + ((unsigned int) *p);
+        p++;
+    }
+    
+    return hash;
+}
+
+/** Free all the memory used by a hash table.
+* @param table The hash table to be deallocated.
+*/
+void free_hashtable(struct hashtable *table) {
+    unsigned int i;
+    struct hashtable_entry *entry;
+    struct hashtable_entry *next;
+    
+    for(i = 0; i < table->nbuckets; i++) {
+        entry = table->bucket[i];
+        while(entry) {
+            next = entry->next;
+            free(entry);
+            entry = next;
+        }
+    }
+    
+    free(table->bucket);
+    free(table);
+}
+
+/** Call a function for each entry in a hash table.
+* @param table The hash table whose entries to iterate over.
+* @param func The function to call for each entry.
+The function receives two argument:
+1. The key of the entry.
+2. The value of the entry.
+*/
+void hashtable_iter(const struct hashtable *table,
+                    void (*func) (char *key, void *value))
+{
+    unsigned int i;
+    struct hashtable_entry *entry;
+    
+    for(i = 0; i < table->nbuckets; i++) {
+        for(entry = table->bucket[i]; entry; entry = entry->next) {
+            func(entry->key, entry->value);
+        }
+    }
+}
+
+/** Look up the value bound to a key.
+* @param table The hash table in which to look up the key.
+* @param key The key to look up.
+* @return The value belonging to the key if found, NULL if not found.
+*/
+void *hashtable_lookup(const struct hashtable *table,
+                       const char *key)
+{
+    unsigned int n = compute_hash(table, key);
+    struct hashtable_entry *entry = table->bucket[n];
+    
+    while(entry) {
+        if(!strcmp(key, entry->key)) break;
+        entry = entry->next;
+    }
+    
+    return entry ? entry->value : NULL;
+}
+    
+/** Create a hash table.
+* @param hash The hash function to use with this hash table.
+        The function has to map NUL-terminated strings to unsigned ints.
+* @param nbuckets The number of buckets in the hash table.
+* @return The new hash table on success, NULL on failure.
+*/ 
+struct hashtable *make_hashtable(unsigned int (*hash) (const char*),
+                                unsigned int nbuckets)
+{
+    struct hashtable *table = NEW(struct hashtable);
+    
+    if(table) {
+        table->bucket = NEWARRAY(struct hashtable_entry*,
+                                nbuckets);
+        if(!table->bucket) {
+        free(table);
+        return NULL;
+    }
+    table->hash = hash;
+    table->nbuckets = nbuckets;
+    }
+    
+    return table;
+    }
+
diff --git a/src/hashtable.h b/src/hashtable.h
new file mode 100644
index 0000000..1cf616d
--- /dev/null
+++ b/src/hashtable.h
@@ -0,0 +1,27 @@
+#ifndef HASHTABLE_H
+#define HASHTABLE_H
+
+struct hashtable_entry {
+    char *key;
+    void *value;
+    struct hashtable_entry *next;
+};
+
+struct hashtable {
+    unsigned int (*hash) (const char*);
+    unsigned int nbuckets;
+    struct hashtable_entry **bucket;
+};
+
+void free_hashtable(struct hashtable *table);
+int hashtable_add(struct hashtable *table, char *key, void *value);
+unsigned int hashtable_default_hash(const char *key);
+void hashtable_iter(const struct hashtable *table,
+void (*func) (char *key, void *value));
+void *hashtable_lookup(const struct hashtable *table,
+                        const char *key);
+struct hashtable *make_hashtable(unsigned int (*hash) (const char*),
+                                unsigned int nbuckets);
+
+#endif /* ndef HASHTABLE_H */
+
diff --git a/src/map.c b/src/map.c
index 040714c..1d50f83 100644
--- a/src/map.c
+++ b/src/map.c
@@ -23,6 +23,7 @@
 #include "globals.h"
 #include "fileops.h"
 #include "map.h"
+#include "llist.c"
 
 SDL_Surface* map_image;
 
@@ -64,9 +65,10 @@ int map_xml(FILE *fp)
                 jnode = mxmlFindElement(jnode, inode, "tilde",
                     NULL, NULL, MXML_DESCEND))
         {
+            // Get terrain value
             node = mxmlFindElement(jnode, jnode, "terrain",
                     NULL, NULL, MXML_DESCEND);
-
+    
             value = get_terrain_enum(node->child->value.text.string);
             if(value != -1)
             {
@@ -75,6 +77,12 @@ int map_xml(FILE *fp)
 
             printf("%s",node->child->value.text.string);
             
+            // Get objects
+            node = mxmlFindElement(jnode, jnode, "object",
+                    NULL, NULL, MXML_DESCEND);
+
+            value = get_obj_enum(node->child->value.text.string);
+             
             node = mxmlFindElement(jnode, jnode, "height",
                     NULL, NULL, MXML_DESCEND);
             
@@ -128,6 +136,27 @@ int map_xml(FILE *fp)
 // Returns the enum value for each terrain type. If the terrain
 // type don't exists it returns -1
 
+
+int get_obj_enum(char *terrain_string)
+{
+    if(strcmp(terrain_string, "FOREST_BOREAL") == 0)
+        return FOREST_BOREAL;
+    else if(strcmp(terrain_string, "FOREST_CONIFER") == 0)
+        return FOREST_CONFIER;
+    else if(strcmp(terrain_string, "FOREST_MIXED") == 0)
+        return FOREST_MIXED;
+    else if(strcmp(terrain_string, "FOREST_SCRUB") == 0)
+        return FOREST_SCRUB;
+    else if(strcmp(terrain_string, "BROADLEAF") == 0)
+        return FOREST_BROADLEAF;
+    else if(strcmp(terrain_string, "FOREST_RAIN") == 0)
+        return FOREST_RAIN;
+    else if(strcmp(terrain_string, "FOREST_TROPICAL") == 0)
+        return FOREST_TROPICAL;
+    else
+        return -1;
+}
+
 int get_terrain_enum(char *terrain_string)
 {
     if(strcmp(terrain_string, "HIGHSEA") == 0)
diff --git a/src/map.h b/src/map.h
index cb99f91..bcb2b8f 100644
--- a/src/map.h
+++ b/src/map.h
@@ -29,15 +29,19 @@
 //       
 
 enum{
-    TREE,
-    NUM_OF_OBJECTS
+    FOREST,
+    GOLD,
+    STONE,
+    BUILDING,
+    UNI,
+    NUM_OF_TYPES
 };
 
 /*Global tuxhistory vars*/
 typedef struct {
     int id;
     int x, y; // (x,y) in the th_map array
-    int type;
+    int type; // using the enum NUM_OF_TYPES of map.h
     int live; // 100 to 0 
     char name[30];
     int defence;

-- 
tuxhistory - Educational history game



More information about the Tux4kids-commits mailing list