Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2003:
[Freeciv-Dev] (PR#2715) introducing tech_type_iterate
Home

[Freeciv-Dev] (PR#2715) introducing tech_type_iterate

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#2715) introducing tech_type_iterate
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Fri, 3 Jan 2003 22:25:45 -0800
Reply-to: rt@xxxxxxxxxxxxxx

After the patch to add tech graphics to the client, I noticed (again)
that several desirable iterators are missing.  One of them is
tech_type_iterate, which is provided by the attached patch.

The concept is muddied by the existence of A_NONE and also by
"non-existent" techs.

A_NONE==0 is hard-coded as a placeholder, empty tech.  tech_type_iterate
should skip it and start with A_FIRST.  But many loops don't do this;
they just start with 0.  I suspect most of these loops simply don't
realize that A_NONE is irrelevant, but I haven't changed any of them yet
(another patch can go over them in detail).  The one exception is the
loop Rafal and I just added in tilespec.c.

tech_exists can be called to tell if a tech exists.  This isn't a very
helpful explanation, and in fact it's not a very helpful function.  It
will check for out-of-range techs (<0 or >= game.num_techs).  But it
will return TRUE for A_NONE and FALSE for "non-existent" techs.  An
example of a non-existent tech is environmentalism - it exists in the
default ruleset but is impossible to research.  Per speculated that
these techs were kept around from when the techs were hard-coded in the
program, and said Raimar wanted to get rid of them.  But for now I just
ignore the possibility when iterating, so tech_exists is NOT checked. 
It could probably just as easily be done the other way (but none of the
callers except the tilespec one bother with it, so I didn't either).

jason


Index: ai/aidiplomat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidiplomat.c,v
retrieving revision 1.5
diff -u -r1.5 aidiplomat.c
--- ai/aidiplomat.c     2003/01/02 11:59:29     1.5
+++ ai/aidiplomat.c     2003/01/04 06:15:07
@@ -79,14 +79,14 @@
 ******************************************************************************/
 static int count_stealable_techs(struct player *pplayer, struct player 
*tplayer)
 {
-  int index, count = 0;
+  int count = 0;
 
-  for (index = A_FIRST; index < game.num_tech_types; index++) {
+  tech_type_iterate(index) {
     if ((get_invention(pplayer, index) != TECH_KNOWN)
         && (get_invention(tplayer, index) == TECH_KNOWN)) {
       count++;
     }
-  }
+  } tech_type_iterate_end;
 
   return count;
 }
Index: ai/aitech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitech.c,v
retrieving revision 1.37
diff -u -r1.37 aitech.c
--- ai/aitech.c 2002/12/21 11:44:00     1.37
+++ ai/aitech.c 2003/01/04 06:15:07
@@ -110,7 +110,7 @@
 static void ai_select_tech(struct player *pplayer, struct ai_choice *choice,
                           struct ai_choice *gol)
 {
-  Tech_Type_id i, k, l;
+  Tech_Type_id k, l;
   int j;
   int num_cities_nonzero;
   int values[A_LAST];
@@ -120,25 +120,25 @@
     num_cities_nonzero = 1;
   memset(values, 0, sizeof(values));
   memset(goal_values, 0, sizeof(goal_values));
-  for (i = A_FIRST; i < game.num_tech_types; i++) {
+  tech_type_iterate(i) {
     j = num_unknown_techs_for_goal(pplayer, i);
     if (j > 0) { /* if we already got it we don't want it */
       values[i] += pplayer->ai.tech_want[i];
-      for (k = A_FIRST; k < game.num_tech_types; k++) {
+      tech_type_iterate(k) {
        if (is_tech_a_req_for_goal(pplayer, k, i)) {
          values[k] += pplayer->ai.tech_want[i] / j;
        }
-      }
+      } tech_type_iterate_end;
     }
-  }
+  } tech_type_iterate_end;
 
-  for (i = A_FIRST; i < game.num_tech_types; i++) {
+  tech_type_iterate(i) {
     if (num_unknown_techs_for_goal(pplayer, i) > 0) {
-      for (k = A_FIRST; k < game.num_tech_types; k++) {
+      tech_type_iterate(k) {
        if (is_tech_a_req_for_goal(pplayer, k, i)) {
           goal_values[i] += values[k];
         }
-      }
+      } tech_type_iterate_end;
       goal_values[i] += values[i];
       
 /* this is the best I could do.  It still sometimes does freaky stuff like
@@ -152,13 +152,13 @@
                values[i], goal_values[i]);
       }
     } else goal_values[i] = 0;
-  }
+  } tech_type_iterate_end;
 
   l = A_NONE; k = A_NONE;
-  for (i = A_FIRST; i < game.num_tech_types; i++) {
+  tech_type_iterate(i) {
     if (values[i] > values[l] && get_invention(pplayer, i) == TECH_REACHABLE) 
l = i;
     if (goal_values[i] > goal_values[k]) k = i;
-  }
+  } tech_type_iterate_end;
   freelog(LOG_DEBUG, "%s wants %s with desire %d (%d).", pplayer->name,
                advances[l].name, values[l], pplayer->ai.tech_want[l]);
   if (choice) {
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.57
diff -u -r1.57 helpdata.c
--- client/helpdata.c   2002/12/11 10:39:41     1.57
+++ client/helpdata.c   2003/01/04 06:15:07
@@ -254,7 +254,7 @@
            }
          } unit_type_iterate_end;
        } else if(current_type==HELP_TECH) {
-         for(i=A_FIRST; i<game.num_tech_types; i++) {  /* skip A_NONE */
+         tech_type_iterate(i) {
            if(tech_exists(i)) {
              pitem = new_help_item(current_type);
              my_snprintf(name, sizeof(name), " %s", advances[i].name);
@@ -262,7 +262,7 @@
              pitem->text = mystrdup("");
              genlist_insert(&category_nodes, pitem, -1);
            }
-         }
+         } tech_type_iterate_end;
        } else if(current_type==HELP_TERRAIN) {
          for(i=T_FIRST; i<T_COUNT; i++) {
            if(*(tile_types[i].terrain_name) != '\0') {
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.103
diff -u -r1.103 tilespec.c
--- client/tilespec.c   2003/01/03 08:58:47     1.103
+++ client/tilespec.c   2003/01/04 06:15:10
@@ -334,11 +334,9 @@
   impr_type_iterate(imp_id) {
     tilespec_setup_impr_type(imp_id);
   } impr_type_iterate_end;
-  for (id = 0; id < game.num_tech_types; id++) {
-    if (tech_exists(id)) {
-      tilespec_setup_tech_type(id);
-    }
-  }
+  tech_type_iterate(tech_id) {
+    tilespec_setup_tech_type(tech_id);
+  } tech_type_iterate_end;
 
   /* tilespec_load_tiles reverts the city tile pointers to 0.  This
      is a workaround. */
Index: common/tech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.c,v
retrieving revision 1.53
diff -u -r1.53 tech.c
--- common/tech.c       2002/12/18 17:36:19     1.53
+++ common/tech.c       2003/01/04 06:15:10
@@ -115,7 +115,6 @@
 **************************************************************************/
 static void build_required_techs(struct player *pplayer, Tech_Type_id goal)
 {
-  Tech_Type_id i;
   int counter;
 
   memset(pplayer->research.inventions[goal].required_techs, 0,
@@ -135,7 +134,7 @@
   pplayer->research.inventions[goal].num_required_techs = 1;
 
   counter = 0;
-  for (i = A_FIRST; i < game.num_tech_types; i++) {
+  tech_type_iterate(i) {
     if (!is_tech_a_req_for_goal(pplayer, i, goal)) {
       continue;
     }
@@ -150,7 +149,7 @@
     pplayer->research.inventions[goal].num_required_techs++;
     pplayer->research.inventions[goal].bulbs_required +=
        base_total_bulbs_required(pplayer, i);
-  }
+  } tech_type_iterate_end;
 
   /* Undo the changes made above */
   pplayer->research.techs_researched -= counter;
@@ -185,11 +184,11 @@
   for (flag = 0; flag < TF_LAST; flag++) {
     pplayer->research.num_known_tech_with_flag[flag] = 0;
 
-    for (i = A_FIRST; i < game.num_tech_types; i++) {
+    tech_type_iterate(i) {
       if (get_invention(pplayer, i) == TECH_KNOWN && tech_flag(i, flag)) {
        pplayer->research.num_known_tech_with_flag[flag]++;
       }
-    }
+    } tech_type_iterate_end;
   }
 }
 
@@ -506,13 +505,12 @@
 **************************************************************************/
 void precalc_tech_data()
 {
-  Tech_Type_id tech;
   bool counted[A_LAST];
 
-  for (tech = A_FIRST; tech < game.num_tech_types; tech++) {
+  tech_type_iterate(tech) {
     memset(counted, 0, sizeof(counted));
     advances[tech].num_reqs = precalc_tech_data_helper(tech, counted);
-  }
+  } tech_type_iterate_end;
 }
 
 /**************************************************************************
@@ -577,9 +575,8 @@
 ***************************************************************/
 void techs_free(void)
 {
-  Tech_Type_id i;
-
-  for (i = A_FIRST; i < game.num_tech_types; i++) {
+  /* Skip A_NONE */
+  tech_type_iterate(i) {
     tech_free(i);
-  }
+  } tech_type_iterate_end;
 }
Index: common/tech.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.h,v
retrieving revision 1.37
diff -u -r1.37 tech.h
--- common/tech.h       2003/01/03 08:58:47     1.37
+++ common/tech.h       2003/01/04 06:15:10
@@ -124,4 +124,13 @@
 
 extern struct advance advances[];
 
+#define tech_type_iterate(tech_id)                                          \
+{                                                                           \
+  Tech_Type_id tech_id;                                                     \
+  for (tech_id = A_FIRST; tech_id < game.num_tech_types; tech_id++) {
+
+#define tech_type_iterate_end                                               \
+  }                                                                         \
+}
+
 #endif  /* FC__TECH_H */
Index: server/diplomats.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.c,v
retrieving revision 1.33
diff -u -r1.33 diplomats.c
--- server/diplomats.c  2002/12/11 10:39:42     1.33
+++ server/diplomats.c  2003/01/04 06:15:10
@@ -500,7 +500,7 @@
                       struct city  *pcity, int technology)
 {
   struct player *cplayer;
-  int index, count, which, target;
+  int count, which, target;
 
   /* Fetch target civilization's player.  Sanity checks. */
   if (!pcity)
@@ -558,12 +558,12 @@
 
   /* Examine the civilization for technologies to steal. */
   count = 0;
-  for (index = A_FIRST; index < game.num_tech_types; index++) {
+  tech_type_iterate(index) {
     if ((get_invention (pplayer, index) != TECH_KNOWN) &&
        (get_invention (cplayer, index) == TECH_KNOWN)) {
       count++;
     }
-  }
+  } tech_type_iterate_end;
 
   freelog (LOG_DEBUG, "steal-tech: count of technologies: %d", count);
 
@@ -589,7 +589,7 @@
     /* Pick random technology to steal. */
     target = -1;
     which = myrand (count);
-    for (index = A_FIRST; index < game.num_tech_types; index++) {
+    tech_type_iterate(index) {
       if ((get_invention (pplayer, index) != TECH_KNOWN) &&
          (get_invention (cplayer, index) == TECH_KNOWN)) {
        if (which > 0) {
@@ -599,7 +599,7 @@
          break;
        }
       }
-    }
+    } tech_type_iterate_end;
     freelog (LOG_DEBUG, "steal-tech: random: targeted technology: %d (%s)",
             target, advances[target].name);
   } else {
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.128
diff -u -r1.128 ruleset.c
--- server/ruleset.c    2003/01/03 08:58:48     1.128
+++ server/ruleset.c    2003/01/04 06:15:11
@@ -554,7 +554,7 @@
      Non-removed techs depending on removed techs is too
      broken to fix by default, so die.
   */   
-  for( i=A_FIRST; i<game.num_tech_types; i++ ) {
+  tech_type_iterate(i) {
     if (tech_exists(i)) {
       a = &advances[i];
       if (!tech_exists(a->req[0])) {
@@ -568,7 +568,7 @@
        exit(EXIT_FAILURE);
       }
     }
-  } 
+  } tech_type_iterate_end;
 
   precalc_tech_data();
 

[Prev in Thread] Current Thread [Next in Thread]