[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