Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#10128) improve eff building code
Home

[Freeciv-Dev] (PR#10128) improve eff building code

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10128) improve eff building code
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Wed, 15 Sep 2004 03:43:59 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=10128 >

CHANGES:
 - city_range_iterate iterator, which I think can be useful several places
 - move some duplicated code into new function city_want()
 - use the two above to make base_want() prettier and more bug-resistant
 - improve logging a little bit
 - kludgefix EFT_PROD_TO_GOLD want
 - add evaluation of EFT_INCITE_DIST_PCT and EFT_MAKE_CONTENT_MIL_PER
 - add ceiling on evaluation of EFT_AIRLIFT + comment on its brokeness

  - Per

Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.163
diff -u -r1.163 aicity.c
--- ai/aicity.c 13 Sep 2004 15:54:49 -0000      1.163
+++ ai/aicity.c 15 Sep 2004 10:27:13 -0000
@@ -53,6 +53,20 @@
 
 #include "aicity.h"
 
+/* Iterate over cities within a certain range around a given city
+ * (city_here) that exist within a given city list. */
+#define city_range_iterate(city_here, list, range, city)            \
+{                                                                   \
+  Continent_id continent = map_get_continent(pcity->x, pcity->y);   \
+  city_list_iterate(list, city) {                                   \
+    if ((range == EFR_CITY && city == city_here)                    \
+        || (range == EFR_LOCAL && acity == city_here)               \
+        || (range == EFR_CONTINENT                                  \
+            && map_get_continent(city->x, city->y) == continent)    \
+        || (range == EFR_PLAYER)) {
+#define city_range_iterate_end \
+  } } } city_list_iterate_end;
+
 #define CITY_EMERGENCY(pcity)                        \
  (pcity->shield_surplus < 0 || city_unhappy(pcity)   \
   || pcity->food_stock + pcity->food_surplus < 0)
@@ -87,6 +101,29 @@
 }
 
 /**************************************************************************
+  Calculates city want from some input values.
+**************************************************************************/
+static inline int city_want(struct city *acity, struct ai_data *ai,
+                            int food, int shields, int sci, int lux, int tax)
+{
+  int want = 0;
+
+  want += food * ai->food_priority;
+  want += ((shields * get_city_shield_bonus(acity)) / 100) 
+          * ai->shield_priority;
+  want -= city_pollution(acity, shields) * ai->pollution_priority;
+  want += ((lux * get_city_luxury_bonus(acity)) / 100)
+          * ai->luxury_priority;
+  want += ((sci * get_city_science_bonus(acity)) / 100)
+          * ai->science_priority;
+  want += ((city_gold_surplus(acity, tax) 
+          * get_city_tax_bonus(acity)) / 100)
+          * ai->gold_priority;
+
+  return want;
+}
+
+/**************************************************************************
   Calculates want for some buildings by actually adding the building and
   measuring the effect.
 **************************************************************************/
@@ -95,7 +132,6 @@
 {
   struct ai_data *ai = ai_data_get(pplayer);
   int final_want = 0;
-  Continent_id continent = map_get_continent(pcity->x, pcity->y);
   struct city *capital = find_palace(pplayer);
 
   if (ai->impr_calc[id] == AI_IMPR_ESTIMATE) {
@@ -103,60 +139,26 @@
   }
 
   /* First calculate current worth */
-  city_list_iterate(pplayer->cities, acity) {
-    if ((ai->impr_range[id] == EFR_CITY && acity == pcity)
-        || (ai->impr_range[id] == EFR_LOCAL && acity == pcity)
-        || (ai->impr_range[id] == EFR_CONTINENT
-            && map_get_continent(acity->x, acity->y) == continent)
-        || (ai->impr_range[id] == EFR_PLAYER)) {
-      int food, trade, shields, lux, sci, tax, want = 0;
-
-      get_food_trade_shields(acity, &food, &trade, &shields);
-      get_tax_income(pplayer, trade, &sci, &lux, &tax);
-
-      want += food * ai->food_priority;
-      want += ((shields * get_city_shield_bonus(acity)) / 100) 
-              * ai->shield_priority;
-      want -= city_pollution(acity, shields) * ai->pollution_priority;
-      want += ((lux * get_city_luxury_bonus(acity)) / 100)
-              * ai->luxury_priority;
-      want += ((sci * get_city_science_bonus(acity)) / 100)
-              * ai->science_priority;
-      want += ((city_gold_surplus(acity, tax) 
-                * get_city_tax_bonus(acity)) / 100)
-              * ai->gold_priority;
-      acity->ai.worth = want;
-    }
-  } city_list_iterate_end;
+  city_range_iterate(pcity, pplayer->cities, ai->impr_range[id], acity) {
+    int food, trade, shields, lux, sci, tax;
+
+    get_food_trade_shields(acity, &food, &trade, &shields);
+    get_tax_income(pplayer, trade, &sci, &lux, &tax);
+    acity->ai.worth = city_want(acity, ai, food, shields, sci, lux, tax);
+  } city_range_iterate_end;
 
   /* Add the improvement */
   city_add_improvement(pcity, id);
 
   /* Stir, then compare notes */
-  city_list_iterate(pplayer->cities, acity) {
-    if ((ai->impr_range[id] == EFR_CITY && acity == pcity)
-        || (ai->impr_range[id] == EFR_LOCAL && acity == pcity)
-        || (ai->impr_range[id] == EFR_CONTINENT
-            && map_get_continent(acity->x, acity->y) == continent)
-        || (ai->impr_range[id] == EFR_PLAYER)) {
-      int food, trade, shields, lux, sci, tax, want = 0;
-
-      get_food_trade_shields(acity, &food, &trade, &shields);
-      get_tax_income(pplayer, trade, &sci, &lux, &tax);
-      want += food * ai->food_priority;
-      want += ((shields * get_city_shield_bonus(acity)) / 100) 
-              * ai->shield_priority;
-      want -= city_pollution(acity, shields) * ai->pollution_priority;
-      want += ((lux * get_city_luxury_bonus(acity)) / 100)
-              * ai->luxury_priority;
-      want += ((sci * get_city_science_bonus(acity)) / 100)
-              * ai->science_priority;
-      want += ((city_gold_surplus(acity, tax) 
-                * get_city_tax_bonus(acity)) / 100)
-              * ai->gold_priority;
-      final_want += want - acity->ai.worth;
-    }
-  } city_list_iterate_end;
+  city_range_iterate(pcity, pplayer->cities, ai->impr_range[id], acity) {
+    int food, trade, shields, lux, sci, tax;
+
+    get_food_trade_shields(acity, &food, &trade, &shields);
+    get_tax_income(pplayer, trade, &sci, &lux, &tax);
+    final_want += city_want(acity, ai, food, shields, sci, lux, tax)
+                  - acity->ai.worth;
+  } city_range_iterate_end;
 
   /* Restore */
   city_remove_improvement(pcity, id);
@@ -199,8 +201,8 @@
   /* Base want is calculated above using a more direct approach. */
   v += base_want(pplayer, pcity, id);
   if (v != 0) {
-    CITY_LOG(LOG_DEBUG, pcity, "%s base_want is %d (range=%d, calc=%d)", 
-             get_improvement_name(id), v, ai->impr_range[id], 
ai->impr_calc[id]);
+    CITY_LOG(LOG_DEBUG, pcity, "%s base_want is %d (range=%d)", 
+             get_improvement_name(id), v, ai->impr_range[id]);
   }
 
   /* Find number of cities per range.  */
@@ -222,22 +224,20 @@
       if (is_effect_useful(TARGET_BUILDING, pplayer, pcity, id,
                           NULL, id, peff)) {
        int amount = peff->value, c = cities[peff->range];
+        struct city *palace = find_palace(pplayer);
 
        switch (*ptype) {
-          /* TODO */
-         case EFT_INCITE_DIST_PCT:
-         case EFT_MAKE_CONTENT_MIL_PER:
-         case EFT_MAKE_HAPPY:
-         case EFT_UNIT_RECOVER:
-            break;
-
+         case EFT_PROD_TO_GOLD:
+            /* Since coinage contains some entirely spurious ruleset values,
+             * we need to return here with some spurious want. */
+            pcity->ai.building_want[id] = TRADE_WEIGHTING;
+            return;
           /* These have already been evaluated in base_want() */
           case EFT_CAPITAL_CITY:
          case EFT_UPKEEP_FREE:
          case EFT_POLLU_POP_PCT:
          case EFT_POLLU_PROD_PCT:
          case EFT_TRADE_PER_TILE:
-         case EFT_PROD_TO_GOLD:
          case EFT_TRADE_INC_TILE:
          case EFT_FOOD_INC_TILE:
          case EFT_TRADE_ADD_TILE:
@@ -256,6 +256,15 @@
            break;
 
           /* WAG evaluated effects */
+         case EFT_INCITE_DIST_PCT:
+            v += real_map_distance(pcity->x, pcity->y, palace->x, palace->y);
+            break;
+         case EFT_MAKE_HAPPY:
+            /* TODO */
+            break;
+         case EFT_UNIT_RECOVER:
+            /* TODO */
+            break;
          case EFT_NO_UNHAPPY:
             v += (pcity->specialists[SP_ELVIS] + pcity->ppl_unhappy[0]) * 3;
             break;
@@ -265,6 +274,7 @@
              v += 5 * c;
            }
            break;
+         case EFT_MAKE_CONTENT_MIL_PER:
          case EFT_MAKE_CONTENT:
            if (!government_has_flag(gov, G_NO_UNHAPPY_CITIZENS)) {
              v += pcity->ppl_unhappy[0] * amount;
@@ -284,10 +294,12 @@
                * (nplayers - amount)) / (nplayers * amount * 100);
            break;
          case EFT_GROWTH_FOOD:
-           v += c * 4 + 25;
+           v += c * 4 + (amount / 7) * pcity->food_surplus;
            break;
          case EFT_AIRLIFT:
-           v += c + ai->stats.units[UCL_LAND];
+            /* FIXME: We need some smart algorithm here. The below is 
+             * totally braindead. */
+           v += c + MIN(ai->stats.units[UCL_LAND], 20);
            break;
          case EFT_ANY_GOVERNMENT:
            if (!can_change_to_government(pplayer, ai->goal.govt.idx)) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#10128) improve eff building code, Per I. Mathisen <=