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

 Store actual number of attack or occupy capable units in
city.ai.invasion instead of just one bit telling if such units exist
or not. This makes it possible to concentrate attacks in the future.
This patch already makes AI not to believe it will conquer city if it
has less attacking units than there is defenders.


 - ML

diff -Nurd -X.diff_ignore freeciv/ai/advmilitary.c freeciv/ai/advmilitary.c
--- freeciv/ai/advmilitary.c    2008-07-23 03:30:10.000000000 +0300
+++ freeciv/ai/advmilitary.c    2008-07-25 21:27:11.000000000 +0300
@@ -984,8 +984,8 @@
         desire = 0;
         
       } else if (uclass_has_flag(utype_class(punittype), UCF_CAN_OCCUPY) && 
acity
-                 && TEST_BIT(acity->ai.invasion, INVASION_ATTACK)
-                 && !TEST_BIT(acity->ai.invasion, INVASION_OCCUPY)) {
+                 && acity->ai.invasion.attack > 0
+                 && acity->ai.invasion.occupy == 0) {
         desire = bcost * SHIELD_WEIGHTING;
 
       } else {
@@ -1205,7 +1205,7 @@
        def_owner = unit_owner(pdef);
       }
     }
-    if (COULD_OCCUPY(myunit) || TEST_BIT(acity->ai.invasion, INVASION_OCCUPY)) 
{
+    if (COULD_OCCUPY(myunit) || acity->ai.invasion.occupy > 0) {
       /* bonus for getting the city */
       benefit += 40;
     }
diff -Nurd -X.diff_ignore freeciv/ai/aiair.c freeciv/ai/aiair.c
--- freeciv/ai/aiair.c  2008-01-20 04:03:28.000000000 +0200
+++ freeciv/ai/aiair.c  2008-07-25 21:33:24.000000000 +0300
@@ -75,8 +75,9 @@
   /* TODO: There is a danger of producing too many units that will not 
    * attack anything.  Production should not happen if there is an idle 
    * unit of the same type nearby */
-  if (acity && !TEST_BIT(acity->ai.invasion, INVASION_OCCUPY) && punit->id != 
0) {
-    /* No ground troups are invading */
+  if (acity && punit->id != 0
+      && acity->ai.invasion.occupy == 0 && !COULD_OCCUPY(punit)) {
+    /* No units capable of occupying are invading */
     freelog(LOG_DEBUG, "Don't want to attack %s, although we could", 
             city_name(acity));
     return FALSE;
diff -Nurd -X.diff_ignore freeciv/ai/aiunit.c freeciv/ai/aiunit.c
--- freeciv/ai/aiunit.c 2008-02-02 09:34:56.000000000 +0200
+++ freeciv/ai/aiunit.c 2008-07-25 21:25:22.000000000 +0300
@@ -1141,7 +1141,7 @@
   center of the area is either the unit itself (dest == FALSE) or the
   destination of the current goto (dest == TRUE). The invasion threat
   is marked in pcity->ai.invasion by setting the "which" bit (to
-  tell attack from sea apart from ground unit attacks).
+  tell attack which can only kill units from occupy possibility).
 
   If dest == TRUE then a valid goto is presumed.
 **************************************************************************/
@@ -1165,9 +1165,11 @@
 
     if (pcity
         && HOSTILE_PLAYER(pplayer, ai, city_owner(pcity))
-       && !TEST_BIT(pcity->ai.invasion, which)
        && (dest || !has_defense(pcity))) {
-      pcity->ai.invasion |= COND_SET_BIT(TRUE, which);
+      pcity->ai.invasion.attack++;
+      if (which == INVASION_OCCUPY) {
+        pcity->ai.invasion.occupy++;
+      }
     }
   } square_iterate_end;
 }
@@ -1259,7 +1261,8 @@
     city_list_iterate(aplayer->cities, acity) {
       reinforcements_cost_and_value(punit, acity->tile,
                                     &acity->ai.attack, &acity->ai.bcost);
-      acity->ai.invasion = 0;
+      acity->ai.invasion.attack = 0;
+      acity->ai.invasion.occupy = 0;
     } city_list_iterate_end;
   } players_iterate_end;
 
@@ -1360,6 +1363,8 @@
   }
 
   players_iterate(aplayer) {
+    int reserves;
+
     /* For the virtual unit case, which is when we are called to evaluate
      * which units to build, we want to calculate in danger and which
      * players we want to make war with in the future. We do _not_ want
@@ -1425,9 +1430,16 @@
         }
       }
 
-      if (COULD_OCCUPY(punit) || TEST_BIT(acity->ai.invasion, 
INVASION_OCCUPY)) {
-        /* There are units able to occupy the city! */
-        benefit += 40;
+      reserves = acity->ai.invasion.attack - 
unit_list_size(acity->tile->units);
+
+      if (reserves >= 0) {
+        /* We have enough units to kill all the units in the city */
+        if (reserves > 0
+            && (COULD_OCCUPY(punit) || acity->ai.invasion.occupy > 0)) {
+          /* There are units able to occupy the city after all defenders
+           * are killed! */
+          benefit += 60;
+        }
       }
 
       attack = (attack_value + acity->ai.attack) 
@@ -1448,8 +1460,8 @@
         /* Too far! */
         want = 0;
       } else if (COULD_OCCUPY(punit)
-                 && TEST_BIT(acity->ai.invasion, INVASION_ATTACK)
-                 && !TEST_BIT(acity->ai.invasion, INVASION_OCCUPY)) {
+                 && acity->ai.invasion.attack > 0
+                 && acity->ai.invasion.occupy == 0) {
         /* Units able to occupy really needed there! */
         want = bcost * SHIELD_WEIGHTING;
       } else {
diff -Nurd -X.diff_ignore freeciv/ai/aiunit.h freeciv/ai/aiunit.h
--- freeciv/ai/aiunit.h 2008-01-15 04:53:46.000000000 +0200
+++ freeciv/ai/aiunit.h 2008-07-25 21:32:50.000000000 +0300
@@ -49,7 +49,7 @@
   (ut->pop_cost * 3 + ut->happy_cost                                   \
    + ut->upkeep[O_SHIELD] + ut->upkeep[O_FOOD] + ut->upkeep[O_GOLD])
 
-/* INVASION bits */
+/* Invasion types */
 #define INVASION_OCCUPY  0
 #define INVASION_ATTACK  1
 
diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h
--- freeciv/common/city.h       2008-07-18 22:08:33.000000000 +0300
+++ freeciv/common/city.h       2008-07-25 21:06:20.000000000 +0300
@@ -200,6 +200,12 @@
   bool need_boat;        /* unit being built wants a boat */
 };
 
+/* Who's coming to kill us, for attack co-ordination */
+struct ai_invasion {
+  int attack;         /* Units capable of attacking city */
+  int occupy;         /* Units capable of occupying city */
+};
+
 struct ai_city {
   int building_turn;            /* only recalculate every Nth turn */
   int building_wait;            /* for weighting values */
@@ -216,7 +222,7 @@
 
   int worth; /* Cache city worth here, sum of all weighted incomes */
 
-  int invasion; /* who's coming to kill us, for attack co-ordination */
+  struct ai_invasion invasion;
   int attack, bcost; /* This is also for invasion - total power and value of
                       * all units coming to kill us. */
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to