Complete.Org: Mailing Lists: Archives: freeciv-ai: December 2004:
[freeciv-ai] (PR#10036) stupid autosettlers won't irrigate
Home

[freeciv-ai] (PR#10036) stupid autosettlers won't irrigate

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [freeciv-ai] (PR#10036) stupid autosettlers won't irrigate
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 12 Dec 2004 03:07:06 -0800
Reply-to: bugs@xxxxxxxxxxx

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

> [jdorje - Sat Sep 11 01:53:03 2004]:
> 
> My autosettlers in most cases refused to do irrigation on plains.  They 
> usually prefer to mine them instead.

Surely by now everyone has noticed that autosettlers are entirely
useless.  Turns out the bug was much simpler than what I had previously
thought.

Shields are weighted based on the shield bonus and SHIELD_WEIGHTING. 
Food is weighted based on food_weighting().  Trade is weighted based on
the estimated trade bonus and also ai->trade_want.

The bug is that food_weighting() is horrible.  As the city goes up the
food weighting goes down.  For a city of size 25 the food weighting is 1
(compared to a trade weighting of 17).  This means all food-producing
tiles will be converted into shield-producing ones and the city will
quickly starve (which is in fact what happens).

I thought of some several complicated heuristics to improve the
algorithm.  Then I came up with a really simple one.  And surprise, it
works much better.  It ignores all city and player weighting values and
simply assigns an absolute value to the goodness of each tile.  The main
advantage of this method is that it is stable.  There is no way terrain
conversion will flip-flop and end up in a loop, as happens often now. 
The disadvantage is that since the altorithm usually looks only one step
into the future some terrains are "locked".  For instance desert with
mine and railroad (0/3/1) will never be transformed into plains (1/1/1)
because this is a step backward.  If we looked 2 steps into the future
we could see plains+irrigation (2/1/1) and we'd go for it.

Also note that the current weightings (19/17/12) are not very good. 
Food is undervalued.  However in most cases this probably won't matter
since the best terrain types will come to the surface anyway.

The current behavior is a pretty major bug.  So this probably needs to
be fixed.  But a simpler fix is possible...

-jason

Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.215
diff -u -r1.215 settlers.c
--- server/settlers.c   10 Dec 2004 03:42:26 -0000      1.215
+++ server/settlers.c   12 Dec 2004 09:52:53 -0000
@@ -177,50 +177,6 @@
 }
 
 /**************************************************************************
-  The value of excees food is dependent on the amount of food it takes for 
-  a city to increase in size. This amount is in turn dependent on the 
-  citysize, hence this function.
-
-  The value returned from this function does not take into account whether
-  increasing a city's size is attractive, but only how effective the food
-  will be.
-
-  The return value is simply 
-    4*FOOD_WEIGHTING / (num_of_columns_in_foodbox).
-**************************************************************************/
-int food_weighting(int city_size)
-{
-  static int cache[MAX_CITY_SIZE];
-  static bool cache_valid = FALSE;
-
-  if (!cache_valid) {
-    /* FIXME: this cache is only rebuilt once per server process.  That
-     * means if you run two games in the same server with different
-     * options, this function may be broken for the second one. */
-    int size;
-
-    for (size = 1; size < MAX_CITY_SIZE; size++) {
-      int food_weighting_is_for = 4;   /* FOOD_WEIGHTING applies to city with
-                                          foodbox width of 4 */
-      int weighting = (food_weighting_is_for * FOOD_WEIGHTING) /
-                      (city_granary_size(size) / game.foodbox);
-
-      /* If the citysize is 1 we assume it will not be so for long, and
-         so adjust the value a little downwards. */
-      if (size == 1) {
-       weighting = (weighting * 3) / 4;
-      }
-      cache[size] = weighting;
-    }
-    cache_valid = TRUE;
-  }
-
-  assert(city_size > 0 && city_size < MAX_CITY_SIZE);
-
-  return cache[city_size];
-}
-
-/**************************************************************************
   Returns a measure of goodness of a tile to pcity.
 
   FIXME: foodneed and prodneed are always 0.
@@ -228,30 +184,28 @@
 int city_tile_value(struct city *pcity, int x, int y, 
                    int foodneed, int prodneed)
 {
-  int food_value, shield_value, trade_value;
-  struct player *plr;
-
-  plr = city_owner(pcity);
-
-  food_value = city_get_food_tile(x, y, pcity);
-  if (foodneed > 0) {
-    food_value += 9 * MIN(food_value, foodneed);
+  int food = city_get_food_tile(x, y, pcity);
+  int shield = city_get_shields_tile(x, y, pcity);
+  int trade = city_get_trade_tile(x, y, pcity);
+  int value = 0;
+
+  /* Each food, trade, and shield gets a certain weighting.  We also benefit
+   * tiles that have at least one of an item - this promotes balance and 
+   * also accounts for INC_TILE effects. */
+  value += food * FOOD_WEIGHTING;
+  if (food > 0) {
+    value += FOOD_WEIGHTING / 2;
+  }
+  value += shield * SHIELD_WEIGHTING;
+  if (shield > 0) {
+    value += SHIELD_WEIGHTING / 2;
+  }
+  value += trade * TRADE_WEIGHTING;
+  if (trade > 0) {
+    value += TRADE_WEIGHTING / 2;
   }
-  food_value *= food_weighting(MAX(2, pcity->size));
-  
-  shield_value = city_get_shields_tile(x, y, pcity);
-  if (prodneed > 0) {
-    shield_value += 9 * (MIN(shield_value, prodneed));
-  }
-  shield_value *= SHIELD_WEIGHTING * pcity->bonus[O_SHIELD];
-  shield_value /= 100;
-
-  trade_value = (city_get_trade_tile(x, y, pcity) * pcity->ai.trade_want
-       * (pcity->bonus[O_GOLD] * plr->economic.tax
-         + pcity->bonus[O_LUXURY] * plr->economic.luxury
-         + pcity->bonus[O_SCIENCE] * plr->economic.science)) / 10000;
 
-  return food_value + shield_value + trade_value;
+  return value;
 }  
 
 /**************************************************************************
Index: server/settlers.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.h,v
retrieving revision 1.28
diff -u -r1.28 settlers.h
--- server/settlers.h   29 Sep 2004 02:24:24 -0000      1.28
+++ server/settlers.h   12 Dec 2004 09:52:53 -0000
@@ -27,7 +27,6 @@
 
 void init_settlers(void);
 
-int food_weighting(int city_size);
 int city_tile_value(struct city *pcity, int x, int y,
                    int foodneed, int prodneed);
 void initialize_infrastructure_cache(struct player *pplayer);

[Prev in Thread] Current Thread [Next in Thread]
  • [freeciv-ai] (PR#10036) stupid autosettlers won't irrigate, Jason Short <=