Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2003:
[Freeciv-Dev] (PR#2837) warmap topology fix
Home

[Freeciv-Dev] (PR#2837) warmap topology fix

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2837) warmap topology fix
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Thu, 16 Jan 2003 00:01:30 -0800
Reply-to: rt@xxxxxxxxxxxxxx

warmap.cost, warmap.seacost, and warmap.vector suffer from the same 
problem: their methods of indexing are not topology-safe.  If map.xsize 
and map.ysize are used as the "native" map dimensions (as Ross and I 
agree they should be), they cannot be used as dimensions for an array 
that is indexed with standard map coordinates.

The best solution is to use map_inx (aka map_to_index() in Ross's 
corecleanups) to index into the array.  It can then just be a 
single-dimension array, like map.tiles, hmap, etc.  The patch to 
accomplish this is long, but simple.  The savefiles from an autogame are 
left unchanged.

I was left behind by the path-finding discussion a while ago, but this 
concept should probably be kept in mind there as well.

jason

Index: ai/advmilitary.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v
retrieving revision 1.131
diff -u -r1.131 advmilitary.c
--- ai/advmilitary.c    2003/01/13 23:27:03     1.131
+++ ai/advmilitary.c    2003/01/16 07:26:00
@@ -314,14 +314,14 @@
   if (is_tiles_adjacent(punit->x, punit->y, pcity->x, pcity->y))
     distance = SINGLE_MOVE;
   else if (is_sailing_unit(punit))
-    distance = warmap.seacost[punit->x][punit->y];
+    distance = WARMAP_SEACOST(punit->x, punit->y);
   else if (!is_ground_unit(punit))
     distance = real_map_distance(punit->x, punit->y, pcity->x, pcity->y)
                * SINGLE_MOVE;
   else if (unit_flag(punit, F_IGTER))
     distance = real_map_distance(punit->x, punit->y, pcity->x, pcity->y);
   else
-    distance = warmap.cost[punit->x][punit->y];
+    distance = WARMAP_COST(punit->x, punit->y);
 
   /* If distance = 9, a chariot is 1.5 turns away.  NOT 2 turns away. */
   if (distance < SINGLE_MOVE) distance = SINGLE_MOVE;
@@ -330,7 +330,7 @@
       && find_beachhead(punit, pcity->x, pcity->y, &x, &y) != 0) {
     /* Sea travellers. */
 
-    y = warmap.seacost[punit->x][punit->y];
+    y = WARMAP_SEACOST(punit->x, punit->y);
     if (y >= 6 * THRESHOLD)
       y = real_map_distance(pcity->x, pcity->y, punit->x, punit->y) * 
SINGLE_MOVE;
 
@@ -455,7 +455,7 @@
                  ? 4 * SINGLE_MOVE : 2 * SINGLE_MOVE); /* likely speed */
     boatid = find_boat(aplayer, &x, &y, 0); /* acquire a boat */
     if (boatid != 0) {
-      boatdist = warmap.seacost[x][y]; /* distance to acquired boat */
+      boatdist = WARMAP_SEACOST(x, y); /* distance to acquired boat */
     } else {
       boatdist = -1; /* boat wanted */
     }
@@ -1085,7 +1085,7 @@
       = unit_list_size(&(map_get_tile(acity->x, acity->y)->units)) + 1;
     
     go_by_boat = !(goto_is_sane(myunit, acity->x, acity->y, TRUE) 
-                  && warmap.cost[x][y] <= (MIN(6, move_rate) * THRESHOLD));
+                  && WARMAP_COST(x, y) <= (MIN(6, move_rate) * THRESHOLD));
     
     move_time = turns_to_enemy_city(myunit->type, acity, move_rate, go_by_boat,
                                     ferryboat, boattype);
@@ -1476,7 +1476,7 @@
 
   pcity->ai.downtown = 0;
   city_list_iterate(pplayer->cities, othercity) {
-    distance = warmap.cost[othercity->x][othercity->y];
+    distance = WARMAP_COST(othercity->x, othercity->y);
     if (wonder_continent != 0
         && map_get_continent(othercity->x, othercity->y, NULL) 
              == wonder_continent) {
Index: ai/aidiplomat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidiplomat.c,v
retrieving revision 1.8
diff -u -r1.8 aidiplomat.c
--- ai/aidiplomat.c     2003/01/09 02:36:36     1.8
+++ ai/aidiplomat.c     2003/01/16 07:26:01
@@ -192,7 +192,7 @@
     /* Probability to lose our unit */
     p_failure = (unit_type_flag(u, F_SPY) ? 100 - p_success : 100);
 
-    time_to_dest = warmap.cost[acity->x][acity->y] / ut->move_rate;
+    time_to_dest = WARMAP_COST(acity->x, acity->y) / ut->move_rate;
     time_to_dest *= (time_to_dest/2); /* No long treks, please */
 
     /* Almost kill_desire */
@@ -342,7 +342,7 @@
       }
 
       incite_cost = city_incite_cost(pplayer, acity);
-      move_cost = warmap.cost[acity->x][acity->y];
+      move_cost = WARMAP_COST(acity->x, acity->y);
       dipldef = (count_diplomats_on_tile(acity->x, acity->y) > 0);
       /* Three actions to consider:
        * 1. establishing embassy OR
@@ -398,7 +398,7 @@
       urgency /= 3;
     }
 
-    dist = warmap.cost[acity->x][acity->y];
+    dist = WARMAP_COST(acity->x, acity->y);
     /* This formula may not be optimal, but it works. */
     if (dist > best_dist) {
       /* punish city for being so far away */
@@ -436,7 +436,7 @@
   /* Check ALL possible targets */
   whole_map_iterate(x, y) {
     ptile = map_get_tile(x, y);
-    if (warmap.cost[x][y] > move_rate && !is_ocean(ptile->terrain)) {
+    if (WARMAP_COST(x, y) > move_rate && !is_ocean(ptile->terrain)) {
       /* Can't get there */
       continue;
     }
@@ -446,8 +446,8 @@
       /* Try to bribe a ship on the coast */
       int best = 9999;
       adjc_iterate(x, y, x2, y2) {
-        if (best > warmap.cost[x2][y2]) {
-          best = warmap.cost[x2][y2];
+        if (best > WARMAP_COST(x2, y2)) {
+          best = WARMAP_COST(x2, y2);
           destx = x2;
           desty = y2;
         }
@@ -487,7 +487,7 @@
       /* Compare with victim's attack power */
       newval = ATTACK_POWER(pvictim);
       if (newval > bestval 
-          && unit_type(pvictim)->move_rate > warmap.cost[x][y]) {
+          && unit_type(pvictim)->move_rate > WARMAP_COST(x, y)) {
         /* Enemy can probably kill us */
         threat = TRUE;
       } else {
@@ -653,7 +653,7 @@
     UNIT_LOG(LOG_DIPLOMAT, punit, "attack, dist %d to %s (%s goto)"
              "[%d mc]", dist, ctarget ? ctarget->name : "(none)", 
              punit->activity == ACTIVITY_GOTO ? "has" : "no",
-             warmap.cost[punit->goto_dest_x][punit->goto_dest_y]);
+             WARMAP_COST(punit->goto_dest_x, punit->goto_dest_y));
     if (dist == 1) {
       /* Do our stuff */
       ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.253
diff -u -r1.253 aiunit.c
--- ai/aiunit.c 2003/01/12 22:24:04     1.253
+++ ai/aiunit.c 2003/01/16 07:26:03
@@ -203,7 +203,7 @@
     if (unit_flag(punit, F_IGTER)) {
       move_rate *= 3;
     }
-    move_time = warmap.cost[x][y] / move_rate;
+    move_time = WARMAP_COST(x, y) / move_rate;
     break;
  
   case SEA_MOVING:
@@ -221,7 +221,7 @@
         move_rate += SINGLE_MOVE;
     }
       
-    move_time = warmap.seacost[x][y] / move_rate;
+    move_time = WARMAP_SEACOST(x, y) / move_rate;
     break;
  
   case HELI_MOVING:
@@ -320,13 +320,13 @@
      * the nearest is used. */
     iterate_outward(x, y, maxmoves, x1, y1) {
       if (map_has_special(x1, y1, S_HUT)
-          && warmap.cost[x1][y1] < bestcost
+          && WARMAP_COST(x1, y1) < bestcost
           && (!ai_handicap(pplayer, H_HUTS) || map_get_known(x1, y1, pplayer))
           && tile_is_accessible(punit, x1, y1)
           && ai_fuzzy(pplayer, TRUE)) {
         best_x = x1;
         best_y = y1;
-        bestcost = warmap.cost[best_x][best_y];
+        bestcost = WARMAP_COST(best_x, best_y);
       }
     } iterate_outward_end;
     
@@ -484,9 +484,9 @@
           int threshold = THRESHOLD * move_rate;
           
           if (is_sailing_unit(punit))
-            unknown += COSTWEIGHT * (threshold - warmap.seacost[x1][y1]);
+            unknown += COSTWEIGHT * (threshold - WARMAP_SEACOST(x1, y1));
           else
-            unknown += COSTWEIGHT * (threshold - warmap.cost[x1][y1]);
+            unknown += COSTWEIGHT * (threshold - WARMAP_COST(x1, y1));
           
           /* FIXME? Why we don't do same tests like in part 2? --pasky */
           if (((unknown > most_unknown) ||
@@ -1093,7 +1093,7 @@
   adjc_iterate(dest_x, dest_y, x1, y1) {
     ok = 0;
     t = map_get_terrain(x1, y1);
-    if (warmap.seacost[x1][y1] <= 6 * THRESHOLD && !is_ocean(t)) {
+    if (WARMAP_SEACOST(x1, y1) <= 6 * THRESHOLD && !is_ocean(t)) {
       /* accessible beachhead */
       adjc_iterate(x1, y1, x2, y2) {
        if (is_ocean(map_get_terrain(x2, y2))
@@ -1116,7 +1116,7 @@
         if (get_tile_type(t)->movement_cost * SINGLE_MOVE <
             unit_type(punit)->move_rate)
          ok *= 8;
-        ok += (6 * THRESHOLD - warmap.seacost[x1][y1]);
+        ok += (6 * THRESHOLD - WARMAP_SEACOST(x1, y1));
         if (ok > best) {
          best = ok;
          *x = x1;
@@ -1569,7 +1569,7 @@
   case LAND_MOVING:
     if (go_by_boat) {
       int boatspeed = unit_types[boattype].move_rate;
-      int move_time = (warmap.seacost[acity->x][acity->y]) / boatspeed;
+      int move_time = (WARMAP_SEACOST(acity->x, acity->y)) / boatspeed;
       
       if (unit_type_flag(boattype, F_TRIREME) && move_time > 2) {
         /* FIXME: Should also check for LIGHTHOUSE */
@@ -1578,7 +1578,7 @@
       }
       if (boat) {
         /* Time to get to the boat */
-        move_time += (warmap.cost[boat->x][boat->y] + speed - 1) / speed;
+        move_time += (WARMAP_COST(boat->x, boat->y) + speed - 1) / speed;
       }
       
       if (!unit_type_flag(our_type, F_MARINES)) {
@@ -1589,11 +1589,11 @@
       return move_time;
     } else {
       /* We are walking */
-      return (warmap.cost[acity->x][acity->y] + speed - 1) / speed;
+      return (WARMAP_COST(acity->x, acity->y) + speed - 1) / speed;
     }
   case SEA_MOVING:
     /* We are a boat: time to sail */
-    return (warmap.seacost[acity->x][acity->y] + speed - 1) / speed;
+    return (WARMAP_SEACOST(acity->x, acity->y) + speed - 1) / speed;
   default: 
     freelog(LOG_ERROR, "ERROR: Unsupported move_type in time_to_enemy_city");
     /* Return something prohibitive */
@@ -1615,10 +1615,10 @@
 
   switch(unit_types[our_type].move_type) {
   case LAND_MOVING:
-    dist = warmap.cost[x][y];
+    dist = WARMAP_COST(x, y);
     break;
   case SEA_MOVING:
-    dist = warmap.seacost[x][y];
+    dist = WARMAP_SEACOST(x, y);
     break;
   default:
     /* Compiler warning */
@@ -1842,7 +1842,7 @@
     city_list_iterate(aplayer->cities, acity) {
       bool go_by_boat = (is_ground_unit(punit)
                          && !(goto_is_sane(punit, acity->x, acity->y, TRUE) 
-                              && warmap.cost[acity->x][acity->y] < maxd));
+                              && WARMAP_COST(acity->x, acity->y) < maxd));
 
       if (handicap && !map_get_known(acity->x, acity->y, pplayer)) {
         /* Can't see it */
@@ -1851,13 +1851,13 @@
 
       if (go_by_boat 
           && (!(ferryboat || harbor)
-              || warmap.seacost[acity->x][acity->y] > 6 * THRESHOLD)) {
+              || WARMAP_SEACOST(acity->x, acity->y) > 6 * THRESHOLD)) {
         /* Too far or impossible to go by boat */
         continue;
       }
       
       if (is_sailing_unit(punit) 
-          && warmap.seacost[acity->x][acity->y] >= maxd) {
+          && WARMAP_SEACOST(acity->x, acity->y) >= maxd) {
         /* Too far to sail */
         continue;
       }
@@ -2014,14 +2014,14 @@
 
       if (is_ground_unit(punit) 
           && (map_get_continent(aunit->x, aunit->y, NULL) != con 
-              || warmap.cost[aunit->x][aunit->y] >= maxd)) {
+              || WARMAP_COST(aunit->x, aunit->y) >= maxd)) {
         /* Impossible or too far to walk */
         continue;
       }
 
       if (is_sailing_unit(punit)
           && (!goto_is_sane(punit, aunit->x, aunit->y, TRUE)
-              || warmap.seacost[aunit->x][aunit->y] >= maxd)) {
+              || WARMAP_SEACOST(aunit->x, aunit->y) >= maxd)) {
         /* Impossible or too far to sail */
         continue;
       }
@@ -2084,14 +2084,14 @@
     if (pplayers_allied(pplayer,aplayer)) {
       city_list_iterate(aplayer->cities, pcity) {
         if (ground) {
-          cur = warmap.cost[pcity->x][pcity->y];
+          cur = WARMAP_COST(pcity->x, pcity->y);
           if (city_got_building(pcity, B_BARRACKS)
               || city_got_building(pcity, B_BARRACKS2)
               || city_got_building(pcity, B_BARRACKS3)) {
             cur /= 3;
           }
         } else {
-          cur = warmap.seacost[pcity->x][pcity->y];
+          cur = WARMAP_SEACOST(pcity->x, pcity->y);
           if (city_got_building(pcity, B_PORT)) {
             cur /= 3;
           }
@@ -2390,14 +2390,15 @@
   best = 9999;
   x = -1; y = -1;
   unit_list_iterate(pplayer->units, aunit) {
-    if (aunit->ai.ferryboat != 0 && warmap.seacost[aunit->x][aunit->y] < best 
&&
-       ground_unit_transporter_capacity(aunit->x, aunit->y, pplayer) <= 0
+    if (aunit->ai.ferryboat != 0
+       && WARMAP_SEACOST(aunit->x, aunit->y) < best
+       && ground_unit_transporter_capacity(aunit->x, aunit->y, pplayer) <= 0
         && is_at_coast(aunit->x, aunit->y)) {
       UNIT_LOG(LOG_DEBUG, punit, "Found a potential pickup %d@(%d, %d)",
                    aunit->id, aunit->x, aunit->y);
       x = aunit->x;
       y = aunit->y;
-      best = warmap.seacost[x][y];
+      best = WARMAP_SEACOST(x, y);
     }
     if (is_sailing_unit(aunit)
        && is_ocean(map_get_terrain(aunit->x, aunit->y))) {
@@ -2727,8 +2728,8 @@
        || map_get_continent(aunit->x, aunit->y, NULL) != con)
       continue;
 
-    if (warmap.cost[aunit->x][aunit->y] < mindist) {
-      mindist = warmap.cost[aunit->x][aunit->y];
+    if (WARMAP_COST(aunit->x, aunit->y) < mindist) {
+      mindist = WARMAP_COST(aunit->x, aunit->y);
       closest_unit = aunit;
     }
   } unit_list_iterate_end;
@@ -2752,7 +2753,7 @@
          && map_get_continent(aunit->x, aunit->y, NULL) == con) {
        /* questionable assumption: aunit needs as many moves to reach us as we
           need to reach it */
-       dist = warmap.cost[aunit->x][aunit->y] - unit_move_rate(aunit);
+       dist = WARMAP_COST(aunit->x, aunit->y) - unit_move_rate(aunit);
        if (dist < mindist) {
          freelog(LOG_DEBUG, "Barbarian leader: closest enemy is %s at %d, %d, 
dist %d",
                   unit_name(aunit->type), aunit->x, aunit->y, dist);
@@ -2786,9 +2787,9 @@
            leader->moves_left);
 
     square_iterate(leader->x, leader->y, 1, x, y) {
-      if (warmap.cost[x][y] > safest
+      if (WARMAP_COST(x, y) > safest
          && could_unit_move_to_tile(leader, x, y) == 1) {
-       safest = warmap.cost[x][y];
+       safest = WARMAP_COST(x, y);
        freelog(LOG_DEBUG,
                "Barbarian leader: safest is %d, %d, safeness %d", x, y,
                safest);
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.160
diff -u -r1.160 gotohand.c
--- server/gotohand.c   2003/01/09 02:36:37     1.160
+++ server/gotohand.c   2003/01/16 07:26:05
@@ -184,14 +184,12 @@
 **************************************************************************/
 static void init_warmap(int orig_x, int orig_y, enum unit_move_type move_type)
 {
-  int x;
-
-  if (!warmap.cost[0]) {
-    for (x = 0; x < map.xsize; x++) {
-      warmap.cost[x]=fc_malloc(map.ysize*sizeof(unsigned char));
-      warmap.seacost[x]=fc_malloc(map.ysize*sizeof(unsigned char));
-      warmap.vector[x]=fc_malloc(map.ysize*sizeof(unsigned char));
-    }
+  if (!warmap.cost) {
+    warmap.cost = fc_malloc(map.xsize * map.ysize * sizeof(*warmap.cost));
+    warmap.seacost = fc_malloc(map.xsize * map.ysize
+                              * sizeof(*warmap.seacost));
+    warmap.vector = fc_malloc(map.xsize * map.ysize
+                             * sizeof(*warmap.vector));
   }
 
   init_queue();
@@ -200,14 +198,16 @@
   case LAND_MOVING:
   case HELI_MOVING:
   case AIR_MOVING:
-    for (x = 0; x < map.xsize; x++)
-      memset(warmap.cost[x], MAXCOST, map.ysize*sizeof(unsigned char));
-    warmap.cost[orig_x][orig_y] = 0;
+    whole_map_iterate(x, y) {
+      WARMAP_COST(x, y) = MAXCOST;
+    } whole_map_iterate_end;
+    WARMAP_COST(orig_x, orig_y) = 0;
     break;
   case SEA_MOVING:
-    for (x = 0; x < map.xsize; x++)
-      memset(warmap.seacost[x], MAXCOST, map.ysize*sizeof(unsigned char));
-    warmap.seacost[orig_x][orig_y] = 0;
+    whole_map_iterate(x, y) {
+      WARMAP_SEACOST(x, y) = MAXCOST;
+    } whole_map_iterate_end;
+    WARMAP_SEACOST(orig_x, orig_y) = 0;
     break;
   default:
     freelog(LOG_ERROR, "Bad move_type in init_warmap().");
@@ -289,7 +289,7 @@
     adjc_dir_iterate(x, y, x1, y1, dir) {
       switch (move_type) {
       case LAND_MOVING:
-       if (warmap.cost[x1][y1] <= warmap.cost[x][y])
+       if (WARMAP_COST(x1, y1) <= WARMAP_COST(x, y))
          continue; /* No need for all the calculations */
 
         if (is_ocean(map_get_terrain(x1, y1))) {
@@ -313,9 +313,9 @@
                       (ptile->move_cost[dir] > tmp ? 1 : 0))/2;
         }
 
-        move_cost += warmap.cost[x][y];
-        if (warmap.cost[x1][y1] > move_cost && move_cost < maxcost) {
-          warmap.cost[x1][y1] = move_cost;
+        move_cost += WARMAP_COST(x, y);
+        if (WARMAP_COST(x1, y1) > move_cost && move_cost < maxcost) {
+          WARMAP_COST(x1, y1) = move_cost;
           add_to_mapqueue(move_cost, x1, y1);
         }
        break;
@@ -323,12 +323,12 @@
 
       case SEA_MOVING:
         move_cost = SINGLE_MOVE;
-        move_cost += warmap.seacost[x][y];
-        if (warmap.seacost[x1][y1] > move_cost && move_cost < maxcost) {
+        move_cost += WARMAP_SEACOST(x, y);
+        if (WARMAP_SEACOST(x1, y1) > move_cost && move_cost < maxcost) {
          /* by adding the move_cost to the warmap regardless if we
             can move between we allow for shore bombardment/transport
             to inland positions/etc. */
-          warmap.seacost[x1][y1] = move_cost;
+          WARMAP_SEACOST(x1, y1) = move_cost;
          if (ptile->move_cost[dir] == MOVE_COST_FOR_VALID_SEA_STEP) {
            add_to_mapqueue(move_cost, x1, y1);
          }
@@ -372,8 +372,8 @@
      * correct (warmap.(sea)cost[x][y] == 0), reuse it.
      */
     if (warmap.warunit == punit &&
-       (is_sailing_unit(punit) ? (warmap.seacost[punit->x][punit->y] == 0)
-        : (warmap.cost[punit->x][punit->y] == 0))) {
+       (is_sailing_unit(punit) ? (WARMAP_SEACOST(punit->x, punit->y) == 0)
+        : (WARMAP_COST(punit->x, punit->y) == 0))) {
       return;
     }
 
@@ -565,7 +565,7 @@
    * Land/air units use warmap.cost while sea units use
    * warmap.seacost.  Don't ask me why.  --JDS 
    */
-  unsigned char **warmap_cost =
+  unsigned char *warmap_cost =
       (move_type == SEA_MOVING) ? warmap.seacost : warmap.cost;
 
   orig_x = punit->x;
@@ -620,7 +620,7 @@
 
       switch (move_type) {
       case LAND_MOVING:
-       if (warmap.cost[x1][y1] <= warmap.cost[x][y])
+       if (WARMAP_COST(x1, y1) <= WARMAP_COST(x, y))
          continue; /* No need for all the calculations. Note that this also 
excludes
                       RR loops, ie you can't create a cycle with the same 
move_cost */
 
@@ -683,11 +683,11 @@
        if (restriction == GOTO_MOVE_STRAIGHTEST && dir == straight_dir)
          move_cost /= SINGLE_MOVE;
 
-       total_cost = move_cost + warmap.cost[x][y];
+       total_cost = move_cost + WARMAP_COST(x, y);
        break;
 
       case SEA_MOVING:
-       if (warmap.seacost[x1][y1] <= warmap.seacost[x][y])
+       if (WARMAP_SEACOST(x1, y1) <= WARMAP_SEACOST(x, y))
          continue; /* No need for all the calculations */
 
        /* allow ships to target a shore */
@@ -723,11 +723,11 @@
        if ((restriction == GOTO_MOVE_STRAIGHTEST) && (dir == straight_dir))
          move_cost /= SINGLE_MOVE;
 
-       total_cost = move_cost + warmap.seacost[x][y];
+       total_cost = move_cost + WARMAP_SEACOST(x, y);
 
        /* For the ai, maybe avoid going close to enemies. */
        if (pplayer->ai.control &&
-           warmap.seacost[x][y] < punit->moves_left
+           WARMAP_SEACOST(x, y) < punit->moves_left
            && total_cost < maxcost
            && total_cost >= punit->moves_left - 
(get_transporter_capacity(punit) >
                              unit_type(punit)->attack_strength ? 3 : 2)
@@ -742,7 +742,7 @@
 
       case AIR_MOVING:
       case HELI_MOVING:
-       if (warmap.cost[x1][y1] <= warmap.cost[x][y])
+       if (WARMAP_COST(x1, y1) <= WARMAP_COST(x, y))
          continue; /* No need for all the calculations */
 
        move_cost = SINGLE_MOVE;
@@ -757,7 +757,7 @@
 
        if ((restriction == GOTO_MOVE_STRAIGHTEST) && (dir == straight_dir))
          move_cost /= SINGLE_MOVE;
-       total_cost = move_cost + warmap.cost[x][y];
+       total_cost = move_cost + WARMAP_COST(x, y);
        break;
 
       default:
@@ -767,14 +767,14 @@
 
       /* Add the route to our warmap if it is worth keeping */
       if (total_cost < maxcost) {
-       if (warmap_cost[x1][y1] > total_cost) {
-         warmap_cost[x1][y1] = total_cost;
+       if (warmap_cost[map_inx(x1, y1)] > total_cost) {
+         warmap_cost[map_inx(x1, y1)] = total_cost;
          add_to_mapqueue(total_cost, x1, y1);
          local_vector[x1][y1] = 1 << DIR_REVERSE(dir);
          freelog(LOG_DEBUG,
                  "Candidate: %s from (%d, %d) to (%d, %d), cost %d",
                  dir_get_name(dir), x, y, x1, y1, total_cost);
-       } else if (warmap_cost[x1][y1] == total_cost) {
+       } else if (warmap_cost[map_inx(x1, y1)] == total_cost) {
          local_vector[x1][y1] |= 1 << DIR_REVERSE(dir);
          freelog(LOG_DEBUG,
                  "Co-Candidate: %s from (%d, %d) to (%d, %d), cost %d",
@@ -798,8 +798,9 @@
 
   /*** Succeeded. The vector at the destination indicates which way we get 
there.
      Now backtrack to remove all the blind paths ***/
-  for (x = 0; x < map.xsize; x++)
-    memset(warmap.vector[x], 0, map.ysize*sizeof(unsigned char));
+  whole_map_iterate(x, y) {
+    WARMAP_VECTOR(x, y) = 0;
+  } whole_map_iterate_end;
 
   init_queue();
   add_to_mapqueue(0, dest_x, dest_y);
@@ -813,11 +814,13 @@
          && !DIR_IS_CARDINAL(dir)) continue;
 
       if (TEST_BIT(local_vector[x][y], dir)) {
-       move_cost = (move_type == SEA_MOVING) ? warmap.seacost[x1][y1] : 
warmap.cost[x1][y1];
+       move_cost = (move_type == SEA_MOVING)
+               ? WARMAP_SEACOST(x1, y1)
+               : WARMAP_COST(x1, y1);
 
         add_to_mapqueue(MAXCOST-1 - move_cost, x1, y1);
        /* Mark it on the warmap */
-       warmap.vector[x1][y1] |= 1 << DIR_REVERSE(dir); 
+       WARMAP_VECTOR(x1, y1) |= 1 << DIR_REVERSE(dir); 
         local_vector[x][y] -= 1<<dir; /* avoid repetition */
        freelog(LOG_DEBUG, "PATH-SEGMENT: %s from (%d, %d) to (%d, %d)",
                dir_get_name(DIR_REVERSE(dir)), x1, y1, x, y);
@@ -901,7 +904,7 @@
     int dir;
 
     if (base_get_direction_for_step(punit->x, punit->y, dest_x, dest_y, &dir)
-       && TEST_BIT(warmap.vector[punit->x][punit->y], dir)
+       && TEST_BIT(WARMAP_VECTOR(punit->x, punit->y), dir)
        && !(restriction == GOTO_MOVE_CARDINAL_ONLY
             && !DIR_IS_CARDINAL(dir))) {
       return dir;
@@ -926,7 +929,7 @@
     /* 
      * Is it an allowed direction?  is it marked on the warmap?
      */
-    if (!TEST_BIT(warmap.vector[punit->x][punit->y], dir)
+    if (!TEST_BIT(WARMAP_VECTOR(punit->x, punit->y), dir)
        || ((restriction == GOTO_MOVE_CARDINAL_ONLY)
            && !DIR_IS_CARDINAL(dir))) {
       /* make sure we don't select it later */
@@ -1429,9 +1432,9 @@
   generate_warmap(NULL, punit);
 
   if (is_sailing_unit(punit))
-    return warmap.seacost[dest_x][dest_y];
+    return WARMAP_SEACOST(dest_x, dest_y);
   else /* ground unit */
-    return warmap.cost[dest_x][dest_y];
+    return WARMAP_COST(dest_x, dest_y);
 }
 
 
@@ -1555,7 +1558,7 @@
 
   while (get_from_mapqueue(&x, &y)) {
     adjc_dir_iterate(x, y, x1, y1, dir) {
-      if (warmap.cost[x1][y1] != MAXCOST) {
+      if (WARMAP_COST(x1, y1) != MAXCOST) {
        continue;
       }
 
@@ -1566,17 +1569,17 @@
       if (same_pos(x1, y1, dest_x, dest_y)) {
        /* We're there! */
        freelog(LOG_DEBUG, "air_can_move_between: movecost: %i",
-               warmap.cost[x][y] + MOVE_COST_AIR);
+               WARMAP_COST(x, y) + MOVE_COST_AIR);
        /* The -MOVE_COST_AIR is because we haven't taken the final
           step yet. */
-       return moves - warmap.cost[x][y] - MOVE_COST_AIR;
+       return moves - WARMAP_COST(x, y) - MOVE_COST_AIR;
       }
 
       /* We refuse to goto through unsafe airspace. */
       if (airspace_looks_safe(x1, y1, pplayer)) {
-       int cost = warmap.cost[x][y] + MOVE_COST_AIR;
+       int cost = WARMAP_COST(x, y) + MOVE_COST_AIR;
 
-       warmap.cost[x1][y1] = cost;
+       WARMAP_COST(x1, y1) = cost;
 
        /* Now for A* we find the minimum total cost. */
        cost += real_map_distance(x1, y1, dest_x, dest_y);
Index: server/gotohand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.h,v
retrieving revision 1.22
diff -u -r1.22 gotohand.h
--- server/gotohand.h   2002/02/14 15:17:32     1.22
+++ server/gotohand.h   2003/01/16 07:26:05
@@ -46,14 +46,18 @@
 bool goto_is_sane(struct unit *punit, int x, int y, bool omni);
 
 struct move_cost_map {
-  unsigned char *cost[MAP_MAX_WIDTH];
-  unsigned char *seacost[MAP_MAX_WIDTH];
-  unsigned char *vector[MAP_MAX_WIDTH];
+  unsigned char *cost;
+  unsigned char *seacost;
+  unsigned char *vector;
   struct city *warcity; /* so we know what we're dealing with here */
   struct unit *warunit; /* so we know what we're dealing with here */
   int orig_x, orig_y;
 };
 
 extern struct move_cost_map warmap;
+
+#define WARMAP_COST(x, y) (warmap.cost[map_inx((x), (y))])
+#define WARMAP_SEACOST(x, y) (warmap.seacost[map_inx((x), (y))])
+#define WARMAP_VECTOR(x, y) (warmap.vector[map_inx((x), (y))])
 
 #endif  /* FC__GOTOHAND_H */
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.161
diff -u -r1.161 settlers.c
--- server/settlers.c   2003/01/09 02:36:37     1.161
+++ server/settlers.c   2003/01/16 07:26:06
@@ -760,12 +760,12 @@
   Unit_Type_id id = 0;
   unit_list_iterate(pplayer->units, aunit)
     if (is_ground_units_transport(aunit)) {
-      if (warmap.cost[aunit->x][aunit->y] < best &&
-         (warmap.cost[aunit->x][aunit->y] == 0 ||
+      if (WARMAP_COST(aunit->x, aunit->y) < best &&
+         (WARMAP_COST(aunit->x, aunit->y) == 0 ||
           ground_unit_transporter_capacity(aunit->x, aunit->y,
                                            pplayer) >= cap)) {
         id = aunit->id;
-        best = warmap.cost[aunit->x][aunit->y];
+        best = WARMAP_COST(aunit->x, aunit->y);
         *x = aunit->x;
         *y = aunit->y;
       }
@@ -778,9 +778,9 @@
         unit_types[pcity->currently_building].transport_capacity &&
         !unit_flag(pcity->currently_building, F_CARRIER) &&
        !unit_flag(pcity->currently_building, F_MISSILE_CARRIER)) {
-      if (warmap.cost[pcity->x][pcity->y] < best) {
+      if (WARMAP_COST(pcity->x, pcity->y) < best) {
         id = pcity->id;
-        best = warmap.cost[pcity->x][pcity->y];
+        best = WARMAP_COST(pcity->x, pcity->y);
         *x = pcity->x;
         *y = pcity->y;
       }
@@ -944,11 +944,11 @@
        if (!is_ocean_near_tile(x, y)) {
          mv_cost = 9999;
        } else {
-         mv_cost = warmap.seacost[x][y] * mv_rate /
+         mv_cost = WARMAP_SEACOST(x, y) * mv_rate /
              unit_type(*ferryboat)->move_rate;
        }
       } else if (!goto_is_sane(punit, x, y, TRUE) ||
-                warmap.cost[x][y] > THRESHOLD * mv_rate) {
+                WARMAP_COST(x, y) > THRESHOLD * mv_rate) {
        /* for Rome->Carthage */
        if (!is_ocean_near_tile(x, y)) {
          mv_cost = 9999;
@@ -956,20 +956,20 @@
          if (punit->id == 0 && mycity->id == boatid) {
            w_virtual = TRUE;
          }
-         mv_cost = warmap.cost[bx][by] + real_map_distance(bx, by, x, y)
+         mv_cost = WARMAP_COST(bx, by) + real_map_distance(bx, by, x, y)
            + mv_rate; 
        } else if (punit->id != 0 ||
                   !is_ocean_near_tile(mycity->x, mycity->y)) {
          mv_cost = 9999;
        } else {
-         mv_cost = warmap.seacost[x][y] * mv_rate / 9;
+         mv_cost = WARMAP_SEACOST(x, y) * mv_rate / 9;
          /* this should be fresh; the only thing that could have
             munged the seacost is the ferryboat code in
             k_s_w/f_s_t_k, but only if find_boat succeeded */
          w_virtual = TRUE;
        }
       } else {
-       mv_cost = warmap.cost[x][y];
+       mv_cost = WARMAP_COST(x, y);
       }
       moves = mv_cost / mv_rate;
       /* without this, the computer will go 6-7 tiles from X to
@@ -1077,7 +1077,7 @@
        continue;
       in_use = (get_worker_city(pcity, i, j) == C_TILE_WORKER);
       if (map_get_continent(x, y, pplayer) == ucont
-         && warmap.cost[x][y] <= THRESHOLD * mv_rate
+         && WARMAP_COST(x, y) <= THRESHOLD * mv_rate
          && !BV_CHECK_MASK(territory[x][y], my_enemies)
          /* pretty good, hope it's enough! -- Syela */
          && !is_already_assigned(punit, pplayer, x, y)) {
@@ -1085,7 +1085,7 @@
           for obvious reasons;  structure is much the same as it once
           was but subroutines are not -- Syela */
        int time;
-       mv_turns = (warmap.cost[x][y]) / mv_rate;
+       mv_turns = (WARMAP_COST(x, y)) / mv_rate;
        oldv = city_tile_value(pcity, i, j, 0, 0);
 
        /* now, consider various activities... */

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#2837) warmap topology fix, Jason Short via RT <=