Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2005:
[Freeciv-Dev] (PR#11907) a better init_min_production
Home

[Freeciv-Dev] (PR#11907) a better init_min_production

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#11907) a better init_min_production
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 Apr 2005 00:46:47 -0700
Reply-to: bugs@xxxxxxxxxxx

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

Well, here's an updated patch.  This also uses is_free_worked_tile to
avoid hard-coding the free-city-center.

Pruning by everything except shields and food is dropped again.  This is
still an improvement over the current version since it uses pcity->usage.

However I think with the current method of trade-routes it is impossible
ever to do pruning by trade or luxury or gold.

1.  We can't prune directly by gold since only taxmen make gold. 
Tile-workers don't make gold they make trade.

2.  We can't convert the gold minimum into a trade minimum because
taxmen don't make trade.

3.  We might be able to convert trade into gold directly at the pruning
stage in compute_max_stats_heuristic, allowing (again) pruning by gold,
except...

4.  Without even more recalculation in compute_max_stats_heuristic there
is no way at all to account for trade routes in compute_max_stats_heuristic.

Maybe something can be done but that can wait for later.  For the moment
this patch is sufficient.

I tried running it on client-side CM and got identical results to what
we have now.

As a side note the CM should have a debug mode that skips all pruning
and does a full search.  This will be super slow (exponentially slower
than the current code, probably) but would allow sanity checks by
comparing it to the pruned searches.

-jason

? 1
? diff
Index: common/aicore/cm.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/cm.c,v
retrieving revision 1.62
diff -u -r1.62 cm.c
--- common/aicore/cm.c  7 Apr 2005 04:36:02 -0000       1.62
+++ common/aicore/cm.c  19 Apr 2005 07:33:00 -0000
@@ -1518,67 +1518,45 @@
 ****************************************************************************/
 static void init_min_production(struct cm_state *state)
 {
-  int x = CITY_MAP_RADIUS, y = CITY_MAP_RADIUS;
-  int usage[O_COUNT];
   struct city *pcity = state->pcity;
   bool is_celebrating = base_city_celebrating(pcity);
-  struct city backup;
 
-  /* make sure the city's numbers make sense (sometimes they don't,
-   * somehow) */
-  memcpy(&backup, pcity, sizeof(*pcity));
-  generic_city_refresh(pcity, FALSE, NULL);
+  /* We used to call generic_city_refresh here, but that's no longer
+   * necessary since it's called at the start of cm_query_result. */
 
   memset(state->min_production, 0, sizeof(state->min_production));
+  output_type_iterate(o) {
+    /* Calculate minimum output.  This assumes no waste.  Pruning
+     * is done mainly based on minimum production, so we want to find the
+     * absolute highest minimum possible.  However if the minimum we find
+     * here is incorrectly too high, then the algorithm will fail. */
+    int min;
+
+    if (o != O_SHIELD && o != O_FOOD) {
+      /* min-production calculations are only possible for food and
+       * shields.  The others depend on complex trade calculations
+       * that cannot be accounted for since the bonus from trade
+       * routes depends on the amount of trade in an unpredictable way. */
+      continue;
+    }
+
+    /* 1.  Calculate the minimum final production that is needed.
+     * 2.  Divide by the bonus (rounding down) to get the minimum citizen
+     *     production that is needed.
+     * 3.  Subtract off any "free" production (trade routes, tithes, and
+     *     city-center). */
+    min = pcity->usage[o] + state->parameter.minimal_surplus[o];
+    min = min * 100 / pcity->bonus[o];
+    city_map_iterate(x, y) {
+      if (is_free_worked_tile(x, y)) {
+       min -= base_city_get_output_tile(x, y, pcity, is_celebrating, o);
+      }
+    } city_map_iterate_end;
+    state->min_production[o] = MAX(min, 0);
+  } output_type_iterate_end;
 
-  /* If the city is content, then we know the food usage is just
-   * prod-surplus; otherwise, we know it's at least 2*size but we
-   * can't easily compute the settlers. */
-  if (!city_unhappy(pcity)) {
-    usage[O_FOOD] = pcity->prod[O_FOOD] - pcity->surplus[O_FOOD];
-  } else {
-    usage[O_FOOD] = pcity->size * 2;
-  }
-  state->min_production[O_FOOD] = usage[O_FOOD]
-    + state->parameter.minimal_surplus[O_FOOD]
-    - base_city_get_output_tile(x, y, pcity, is_celebrating, O_FOOD);
-
-  /* surplus = (factories-waste) * production - shield_usage, so:
-   *   production = (surplus + shield_usage)/(factories-waste)
-   * waste >= 0, so:
-   *   production >= (surplus + usage)/factories
-   * Solving with surplus >= min_surplus, we get:
-   *   production >= (min_surplus + usage)/factories
-   * 'factories' is the pcity->bonus[O_SHIELD]/100.  Increase it a bit to avoid
-   * rounding errors.
-   *
-   * pcity->prod[O_SHIELD] = (factories-waste) * production.
-   * Therefore, shield_usage = pcity->prod[O_SHIELD] - pcity->shield_surplus
-   */
-  if (!city_unhappy(pcity)) {
-    double sbonus;
-
-    usage[O_SHIELD] = pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD];
-
-    sbonus = ((double)pcity->bonus[O_SHIELD]) / 100.0;
-    sbonus += .1;
-    state->min_production[O_SHIELD]
-      = ((usage[O_SHIELD] + state->parameter.minimal_surplus[O_SHIELD])
-        / sbonus);
-    state->min_production[O_SHIELD]
-      -= base_city_get_output_tile(x, y, pcity, is_celebrating, O_SHIELD);
-  } else {
-    /* Dunno what the usage is, so it's pointless to set the
-     * min_production */
-    usage[O_SHIELD] = 0;
-    state->min_production[O_SHIELD] = 0;
-  }
-
-  /* we should be able to get a min_production on gold and trade, too;
-     also, lux, if require_happy, but not otherwise */
-
-  /* undo any effects from the refresh */
-  memcpy(pcity, &backup, sizeof(*pcity));
+  /* We could get a minimum on luxury if we knew how many luxuries were
+   * needed to make us content. */
 }
 
 /****************************************************************************

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#11907) a better init_min_production, Jason Short <=