Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2002:
[Freeciv-Dev] Cache win_chance in get_defender(attacker) (PR#1269)
Home

[Freeciv-Dev] Cache win_chance in get_defender(attacker) (PR#1269)

[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] Cache win_chance in get_defender(attacker) (PR#1269)
From: Gregory Berkolaiko <gberkolaiko@xxxxxxxxxxx>
Date: Fri, 22 Feb 2002 10:00:31 -0800 (PST)

 --- Gregory Berkolaiko <gberkolaiko@xxxxxxxxxxx> wrote: 
>  --- Raimar Falke <hawk@xxxxxxxxxxxxxxxxxxxxxxx> wrote: 
> > On Fri, Feb 22, 2002 at 03:34:10PM +0100, Petr Baudis wrote:
> > 
> > > +             get_total_attack_power(patt, punit) *
> > > +             get_total_attack_power(punit, pdef)
> > 
> > Can't this test be replaced with win_chance?
> 
> Mmmm, I got so carried away with the idea that win_chance takes too much
> CPU,
> that I didn't notice that here it won't be more costly...
> 
> If, that is, we modify get_attacker and get_defender slightly to cache the
> value of the winchance.  Because all win probabilities were already computed
> in there.

And a patch to enable this.

This will pave a road for a very simple patch which will make autoattack
_significantly_ better.

Of course we don't have to cache the win_chance but it is a big fat function
to call (and we would need to call it if we want to get the attack profit
equation absolutely right).

G.

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com
? auto.rc
? saves
Index: ai/advmilitary.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v
retrieving revision 1.90
diff -u -r1.90 advmilitary.c
--- ai/advmilitary.c    2002/02/21 09:44:50     1.90
+++ ai/advmilitary.c    2002/02/22 17:52:16
@@ -686,7 +686,7 @@
 
   acity = map_get_city(x, y);
   if (!acity) {
-    aunit = get_defender(myunit, x, y);
+    aunit = get_defender(myunit, x, y, NULL);
   } else {
     aunit = NULL;
   }
@@ -710,7 +710,7 @@
     a *= a;
 
     if (acity) {
-      pdef = get_defender(myunit, x, y);
+      pdef = get_defender(myunit, x, y, NULL);
 
       m = unit_types[v].move_rate;
       if (unit_type_flag(v, F_IGTER)) m *= 3; /* not quite right */
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.176
diff -u -r1.176 aiunit.c
--- ai/aiunit.c 2002/02/22 13:14:38     1.176
+++ ai/aiunit.c 2002/02/22 17:52:16
@@ -766,9 +766,9 @@
   } /* ferryboats do not attack.  no. -- Syela */
 
   adjc_iterate(x, y, x1, y1) {
-    pdef = get_defender(punit, x1, y1);
+    pdef = get_defender(punit, x1, y1, NULL);
     if (pdef) {
-      patt = get_attacker(punit, x1, y1);
+      patt = get_attacker(punit, x1, y1, NULL);
 /* horsemen in city refused to attack phalanx just outside that was
 bodyguarding catapult - patt will resolve this bug nicely -- Syela */
       if (can_unit_attack_tile(punit, x1, y1)) { /* thanks, Roar */
@@ -1408,7 +1408,7 @@
           ((ferryboat || harborcity) &&
                       warmap.seacost[acity->x][acity->y] <= 6 * THRESHOLD))) ||
           (is_sailing_unit(punit) && warmap.seacost[acity->x][acity->y] < 
maxd))) {
-          if ((pdef = get_defender(punit, acity->x, acity->y))) {
+          if ((pdef = get_defender(punit, acity->x, acity->y, NULL))) {
             d = unit_vulnerability(punit, pdef);
             b = unit_type(pdef)->build_cost + 40;
           } else { d = 0; b = 40; }
@@ -1529,7 +1529,7 @@
         if (handicap && !map_get_known(aunit->x, aunit->y, pplayer)) continue;
         if (unit_flag(aunit, F_CARAVAN) && !punit->id) continue; /* kluge */
         if (ai_fuzzy(pplayer, TRUE) &&
-           (aunit == get_defender(punit, aunit->x, aunit->y) &&
+           (aunit == get_defender(punit, aunit->x, aunit->y, NULL) &&
            ((is_ground_unit(punit) &&
                 map_get_continent(aunit->x, aunit->y) == con &&
                 warmap.cost[aunit->x][aunit->y] < maxd) ||
Index: common/combat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v
retrieving revision 1.19
diff -u -r1.19 combat.c
--- common/combat.c     2002/02/16 17:05:05     1.19
+++ common/combat.c     2002/02/22 17:52:16
@@ -436,7 +436,8 @@
 also be able to spare units without full hp's to some extend, as these
 could be more valuable later.
 **************************************************************************/
-struct unit *get_defender(struct unit *attacker, int x, int y)
+struct unit *get_defender(struct unit *attacker, int x, int y, 
+                         int *chance)
 {
   struct unit *bestdef = NULL;
   int bestvalue = -1, count = 0, best_cost = 0, rating_of_best = 0;
@@ -481,6 +482,11 @@
            " of the unit is %s", x, y, unit_owner(debug_unit)->name);
   }
 
+  if (chance != NULL) {
+    /* Save the win_chance result to be used by the caller function */
+    *chance = bestvalue;
+  }
+
   return bestdef;
 }
 
@@ -490,7 +496,8 @@
 Works like get_defender; see comment there.
 This function is mostly used by the AI.
 **************************************************************************/
-struct unit *get_attacker(struct unit *defender, int x, int y)
+struct unit *get_attacker(struct unit *defender, int x, int y, 
+                         int *chance)
 {
   struct unit *bestatt = 0;
   int bestvalue = -1, unit_a, best_cost = 0;
@@ -509,6 +516,11 @@
       best_cost = build_cost;
     }
   } unit_list_iterate_end;
+
+  if (chance != NULL) {
+    /* Save the win_chance result to be used by the caller function */
+    *chance = bestvalue;
+  }
 
   return bestatt;
 }
Index: common/combat.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.h,v
retrieving revision 1.4
diff -u -r1.4 combat.h
--- common/combat.h     2002/02/14 15:17:09     1.4
+++ common/combat.h     2002/02/22 17:52:16
@@ -40,7 +40,9 @@
 int get_virtual_defense_power(Unit_Type_id a_type, Unit_Type_id d_type, int x, 
int y);
 int get_total_attack_power(struct unit *attacker, struct unit *defender);
 
-struct unit *get_defender(struct unit *attacker, int x, int y);
-struct unit *get_attacker(struct unit *defender, int x, int y);
+struct unit *get_defender(struct unit *attacker, int x, int y, 
+                         int *chance);
+struct unit *get_attacker(struct unit *defender, int x, int y, 
+                         int *chance);
 
 #endif /* FC__COMBAT_H */
Index: server/autoattack.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/autoattack.c,v
retrieving revision 1.35
diff -u -r1.35 autoattack.c
--- server/autoattack.c 2002/02/21 08:56:22     1.35
+++ server/autoattack.c 2002/02/22 17:52:16
@@ -92,7 +92,7 @@
       continue;
 
     freelog(LOG_DEBUG,  "found enemy unit/stack at %d,%d", x, y);
-    enemy = get_defender(punit, x, y);
+    enemy = get_defender(punit, x, y, NULL);
     freelog(LOG_DEBUG,  "defender is %s", unit_name(enemy->type));
 
     if (!is_city_option_set(pcity, unit_type(enemy)->move_type - 1 +
@@ -126,6 +126,7 @@
   freelog(LOG_DEBUG,"choosen target=%s (%d/%d)",
          get_unit_name(enemy->type), enemy->x,enemy->y);
 
+  /* TODO: Use cached value from get_defender in this test */
   if((unit_type(enemy)->defense_strength) >
      unit_type(punit)->attack_strength*1.5) {
     notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.217
diff -u -r1.217 unithand.c
--- server/unithand.c   2002/02/22 13:14:45     1.217
+++ server/unithand.c   2002/02/22 17:52:17
@@ -856,7 +856,7 @@
   struct player *pplayer = unit_owner(punit);
   struct tile *pdesttile = map_get_tile(dest_x, dest_y);
   struct tile *psrctile = map_get_tile(punit->x, punit->y);
-  struct unit *pdefender = get_defender(punit, dest_x, dest_y);
+  struct unit *pdefender = get_defender(punit, dest_x, dest_y, NULL);
   struct city *pcity = pdesttile->city;
 
   /* barbarians shouldn't enter huts */
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.160
diff -u -r1.160 unittools.c
--- server/unittools.c  2002/02/22 13:14:46     1.160
+++ server/unittools.c  2002/02/22 17:52:17
@@ -159,7 +159,7 @@
 bool can_unit_attack_tile(struct unit *punit, int dest_x, int dest_y)
 {
   struct unit *pdefender;
-  pdefender=get_defender(punit, dest_x, dest_y);
+  pdefender=get_defender(punit, dest_x, dest_y, NULL);
   return(can_unit_attack_unit_at_tile(punit, pdefender, dest_x, dest_y));
 }
 
@@ -2915,8 +2915,9 @@
     }
   }
   /* A transporter should not take units with it when on an attack goto -- 
fisch */
+  /* TODO: Use is_enemy(non_allied)_unit_tile instead of get_defender */
   if ((punit->activity == ACTIVITY_GOTO) &&
-      get_defender(punit, punit->goto_dest_x, punit->goto_dest_y) &&
+      get_defender(punit, punit->goto_dest_x, punit->goto_dest_y, NULL) &&
       psrctile->terrain != T_OCEAN) {
     transport_units = FALSE;
   }

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