Complete.Org: Mailing Lists: Archives: freeciv-dev: December 1999:
[Freeciv-Dev] domestic advisor patch 2 (PR#199)
Home

[Freeciv-Dev] domestic advisor patch 2 (PR#199)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] domestic advisor patch 2 (PR#199)
From: Peter Schaefer <schaefer@xxxxxx>
Date: Sun, 19 Dec 1999 13:56:29 -0800 (PST)

Some experimental code to assess the need for building defenses.
like walls, coastal defenses, SAM.

it has these shortcomings:
- needs to be cached, otherwise all cities have to be scanned (for every
city).
- the algorithm used isn´t the best, and the constants used make sense
only
  for the civ2 ruleset (if at all).
--------------84315340CC03804B47ADF517
Content-Type: text/plain; charset=us-ascii;
 name="advdom2.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="advdom2.diff"

--- freeciv-1.9.0/ai/advdomestic.c      Sun Dec 19 22:54:06 1999
+++ advdomestic.c       Sun Dec 19 22:45:47 1999
@@ -176,6 +176,169 @@
   return(c); /* benefit or cost of this building */
 }

+ /***********************************************************************
+ Iterate over own neighboring cities to determine whether this is
+ a land/ sea/ air border city. This mechanism is an O(2) CPU hog, and
+ needs to be cached, but I want to get rid of the dumb wall building.
+ Return Values: int lsa[3] = { land, sea, air };
+***********************************************************************/
+static void city_need_defenses(struct player *pplayer, struct city *pcity, int 
*lsa )
+{
+#define _D_LAND (0)
+#define _D_SEA (1)
+#define _D_AIR (2)
+
+  int size_friendly, c_friendly, lsa_defenses[3];
+  int size_danger, lsa_danger[3];
+
+  int cthis, cthat;
+  int i;
+  int handicap;
+  int distance;
+
+  struct player *aplayer;
+
+  size_friendly = 0;
+  c_friendly = 0;
+  lsa_defenses[2]= lsa_defenses[1]= lsa_defenses[0]= 0;
+
+  size_danger = 0;
+  lsa_danger[2]= lsa_danger[1]= lsa_danger[0]= 0;
+
+  cthis= map_get_continent(pcity->x, pcity->y);
+
+
+  /* calculate some statistics */
+
+  /* own cities */
+  city_list_iterate(pplayer->cities, acity)
+    {
+      /* check that this city can help */
+      cthat= map_get_continent(acity->x, acity->y);
+      if( cthis == cthat ){
+       distance = real_map_distance(pcity->x, pcity->y, acity->x, acity->y);
+       if( distance < CITY_MAP_SIZE+2
+           &&
+           acity->ai.a <= pcity->ai.a
+           )
+         {
+           size_friendly += pcity->size;
+           ++c_friendly;
+           if( city_got_effect(pcity, B_WALL) ){
+             ++lsa_defenses[_D_LAND];
+           }
+
+           if( city_got_effect(pcity, B_COASTAL) ){
+             ++lsa_defenses[_D_SEA];
+           }
+
+           if( city_got_effect(pcity, B_SAM) ){
+             ++lsa_defenses[_D_AIR];
+           }
+
+         }
+      }
+    }
+  city_list_iterate_end;
+
+
+  /* enemy cities */
+  handicap=ai_handicap(pplayer, H_TARGETS);
+  for (i = 0; i < game.nplayers; i++) {
+    aplayer = &game.players[i];
+    if (aplayer != pplayer) { /* enemy */
+      city_list_iterate(aplayer->cities, acity)
+       {
+         if (handicap && !map_get_known(acity->x, acity->y, pplayer))
+           continue;
+
+         distance = real_map_distance(pcity->x, pcity->y, acity->x, acity->y);
+
+           size_danger+= acity->size;
+
+           if( distance < CITY_MAP_SIZE + 2
+               ||
+               (( distance < CITY_MAP_SIZE * 2 +2 ) && cthis == 
map_get_continent(acity->x, acity->y) )
+               )
+             {
+               lsa_danger[_D_LAND]+= acity->size;
+             }
+
+           /* Assuming 5 sea range, which is modified by MAGELLAN */
+           /* The correct way would be to scan all seen enemy and
+              own sea units for their maximum range     */
+
+           if( distance
+               <
+               4*
+               (
+                5 +
+                2 - ( player_owns_active_wonder(pplayer, B_MAGELLAN) ? ( 
(improvement_variant(B_MAGELLAN)==1) ? 3 : 6 )/3 : 0 )
+                )
+              )
+             {
+               if( is_terrain_near_tile(acity->x, acity->y, T_OCEAN) )
+                 {
+                   lsa_danger[_D_SEA]+= acity->size;
+                 }
+             }
+
+           /* Assuming 16 range (cruise missile range) .. */
+           /* The correct way would be to scan all seen enemy and
+              own air units for their maximum range */
+
+           if( distance < 16 )
+             {
+               lsa_danger[_D_AIR]+= acity->size; /* but air units are much 
more mobile than others ?! */
+             }
+
+         }
+    city_list_iterate_end;
+    }
+  }
+
+  /* Let's cook up some rules which return maximum values of about 40-50 */
+  {
+    int land, sea, air;
+
+    land = 36*lsa_danger[_D_LAND] / (size_friendly+1);
+    sea =   8*lsa_danger[_D_SEA] / (size_friendly+1);
+    air =  12*lsa_danger[_D_AIR] / (size_friendly+1);
+
+    freelog(LOG_DEBUG, "Step 1: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+    /* only about every 2nd city builds city walls initially */
+    if( 2 * lsa_defenses[_D_LAND] > c_friendly )
+      land /= 2;
+
+    /* only about every 3rd city builds coastal defenses initially */
+    if( 3 * lsa_defenses[_D_LAND] > c_friendly )
+      sea /= 2;
+
+    /* only about every 4th city builds SAM initially */
+    if( 4 * lsa_defenses[_D_LAND] > c_friendly )
+      sea /= 2;
+
+    freelog(LOG_DEBUG, "Step 2: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+    if( land > 40 )
+      land = 40;
+    if( sea > 45 )
+      sea = 45;
+    if( air > 50 )
+      air = 50;
+
+    lsa[0]= land;
+    lsa[1]= sea;
+    lsa[2]= air;
+
+    freelog(LOG_DEBUG, "Step 3: %s lsa %d/%d/%d\n", pcity->name, land, sea, 
air);
+
+  }
+
+  return;
+}
+

 void ai_eval_buildings(struct city *pcity)
 {
@@ -290,16 +453,21 @@
 /* and it would have no chance to finish them before it was too late */


+  /*!PS: added somewhat smarter code, which produces weights <50 */
   {
+    int lsa[3];
+
+    city_need_defenses(pplayer, pcity, lsa );
+
   if (could_build_improvement(pcity, B_CITY))
 /* && !built_elsewhere(pcity, B_WALL))      was counterproductive -- Syela */
-    values[B_CITY] = 40; /* WAG */
+    values[B_CITY] = lsa[0];

   if (could_build_improvement(pcity, B_COASTAL))
-    values[B_COASTAL] = 40; /* WAG */
+    values[B_COASTAL] = lsa[1];

   if (could_build_improvement(pcity, B_SAM))
-    values[B_SAM] = 50; /* WAG */
+    values[B_SAM] = lsa[2];
   }



--------------84315340CC03804B47ADF517--


-------

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] domestic advisor patch 2 (PR#199), Peter Schaefer <=