[Freeciv-Dev] domestic advisor patch 2 (PR#199)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
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 <=
|
|