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

julio (none) julio at julio-desktop.
Fri Aug 6 03:50:20 UTC 2010


The following commit has been merged in the master branch:
commit 37c42208f394caf93688d68c24c60f43b47b0b08
Author: julio <julio at julio-desktop.(none)>
Date:   Thu Aug 5 22:49:33 2010 -0500

    Pathfind working now for short paths, but buggy on large paths

diff --git a/src/ai.c b/src/ai.c
index 78e8ab3..6e9db73 100644
--- a/src/ai.c
+++ b/src/ai.c
@@ -1,7 +1,6 @@
-
 /* ai.c
  *
- * Description: AI mainy path finding functions for the game lives here
+ * Description: AI mainly path finding functions for the game lives here
  * 
  * Author: Jesús Manuel Mager Hois (fongog at gmail.com) 2010
  * Copyright: GPL v3 or later
@@ -17,24 +16,185 @@
 #include "ai.h"
 #include "tuxrts.h"
 #include "bheap.h"
+#include "hashtable.h"
 
 // Hueristic distance between to points
 #define HDIST(x1, y1, x2, y2) ((x1<x2)?(x2-x1):(x1-x2)) + ((y1<y2)?(y2-y1):(y1-y2))
 
-void ai_shortes_path(th_point source, th_point goal)
+/* itoa: thanks to Lukás Chmel */
+static char* itoa(int value, char* result, int base)
+{
+    if (base < 2 || base > 36) { *result = '\0'; return result; }
+    char* ptr = result, *ptr1 = result, tmp_char;
+    int tmp_value;
+    do {
+        tmp_value = value;
+        value /= base;
+        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
+    } while ( value );
+    if (tmp_value < 0) *ptr++ = '-';
+    *ptr-- = '\0';
+    while(ptr1 < ptr) {
+        tmp_char = *ptr;
+        *ptr--= *ptr1;
+        *ptr1++ = tmp_char;
+    }
+    return result;
+}
+
+th_point *ai_shortes_path(int player, int unit, th_point source, th_point goal)
 {
-    int H, G, F;
-    if( source.x >= 0 && source.x < x_tildes   &&
-        source.y >= 0 && source.y < y_tildes   &&
-        goal.x >= 0 && goal.x < x_tildes       &&
-        goal.y >= 0 && goal.y < y_tildes       )
+    int i, a;
+    int count;
+
+    th_vector vector;
+    th_point pt;
+
+    bheap *open;
+    struct hashtable *closed;
+    bheap_node *e;
+    bheap_node *p;
+    bheap_node *n;
+    
+    // Are the source and goal point valid?
+    if( source.x >= 0 && source.x <= x_tildes   &&
+        source.y >= 0 && source.y <= y_tildes   &&
+        goal.x >= 0 && goal.x <= x_tildes       &&
+        goal.y >= 0 && goal.y <= y_tildes       )
     {
-        H = HDIST(source.x, source.y, goal.x, goal.y);
-        printf("H Distance %d\n", H);
+        
+        e = (bheap_node *)malloc(x_tildes * y_tildes * sizeof(bheap_node));
+        if(e == NULL)
+            return NULL;
+
+        count = 0;
+        i = 0;
+
+        // Creating open and closed lists
+        open = bheap_init(x_tildes * y_tildes);
+        closed = make_hashtable(hashtable_default_hash, x_tildes * y_tildes);
+
+        // Defining the initial node 
+        sprintf(e[count].id, "%03d%03d", source.x, source.y);
+        printf("Element id to store: %s\n", e[count].id);
+        e[count].deph = 0;
+        e[count].point = source;
+        e[count].h = HDIST(e[count].point.x, e[count].point.y, goal.x, goal.y);
+        e[count].g = e[count].deph;
+        e[count].val = e[count].g + e[count].h;
+        e[count].index = i;
+        e[count].parent = NULL;
+        
+        // Insert the initial node to the open list
+        if(!bheap_add(open, &e[count]))
+        {
+            printf("Coudn't add element to the open list!\n");
+            return NULL;
+        }
+        bheap_print(open);
+
+        while(open->count >= 0)
+        {
+            // Remove the lowest element in open list
+            // and add it to the closed list
+            n = bheap_del(open);
+            if(n == NULL)
+            {
+                printf("Error deleting the priority element from open list!\n");
+                return NULL;
+            }
+            bheap_print(open);
+            
+            printf("Element id to store in loop: %s, index: %d\n", n->id, n->index);
+
+            if(!hashtable_add(closed, e[n->index].id, &e[n->index]))
+            {
+                printf("Error adding to hashtable!\n");
+                return NULL;
+            }
+
+            printf("Element added to hashtable!\n");
+            
+
+            //Is this element the goal?
+            if(n->point.x == goal.x && n->point.y == goal.y)
+            {
+                while(n->parent)
+                {
+                    printf("(%d,%d)\n",n->point.x, n->point.y);
+                    n = n->parent;
+                }
+                
+                return NULL;
+            }
+
+            printf("This element is not the goal!.. Trying...\n");
+
+            //For each valid move for n
+            for(a = 0; a < NUM_DIRS; a++)
+            {
+                vector = get_vector(n->point, a);
+                if(vector.x != -2 && vector.y != -2)
+                {
+                    printf("Vector is valid... \n");
+                    printf("For %d direction tile in (%d,%d) is valid?\n", a, n->point.x, n->point.y);
+
+                    pt.x = vector.x + n->point.x;
+                    pt.y = vector.y + n->point.y;
+                    if(rts_valid_tile(player, unit, pt))
+                    {
+
+                        printf("Adding direction %d to open list!\n", a);
+
+                        //New valid element
+                        count++;
+                        e[count].deph = n->deph + 1;
+                        e[count].point = pt;
+                        memset(e[count].id, 0, 7);
+                        sprintf(e[count].id, "%03d%03d", pt.x, pt.y);
+                        e[count].index = count;
+                        e[count].h = HDIST(e[count].point.x, e[count].point.y, goal.x, goal.y);
+                        e[count].g = e[count].deph; //Unnecessary?
+                        e[count].val = e[count].g + e[count].h; // F = G + H
+                        e[count].parent = n;
+                        printf("Actual id: %s\n, H: %d G:%d F:%d Deph:%d\n", e[count].id, e[count].h,
+                               e[count].g, e[count].val, e[count].deph);
+
+                        //Is this element in closed list?
+                        if((p = hashtable_lookup(closed, e[count].id)) != NULL)
+                        {
+                            if(p->val < e[count].val)
+                            {
+                                if(!hashtable_remove(closed, p->id))
+                                {
+                                    printf("Error ocurred while trying to remove key in hashtable!\n");
+                                    return NULL;
+                                }
+                                if(!bheap_add(open, p))
+                                {
+                                    printf("Error ocurred while adding a element to open list\n");
+                                    return NULL;
+                                }
+                            }
+                        }   
+                        else
+                        {
+                            if(!bheap_add(open, &e[count]))
+                            {
+                                printf("Error ocurred while adding a new element to open list\n");
+                                return NULL;
+                            }
+                        }
+                        bheap_print(open);
+                    }
+                }
+            }
+        }
+        FREE(e);
     }
     else
     {
-        printf("Bad point references!\n");
+        printf("Bad point references : Origin(%d, %d) Dest(%d, %d)\n", source.x, source.y, goal.x, goal.y);
     }
 }
 
diff --git a/src/ai.h b/src/ai.h
index 5597b40..828b6fc 100644
--- a/src/ai.h
+++ b/src/ai.h
@@ -15,4 +15,4 @@
 #include "globals.h"
 #include "graphs.h"
 
-void ai_shortes_path(th_point source, th_point goal);
+th_point *ai_shortes_path(int, int, th_point source, th_point goal);
diff --git a/src/bheap.c b/src/bheap.c
index 3c1a1a6..ba73011 100644
--- a/src/bheap.c
+++ b/src/bheap.c
@@ -1,3 +1,15 @@
+/* bheap.c
+ *
+ * Description: Binary Heap functions.
+ * 
+ * Author: Jesús Manuel Mager Hois (fongog at gmail.com) 2010
+ * Copyright: GPL v3 or later
+ *
+ * Part of "Tux4Kids Project
+ * http://www.tux4kids.com
+ * 
+ */
+
 #include<stdio.h>
 #include<stdlib.h>
 
@@ -29,9 +41,9 @@ bheap *bheap_init(int size)
     return heap;
 }
 
-int bheap_add(bheap *heap, bheap_node data)
+int bheap_add(bheap *heap, bheap_node *data)
 {
-    bheap_node *node;
+    //bheap_node *node;
     int m;
 
     heap->count++;
@@ -42,14 +54,19 @@ int bheap_add(bheap *heap, bheap_node data)
     if(heap == NULL)
         return 0;
 
+    if(data == NULL)
+        return 0;
+
+    /*
     node = (bheap_node *)malloc(sizeof(bheap_node));
     if(node == NULL)
         return 0;
 
     *node = data;
+    */
     
     m = heap->count;
-    heap->items[heap->count] = node;
+    heap->items[heap->count] = data;
     while(m != 0)
     {
         if(heap->items[m]->val < heap->items[m/2]->val)
@@ -65,15 +82,23 @@ int bheap_add(bheap *heap, bheap_node data)
     return 1;
 }
 
-bheap_node bheap_del(bheap *heap)
+bheap_node *bheap_del(bheap *heap)
 {
     int u, v;
-    bheap_node node;
+    bheap_node *node;
+
+    if(heap->count < 0)
+    {
+        printf("Error, there is no element to delete!\n");
+        return NULL;
+    }
     
-    node = *heap->items[0];
-    free(heap->items[0]);
+    node = heap->items[0];
+    //free(heap->items[0]);
     heap->items[0] = heap->items[heap->count];
     heap->count--;
+    if(heap->count < 0)
+        printf("heap is empty!\n");
     v = 0;
     do{
         u = v;
@@ -109,6 +134,11 @@ bheap_node bheap_del(bheap *heap)
 void bheap_print(bheap *heap)
 {
     int i;
+    if(heap->count < 0)
+    {
+        printf("Error, there are no elements to print!\n");
+        return;
+    }
     for(i=0; i<=heap->count; i++)
         printf("%d ", heap->items[i]->val);
     printf("\n");
@@ -116,17 +146,14 @@ void bheap_print(bheap *heap)
 
 void bheap_free(bheap *heap)
 {
-    int i;
+    /*int i;
     for(i=0; i<=heap->count; i++)
     {
         free(heap->items[i]);
         heap->items[i] = NULL;
-    }
+    }*/
+    free(heap->items);
+    heap->items = NULL;
     free(heap);
     heap = NULL;
 }
-
-
-    
-
-
diff --git a/src/bheap.h b/src/bheap.h
index 94518e5..6939a3d 100644
--- a/src/bheap.h
+++ b/src/bheap.h
@@ -1,20 +1,43 @@
+/* bheap.h
+ *
+ * Description: Binary Heap functions.
+ * 
+ * Author: Jesús Manuel Mager Hois (fongog at gmail.com) 2010
+ * Copyright: GPL v3 or later
+ *
+ * Part of "Tux4Kids Project
+ * http://www.tux4kids.com
+ * 
+ */
+
 #ifndef BHEAP_H
 #define BHEAP_H
 
+#include "globals.h"
+
+#define ISEMPTY(heap) (heap->count<0)?1:0
+
 typedef struct bheap_node{
+    char id[7];
+    int index;
     int val;
+    int deph;
+    int g, h;
+    th_point point;
+    struct bheap_node *parent;
 }bheap_node;
 
 typedef struct bheap{
     int size;
     int count;
+    int item_count;
     bheap_node **items;
 }bheap;
 
 bheap *bheap_init(int size);
-int bheap_add(bheap *heap, bheap_node data);
+int bheap_add(bheap *heap, bheap_node *data);
 void bheap_print(bheap *heap);
-bheap_node bheap_del(bheap *heap);
+bheap_node *bheap_del(bheap *heap);
 void bheap_free(bheap *heap);
 
 #endif
diff --git a/src/game.c b/src/game.c
index c9faab1..ee8503e 100644
--- a/src/game.c
+++ b/src/game.c
@@ -428,7 +428,9 @@ static void game_handle_mouse(void)
                 if(selection.selected_objs[0] != NULL)
                 {
                     selection.selected_num = 0;
-                    printf("Selected: %s\n", selection.selected_objs[0]->name);
+                    printf("Selected: %s, in (%d, %d)\n", selection.selected_objs[0]->name,
+                            selection.selected_objs[0]->x,
+                            selection.selected_objs[0]->y);
                 }
                 else
                 {
@@ -445,7 +447,6 @@ static void game_handle_mouse(void)
         {
             io.go_rect.x = gmaps[0][Pmousemap.x][Pmousemap.y].rect.x; 
             io.go_rect.y = gmaps[0][Pmousemap.x][Pmousemap.y].rect.y;
-            //printf("Go select: %d %d ", io.go_rect.x, io.go_rect.y);
             io.mousedownr_flag = 0;
             if( io.go_rect.x > Pscreen.x &&
                 io.go_rect.x < Pscreen.x + screen->w &&
@@ -456,7 +457,6 @@ static void game_handle_mouse(void)
                 io.go_rect_dest.y = io.go_rect.y - Pscreen.y;
                 io.go_xy.x = Pmousemap.x;
                 io.go_xy.y = Pmousemap.y;
-                //printf("ScreenP: %d, %d go: %d, %d \n", Pscreen.x, Pscreen.y, io.go_rect.x, io.go_rect.y);
                 if(rts_valid_tile(0,1,io.go_xy))
                 {
                     printf("Is a valid tile...\n");
@@ -487,7 +487,13 @@ static void game_handle_mouse(void)
     {
         Pmousemap.x = selection.selected_objs[0]->x;
         Pmousemap.y = selection.selected_objs[0]->y;
-        ai_shortes_path(Pmousemap, io.go_xy);
+        //printf("Go to: (%d, %d) No.4\n", io.go_xy.x, io.go_xy.y);
+        printf("Path to go: from (%d,%d) to (%d,%d)\n", selection.selected_objs[0]->x,
+                selection.selected_objs[0]->y,
+                io.go_xy.x,
+                io.go_xy.y);
+        if(!ai_shortes_path(0,0,Pmousemap, io.go_xy))
+            printf("No shortes path found or a error ocurred!\n");
     }
 
 }
diff --git a/src/graphs.c b/src/graphs.c
index b88c563..8c16519 100644
--- a/src/graphs.c
+++ b/src/graphs.c
@@ -83,6 +83,9 @@ int create_gmaps(int players)
                 gmaps[i][j][k].visible = 1;
                 gmaps[i][j][k].terrain = map[j][k].terrain;
                 gmaps[i][j][k].object = NULL;
+                gmaps[i][j][k].point.x = j;
+                gmaps[i][j][k].point.y = k;
+
                 for(l = 0; l < NUM_DIRS; l++)
                 {
                     point.x = j;
diff --git a/src/graphs.h b/src/graphs.h
index 1185190..8705d5b 100644
--- a/src/graphs.h
+++ b/src/graphs.h
@@ -35,6 +35,7 @@ enum
 
 typedef struct gnode{
     int id;
+    th_point point;
     th_point rect;
     th_point anchor; //Anchors in main map surface.
     int visible;
diff --git a/src/hashtable.c b/src/hashtable.c
index 353947d..e15ccf4 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -1,5 +1,6 @@
 /*
 Copyright (c) 2007, 2008, 2010 Robbert Haarman
+    with some additions by Jesus Mager 2010
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
@@ -21,6 +22,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "hashtable.h"
@@ -55,6 +57,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 static inline unsigned int compute_hash(const struct hashtable *table,
                                         const char *key)
 {
+    printf("Init compute hash for %s\n", key);
     unsigned int n = table->hash(key);
     return (n < table->nbuckets) ? n : (n % table->nbuckets);
 }
@@ -70,17 +73,22 @@ 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(!table) return 0;
+
     if(entry) {
         entry->key = key;
         entry->value = value;
         entry->next = NULL;
+        entry->prev = 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;
+          while(entries->next) 
+            entries = entries->next;
+          entries->next = entry;
+          entry->prev = entries;
         }
         return 1;
     }
@@ -182,7 +190,50 @@ void *hashtable_lookup(const struct hashtable *table,
     
     return entry ? entry->value : NULL;
 }
+
+ /** remove the value bound to a key.
+ * @param table The hash table in which to remove the key.
+ * @param key The key to remove.
+ * @return The 1 succesfull removal, 0 if not found.
+ */
+int hashtable_remove(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;
+  }
+
+  if(entry) {
+    if(entry->next) {
+      if(entry->prev) {
+        entry->prev->next = entry->next;
+        entry->next->prev = entry->prev;
+      }
+      else {
+        table->bucket[n] = entry->next;
+      }
+    }
+    else if(entry->prev)
+    {
+      entry->prev->next = NULL;
+    }
+    else {
+      table->bucket[n] = NULL;
+    }
     
+    free(entry);
+    entry = NULL;
+    return 1;
+  }
+  else {
+    return 0;
+  }
+}   
+
 /** 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.
diff --git a/src/hashtable.h b/src/hashtable.h
index aac6b0f..57d090d 100644
--- a/src/hashtable.h
+++ b/src/hashtable.h
@@ -1,5 +1,6 @@
 /*
 Copyright (c) 2007, 2008, 2010 Robbert Haarman
+    with some additions by Jesus Mager 2010
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the
@@ -28,6 +29,7 @@ struct hashtable_entry {
     char *key;
     void *value;
     struct hashtable_entry *next;
+    struct hashtable_entry *prev;
 };
 
 struct hashtable {
@@ -43,6 +45,7 @@ void hashtable_iter(const struct hashtable *table,
 void (*func) (char *key, void *value));
 void *hashtable_lookup(const struct hashtable *table,
                         const char *key);
+int hashtable_remove(const struct hashtable *table, const char *key);
 struct hashtable *make_hashtable(unsigned int (*hash) (const char*),
                                 unsigned int nbuckets);
 
diff --git a/src/map.h b/src/map.h
index 81d62b9..704c284 100644
--- a/src/map.h
+++ b/src/map.h
@@ -65,8 +65,8 @@ void        th_draw_map(void);
 
 th_vector   get_vector(th_point point, int iso_dir);
 
-int generate_anchormap(void);
-void free_anchormap(void);
+int         generate_anchormap(void);
+void        free_anchormap(void);
 
 
 //mouse_map(): returns a th_point with the (x,y) pair
diff --git a/src/objects.h b/src/objects.h
index ca411a3..6a75c2d 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -15,7 +15,7 @@ enum{
 
 typedef struct th_obj{
     int id;
-    int x, y; // (x,y) in the th_map array
+    int x, y; // (x,y) in the gmaps array
     int type; // using the enum NUM_OF_TYPES of map.h
     int live; 
     int actual_live;

-- 
tuxhistory - Educational history game



More information about the Tux4kids-commits mailing list