<URL: http://bugs.freeciv.org/Ticket/Display.html?id=19822 >

On 1/14/07, Marko Lindqvist <[EMAIL PROTECTED]> wrote:
>
>
>  1. First node always gets segment_length = 1.
>  2. No other node can get segment_length 1.
>  3. Segment_length can be too big, but not too small.
>
>  This mostly untested patch modifies create_danger_segment() so that
> it uses segment_length from last node only as maximum length.
> Iteration continues until segment_length of the current node is 1.

 This version makes similar fix for danger_construct_path(). All this
still untested.


 - ML

diff -Nurd -X.diff_ignore freeciv/common/aicore/path_finding.c freeciv/common/aicore/path_finding.c
--- freeciv/common/aicore/path_finding.c	2006-07-17 23:56:45.000000000 +0300
+++ freeciv/common/aicore/path_finding.c	2007-01-15 21:30:17.000000000 +0200
@@ -823,33 +823,44 @@
 /***********************************************************************
   Creating path segment going back from d_node1 to a safe tile.
 ***********************************************************************/
-static void create_danger_segment(struct pf_map *pf_map, enum direction8 dir,
-                                  struct danger_node *d_node1, int length)
+static void create_danger_segment(struct pf_map *pf_map,
+                                  struct danger_node *d_node1)
 {
   int i;
   struct tile *ptile = pf_map->tile;
   struct pf_node *node = &pf_map->lattice[ptile->index];
+  struct danger_node *dnode = &pf_map->d_lattice[ptile->index];
+  int max_length = dnode->segment_length;
 
   /* Allocating memory */
   if (d_node1->danger_segment) {
     freelog(LOG_ERROR, "Possible memory leak in create_danger_segment");
   }
-  d_node1->danger_segment = fc_malloc(length * sizeof(struct pf_danger_pos));
+  d_node1->danger_segment = fc_malloc(max_length * sizeof(struct pf_danger_pos));
 
   /* Now fill the positions */
-  for (i = 0; i < length; i++) {
+  for (i = 0; dnode != NULL; i++) {
+    assert(i < max_length);
+
     /* Record the direction */
     d_node1->danger_segment[i].dir = node->dir_to_here;
     d_node1->danger_segment[i].cost = node->cost;
     d_node1->danger_segment[i].extra_cost = node->extra_cost;
-    if (i == length - 1) {
-      /* The last dangerous node contains "waiting" info */
-      d_node1->waited = pf_map->d_lattice[ptile->index].waited;
-    }
 
     /* Step further down the tree */
     ptile = mapstep(ptile, DIR_REVERSE(node->dir_to_here));
     node = &pf_map->lattice[ptile->index];
+
+    if (dnode->segment_length == 1) {
+      /* The last dangerous node contains "waiting" info */
+      d_node1->waited = dnode->waited;
+
+      /* Go no further */
+      dnode = NULL;
+    } else {
+      /* Get next danger node */
+      dnode = &pf_map->d_lattice[ptile->index];
+    }
   }
 
   /* Make sure we reached a safe node */
@@ -1010,8 +1021,7 @@
           }
 	  if (d_node->is_dangerous) {
 	    /* Transition from red to blue, need to record the path back */
-	    create_danger_segment(pf_map, dir, d_node1, 
-                                  d_node->segment_length);
+	    create_danger_segment(pf_map, d_node1);
 	  } else {
             /* We don't consider waiting to get to a safe tile as 
              * "real" waiting */
@@ -1119,6 +1129,7 @@
   bool waited = FALSE;
   struct pf_node *node = &pf_map->lattice[ptile->index];
   struct danger_node *d_node = &pf_map->d_lattice[ptile->index];
+  int max_step = d_node->step;
 
   if (pf_map->params->turn_mode != TM_BEST_TIME &&
       pf_map->params->turn_mode != TM_WORST_TIME) {
@@ -1127,12 +1138,14 @@
   }
 
   path->positions 
-    = fc_malloc((d_node->step + 1) * sizeof(struct pf_position));
-  path->length = d_node->step + 1;
+    = fc_malloc((max_step + 1) * sizeof(struct pf_position));
+  path->length = max_step + 1;
 
-  for (i = d_node->step; i >= 0; i--) {
+  for (i = max_step; d_node != NULL; i--) {
     bool old_waited = FALSE;
 
+    assert(i >= d_node->step);
+
     /* 1: Deal with waiting */
     if (!d_node->is_dangerous) {
       if (waited) {
@@ -1176,9 +1189,22 @@
     finalize_position(pf_map, &path->positions[i]);
 
     /* 3: Check if we finished */
-    if (i == 0) {
+    if (d_node->step == 1) {
       /* We should be back at the start now! */
       assert(same_pos(ptile, pf_map->params->start_tile));
+
+      if (i > 0) {
+        /* step value for original node was too high.
+         * Reorganize path. */
+        int j;
+
+        path->length -= i;
+
+        for (j = 0; i <= max_step; j++, i++) {
+          path->positions[j] = path->positions[i];
+        }
+      }
+
       return path;
     }
 
@@ -1198,9 +1224,13 @@
     }
 
     /* 5: Step further back */
-    ptile = mapstep(ptile, DIR_REVERSE(dir_next));
-    node = &pf_map->lattice[ptile->index];
-    d_node = &pf_map->d_lattice[ptile->index];
+    if (d_node > 1) {
+      ptile = mapstep(ptile, DIR_REVERSE(dir_next));
+      node = &pf_map->lattice[ptile->index];
+      d_node = &pf_map->d_lattice[ptile->index];
+    } else {
+      d_node = NULL;
+    }
 
   }
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to