Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2002:
[Freeciv-Dev] Re: Military amortize (PR#1199)
Home

[Freeciv-Dev] Re: Military amortize (PR#1199)

[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] Re: Military amortize (PR#1199)
From: "Ross W. Wetmore" <rwetmore@xxxxxxxxxxxx>
Date: Thu, 3 Jan 2002 22:13:14 -0800 (PST)

As a tangential note. Amortize like a number of similar functions
that can be used to massage values (e.g. gaussian distribution,
quadratic or logarithmic scaling, ...) are often usefully implemented
by generating a lookup table. This is particularly effective if there
is just one degree of freedom, and the possible values for it have a
discrete integer range.

The advantage to reducing things to this sort of form is that one can
change the massaging function by substituting a pointer to a new table.

This can be an effective way to develop personalities or subtle static
environment (or at least long(er) term environemntal effects) into 
such calculations.

There may be value in trying to standardize on some common general 
form, or small set of forms for many of these new functions. At least
the calling interfaces could be similar.

Cheers,
RossW
=====

At 06:20 PM 02/01/03 +0000, Gregory Berkolaiko wrote:
>Hi,
>
>Throughout military calculations in the AI some crazy amortize scheme is
>used repeatedly.  I do not claim I understand it, but I thought it's
>worthwhile separating it into a separate procedure, military_amortize.
>
>It makes the code more concise and removes one imaginatively named
>variable (a0) from 3 functions!
>
>From todays CVS,
>Compiles smooth.
>Savegames identical.
>
>Best,
>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? rfile1
>? rfile2
>? saves
>? ai/aiunit.mod.c
>Index: ai/advmilitary.c
>===================================================================
>RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v
>retrieving revision 1.80
>diff -u -r1.80 advmilitary.c
>--- ai/advmilitary.c   2001/12/21 11:17:30     1.80
>+++ ai/advmilitary.c   2002/01/03 18:13:47
>@@ -543,7 +543,7 @@
> { 
>   Unit_Type_id i;
>   Tech_Type_id j;
>-  int a, c, d, e, a0, b0, f, g, fprime;
>+  int a, c, d, e, b0, f, g, fprime;
>   int k, l, m, q;
>   int shore = is_terrain_near_tile(pcity->x, pcity->y, T_OCEAN);
>   struct city *acity = map_get_city(x, y);
>@@ -624,10 +624,7 @@
>         b0 -= l * SHIELD_WEIGHTING;
>         b0 -= c * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING :
SHIELD_WEIGHTING);
>       }
>-      if (b0 > 0) {
>-        a0 = amortize(b0, MAX(1, c));
>-        e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / ((fprime + needferry)
* MORT);
>-      } else e = 0;  
>+      e = military_amortize(b0, MAX(1, c), fprime + needferry);
>       if (e > 0) {
>         if (k) {
>           pplayer->ai.tech_want[j] += e;
>@@ -659,7 +656,7 @@
> {
>   int a, b, c, d, e, f, g; /* variables in the attacker-want equation */
>   Unit_Type_id v, n;
>-  int m, vet, dist, a0, b0, fprime;
>+  int m, vet, dist, b0, fprime;
>   int x, y, unhap = 0;
>   struct unit *pdef, *aunit, *ferryboat;
>   struct city *acity;
>@@ -822,10 +819,7 @@
>                g * SHIELD_WEIGHTING / (acity->ai.a * acity->ai.a + g * d);
>     }
>     b0 -= c * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING :
SHIELD_WEIGHTING);
>-    if (b0 > 0) {
>-      a0 = amortize(b0, MAX(1, c));
>-      e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / ((fprime + needferry) *
MORT);
>-    } else e = 0;  
>+    e = military_amortize(b0, MAX(1, c), fprime + needferry);
> 
> #ifdef DEBUG
>     if (e != fstk && acity) {
>Index: ai/aiunit.c
>===================================================================
>RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
>retrieving revision 1.158
>diff -u -r1.158 aiunit.c
>--- ai/aiunit.c        2001/11/05 01:59:59     1.158
>+++ ai/aiunit.c        2002/01/03 18:13:48
>@@ -490,6 +490,26 @@
> }
> 
> /**************************************************************************
>+Military "want" estimates are amortized in this complicated way.
>+COMMENTME: Why not use simple amortize? -- GB
>+**************************************************************************/
>+int military_amortize(int value, int delay, int build_cost)
>+{
>+  int simply_amortized, fully_amortized;
>+
>+  if (value <= 0) {
>+    return 0;
>+  }
>+
>+  simply_amortized = amortize(value, delay);
>+  fully_amortized = (value * simply_amortized 
>+                   / (MAX(1, value - simply_amortized)) 
>+                   * 100 / build_cost / MORT);
>+
>+  return fully_amortized;
>+}
>+
>+/**************************************************************************
>  this is still pretty dopey but better than the original -- Syela
> **************************************************************************/
> static int reinforcements_value(struct unit *punit, int x, int y)
>@@ -1162,14 +1182,14 @@
> **************************************************************************/
> int find_something_to_kill(struct player *pplayer, struct unit *punit,
int *x, int *y)
> {
>-  int a=0, b, c, d, e, m, n, v, i, f, a0, b0, ab, g;
>+  int a=0, b, c, d, e, m, n, v, i, f, b0, ab, g;
> #ifdef DEBUG
>   int aa = 0, bb = 0, cc = 0, dd = 0, bestb0 = 0;
> #endif
>   int con = map_get_continent(punit->x, punit->y);
>   struct player *aplayer;
>   struct unit *pdef;
>-  int best = 0, maxd, boatid = 0;
>+  int best = 0, maxd, boatid = 0, needferry;
>   int harborcity = 0, bx = 0, by = 0;
>   int fprime, handicap;
>   struct unit *ferryboat = 0;
>@@ -1314,35 +1334,31 @@
>                       g * SHIELD_WEIGHTING / (acity->ai.a * acity->ai.a +
g * d);
>           }
>           b0 -= c * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING :
SHIELD_WEIGHTING);
>-          if (b0 > 0) {
>-            a0 = amortize(b0, MAX(1, c));
>-            if (!sanity && !boatid && is_ground_unit(punit))
>-              e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / ((fprime + 40)
* MORT);
>-            else e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / (fprime *
MORT);
>- /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE */
>-          } else if (!punit->id && !best) {
>-            b0 = b * SHIELD_WEIGHTING;
>-            a0 = amortize(b0, MAX(1, c));
>-            if (!sanity && !boatid && is_ground_unit(punit))
>-              e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / ((fprime + 40)
* MORT);
>-            else e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / (fprime *
MORT);
>-            if (e > bk) {
>+        /* FIXME: sheild_cost of ferry */
>+          needferry = ((!sanity && !boatid && is_ground_unit(punit)) ? 
>+                     40 : 0);
>+        e = military_amortize(b0, MAX(1, c), fprime + needferry);
>+        /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE */
>+          if (b0 <= 0 && !punit->id && !best) {
>+          int bk_e = military_amortize(b * SHIELD_WEIGHTING, 
>+                                       MAX(1, c), fprime + needferry);
>+            if (bk_e > bk) {
>               if (punit->id && is_ground_unit(punit) &&
>-                       !unit_flag(punit, F_MARINES) &&
>-                       map_get_continent(acity->x, acity->y) != con) {
>+                !unit_flag(punit, F_MARINES) &&
>+                map_get_continent(acity->x, acity->y) != con) {
>                 if (find_beachhead(punit, acity->x, acity->y, &xx, &yy)) {
>                   *x = acity->x;
>                   *y = acity->y;
>-                  bk = e;
>+                  bk = bk_e;
>                 } /* else no beachhead */
>               } else {
>                 *x = acity->x;
>                 *y = acity->y;
>-                bk = e;
>+                bk = bk_e;
>               }
>             }
>-            e = 0; /* END STEAM-ENGINES KLUGE */
>-          } else e = 0;
>+        }
>+        /* END STEAM-ENGINES KLUGE */
> 
>         if (punit->id && ferryboat && is_ground_unit(punit)) {
>           freelog(LOG_DEBUG, "%s@(%d, %d) -> %s@(%d, %d) -> %s@(%d, %d)"
>@@ -1410,10 +1426,7 @@
>           else if (c > THRESHOLD) b0 = 0;
>           else b0 = ((b * a - f * d) * SHIELD_WEIGHTING / (a + d)) - 
>             c * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING :
SHIELD_WEIGHTING);
>-          if (b0 > 0) {
>-            a0 = amortize(b0, MAX(1, c));
>-            e = ((a0 * b0) / (MAX(1, b0 - a0))) * 100 / (fprime * MORT);
>-          } else e = 0;
>+        e = military_amortize(b0, MAX(1, c), fprime);
>           if (e > best && ai_fuzzy(pplayer,1)) {
> #ifdef DEBUG
>             aa = a; bb = b; cc = c; dd = d; bestb0 = b0;
>Index: ai/aiunit.h
>===================================================================
>RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.h,v
>retrieving revision 1.24
>diff -u -r1.24 aiunit.h
>--- ai/aiunit.h        2001/01/10 18:50:45     1.24
>+++ ai/aiunit.h        2002/01/03 18:13:48
>@@ -34,6 +34,7 @@
> int unit_vulnerability_basic(struct unit *punit, struct unit *pdef);
> int unit_vulnerability_virtual(struct unit *punit);
> int unit_vulnerability(struct unit *punit, struct unit *pdef);
>+int military_amortize(int value, int delay, int build_cost);
> 
> int is_on_unit_upgrade_path(Unit_Type_id test, Unit_Type_id base);
> int is_ai_simple_military(Unit_Type_id type);
>




[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] Re: Military amortize (PR#1199), Ross W. Wetmore <=