<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
[email protected]
https://mail.gna.org/listinfo/freeciv-dev