Complete.Org: Mailing Lists: Archives: freeciv-ai: November 2004:
[freeciv-ai] [Freeciv-Dev] (PR#10694) AI Builds Doomed Ferries and Passe
Home

[freeciv-ai] [Freeciv-Dev] (PR#10694) AI Builds Doomed Ferries and Passe

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [freeciv-ai] [Freeciv-Dev] (PR#10694) AI Builds Doomed Ferries and Passengers
From: "Benedict Adamson" <badamson@xxxxxxxxxxx>
Date: Sun, 7 Nov 2004 16:30:40 -0800
Reply-to: rt@xxxxxxxxxxx

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

Here is a patch that implements a possible fix. This is applicable to 
the 2004-1103 CVS development version. Note that this patch is only 
lightly tested; I'm posting it to get feedback rather than to provide a 
final fix.

The uses an estimate of the ferry sinking probability to adjust the cost 
estimate for a proposed ferried attacker. That tends to punish long 
ferry routes through dangerous waters. It computes the sinking 
probability from the danger values already computed in the assess_danger 
function. The computation has one WAG constant (FERRY_DANGER_FACTOR).

Any comments?

diff -ru -Xfreeciv.PR10694/diff_ignore vendor.freeciv.current/ai/advmilitary.c 
freeciv.PR10694/ai/advmilitary.c
--- vendor.freeciv.current/ai/advmilitary.c     2004-11-03 19:46:36.000000000 
+0000
+++ freeciv.PR10694/ai/advmilitary.c    2004-11-08 00:14:46.000000000 +0000
@@ -580,6 +580,10 @@
   }
 
   pcity->ai.danger = danger[0];
+  /* TO DO: sea_danger should ignore the effects of coast defences and
+   * should include a contribution from warships that can not make
+   * land attacks */
+  pcity->ai.sea_danger = danger[2];
   pcity->ai.urgency = urgency;
 
   return urgency;
@@ -756,6 +760,47 @@
   return;
 }
 
+/* A WAG for ferry_turn_survival_probabilty */
+#define FERRY_DANGER_FACTOR 800
+/************************************************************************** 
+  Estimate the probability of a loaded ferry evading sinking by enemy warships
+  for one turn in the waters around one of our cities.
+**************************************************************************/
+static int ferry_turn_survival_probabilty(const struct city *pcity)
+{
+  const int danger = MAX(1, pcity->ai.sea_danger);
+  int p = 100;
+
+  p = 100 - MIN(100, danger/FERRY_DANGER_FACTOR);
+  assert(0 <= p && p <= 100);
+  return p;
+}
+
+/************************************************************************** 
+  Estimate the probability of a loaded ferry evading sinking by enemy warships.
+  The ferry starts in our city, pcity. move_time gives the length of the
+  *passenger's* journey; some of that journey will be on land.
+  The probability is a percentage.
+**************************************************************************/
+static int ferry_survival_probabilty(const struct city *pcity,
+                                    const int move_time)
+{
+  const int turn_survival = ferry_turn_survival_probabilty(pcity);
+  int sea_time = MAX(1, move_time - 1); /*assume 1 turn on land*/
+  int p = 100;
+
+  assert(0 <= move_time);
+
+  while (sea_time) {
+    p = p * turn_survival / 100;
+    sea_time--;
+  }
+
+  p = MAX(1, p); /*prevent divide-by-zero */
+  assert(0 < p && p <= 100);
+  return p;
+}
+
 /************************************************************************** 
   This function decides, what unit would be best for erasing enemy. It is 
   called, when we just want to kill something, we've found it but we don't 
@@ -785,17 +830,15 @@
   bool shore = is_ocean_near_tile(pcity->tile);
   int orig_move_type = unit_types[best_choice->choice].move_type;
   int victim_count = 1;
-  int needferry = 0;
+  int ferry_cost = 0;
   bool unhap = ai_assess_military_unhappiness(pcity,
                                               get_gov_pplayer(pplayer));
+  bool will_use_ferry = (orig_move_type == LAND_MOVING
+                        && (boat || boattype < U_LAST));
+  bool will_build_ferry = will_use_ferry && !boat;
 
   assert(orig_move_type == SEA_MOVING || orig_move_type == LAND_MOVING);
 
-  if (orig_move_type == LAND_MOVING && !boat && boattype < U_LAST) {
-    /* cost of ferry */
-    needferry = unit_build_shield_cost(boattype);
-  }
-  
   if (!is_stack_vulnerable(ptile)) {
     /* If it is a city, a fortress or an air base,
      * we may have to whack it many times */
@@ -899,6 +942,22 @@
           }
         }
       }
+
+      /* Using ferries introduces costs of ferry building,
+       * if we use a new ferry, and the danger that we will be sunk en route,
+       * when we are helpless */
+      if (will_use_ferry) {
+       int ferry_build_cost = unit_build_shield_cost(boattype);
+       int p = ferry_survival_probabilty(pcity, move_time);
+       if (will_build_ferry) {
+         ferry_cost = ferry_build_cost * 100 / p;
+       } else {
+         ferry_cost = ferry_build_cost * (100 - p) / p;
+       }
+       bcost_balanced = bcost_balanced * 100 / p;
+      } else {
+       ferry_cost = 0;
+      }
       
       desire -= tech_cost * SHIELD_WEIGHTING;
       /* We can be possibly making some people of our homecity unhappy - then
@@ -908,7 +967,7 @@
                              : SHIELD_WEIGHTING);
 
       want = military_amortize(pplayer, pcity, desire, MAX(1, move_time),
-                               bcost_balanced + needferry);
+                               bcost_balanced + ferry_cost);
       
       if (want > 0) {
         if (tech_dist > 0) {
diff -ru -Xfreeciv.PR10694/diff_ignore vendor.freeciv.current/ai/ailog.c 
freeciv.PR10694/ai/ailog.c
--- vendor.freeciv.current/ai/ailog.c   2004-10-22 23:16:37.000000000 +0100
+++ freeciv.PR10694/ai/ailog.c  2004-11-08 00:14:46.000000000 +0000
@@ -78,7 +78,7 @@
 
 /**************************************************************************
   Log city messages, they will appear like this
-    2: c's Romenna(5,35) [s1 d106 u11 g1] must have Archers ...
+    2: c's Romenna(5,35) [s1 d106 s90 u11 g1] must have Archers ...
 **************************************************************************/
 void CITY_LOG(int level, struct city *pcity, const char *msg, ...)
 {
@@ -93,10 +93,10 @@
     return;
   }
 
-  my_snprintf(buffer, sizeof(buffer), "%s's %s(%d,%d) [s%d d%d u%d g%d] ",
+  my_snprintf(buffer, sizeof(buffer), "%s's %s(%d,%d) [s%d d%d s%d u%d g%d] ",
               city_owner(pcity)->name, pcity->name,
               pcity->tile->x, pcity->tile->y, pcity->size,
-              pcity->ai.danger, pcity->ai.urgency,
+              pcity->ai.danger, pcity->ai.sea_danger, pcity->ai.urgency,
               pcity->ai.grave_danger);
 
   va_start(ap, msg);
diff -ru -Xfreeciv.PR10694/diff_ignore vendor.freeciv.current/common/city.c 
freeciv.PR10694/common/city.c
--- vendor.freeciv.current/common/city.c        2004-10-22 23:16:36.000000000 
+0100
+++ freeciv.PR10694/common/city.c       2004-11-08 00:14:45.000000000 +0000
@@ -2457,6 +2457,7 @@
   pcity->ai.trade_want = 1; /* we always want some */
   memset(pcity->ai.building_want, 0, sizeof(pcity->ai.building_want));
   pcity->ai.danger = 0;
+  pcity->ai.sea_danger = 0;
   pcity->ai.urgency = 0;
   pcity->ai.grave_danger = 0;
   pcity->ai.wallvalue = 0;
diff -ru -Xfreeciv.PR10694/diff_ignore vendor.freeciv.current/common/city.h 
freeciv.PR10694/common/city.h
--- vendor.freeciv.current/common/city.h        2004-10-22 23:16:36.000000000 
+0100
+++ freeciv.PR10694/common/city.h       2004-11-08 00:14:45.000000000 +0000
@@ -174,6 +174,7 @@
   int building_want[B_LAST];    /* not sure these will always be < 256 */
 
   unsigned int danger;          /* danger to be compared to assess_defense */
+  unsigned int sea_danger;      /* due to warships */
   bool diplomat_threat;         /* enemy diplomat or spy is near the city */
   bool has_diplomat;            /* this city has diplomat or spy defender */
   unsigned int urgency;         /* how close the danger is; if zero, 
diff -ru -Xfreeciv.PR10694/diff_ignore vendor.freeciv.current/diff_ignore 
freeciv.PR10694/diff_ignore
--- vendor.freeciv.current/diff_ignore  2004-10-22 23:16:37.000000000 +0100
+++ freeciv.PR10694/diff_ignore 2004-11-08 00:18:21.000000000 +0000
@@ -17,6 +17,7 @@
 *~
 .#*
 .deps
+.svn
 CVS
 Freeciv.h
 Makefile

[Prev in Thread] Current Thread [Next in Thread]