Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2002:
[Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#
Home

[Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Petr Baudis <pasky@xxxxxxxxxxx>
Cc: Gregory Berkolaiko <gberkolaiko@xxxxxxxxxxx>, Mike Kaufman <kaufman@xxxxxxxxxxxxxxxxxxxxxx>, freeciv-dev@xxxxxxxxxxx, bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264)
From: Raahul Kumar <raahul_da_man@xxxxxxxxx>
Date: Fri, 22 Feb 2002 06:55:13 -0800 (PST)

--- Petr Baudis <pasky@xxxxxxxxxxx> wrote:
> Dear diary, on Fri, Feb 22, 2002 at 11:59:29AM CET, I got a letter,
> where Raahul Kumar <raahul_da_man@xxxxxxxxx> told me, that...
> > > +sane number means ordinar value of the victim
> > 
> > ordinar = ordinary.
> 
> Oops, yes sir.

That's more like it soldier.
 
<snip>
> > > +- 2 * MORT * TRADE_WEIGHTING means nothing found and punit causing
> > > unhappiness

> > Why the -? 
> 
> Because it is negative? (hint provided also by the fact that it's bellow
> zero)

Duh. I was wondering why you would not just just + 2 * MORT * TRADE_WEIGHTING 
everywhere. There's no obvious need for a negative version.


<snip>
> > > +  int bellig = unit_belligerence_primitive(punit);
> > 
> > Greg already said this, but there has to a better word than bellig. Angry,
> > pissed off strength, might, hardness toughness, offensive, etc.
> 
> But it IS belligerence :^). And renaming this function and possibly variable
> is
> out of scope of this patch. And no, I'm not going to have variable name and
> function name different, as I consider it confusing, compared to current
> situation ;).

LOL.

<snip>
> > > +  if (punit->unhappiness > 0) {
> > I believe but I am not sure, that the AI does not become democratic or
> > republic.
> > It's always on the offensive, so the unhappiness would kill it. Is unit
> > unhappiness actually an issue? 
> 
> AI does become republic, but not democracy (AFAIK). However .. see last
> Greg's
> mail about this issue :).
> 
> Going to comment this and check if savegames are same (one has to do at
> least best = -1, otherwise we may get catched by the pillage code when
> barbarians)...
> 
> Ok, they aren't. What broke our predictions today was the fact that desire
> may be negative - thus the mean of the unhappy calculation was completely
> opposite to the one we thought.

Negative desire means what? Tell me more about what the unhappy calc actually
is.


> This is an exception and I think it's best this way here. It doesn't wrap at
> least :^).

Not much to be done. It's just damn hard to read and parse.

> > Value of a city? I thought it was shield cost of a riflemen.
> 
> It can't be a same number? :)

Possibly. I wish I knew the how/why of the 40 number. Share your theories with
me.

 
> Improved patch attached (we finally comment the unhappy equation propeerly).
> I also made blank lines between declarations due to popular demand (hopefully
> everyone will be happy with this; even Mike proposed this for very long
> comments :).
> 

> > Index: advdomestic.c
> ===================================================================
> RCS file: /home/cvs/aiciv/freeciv-a2/ai/advdomestic.c,v
> retrieving revision 1.1.1.5
> retrieving revision 1.20
> diff -u -r1.1.1.5 -r1.20
> Index: aiunit.c
> ===================================================================
> RCS file: /home/cvs/aiciv/freeciv-a2/ai/aiunit.c,v
> retrieving revision 1.1.1.8
> retrieving revision 1.36
> diff -u -r1.1.1.8 -r1.36
> --- aiunit.c  19 Feb 2002 19:33:54 -0000      1.1.1.8
> +++ aiunit.c  22 Feb 2002 14:31:08 -0000      1.36
> @@ -733,106 +733,175 @@
>  }
>  
>  /*************************************************************************
> -This looks at tiles neighbouring the unit to find something to kill or
> -explore. It prefers tiles in the following order:
> +This function looks at tiles directly neighbouring the unit in order to find
> +something to kill or explore.  It prefers tiles in the following order:
> +
>  1. Undefended cities
>  2. Huts
>  3. Enemy units weaker than the unit
>  4. Land barbarians also like unfrastructure tiles (for later pillage)
> -If none of the following is there, nothing is chosen.
>  
> -work of Syela - mostly to fix the ZOC/goto strangeness
> +If none of the following is there, nothing is chosen and dest_x, dest_y is
> set
> +to actual punit's position.
> +
> +Returns value of the victim which has been chosen:
> +
> +99999   means empty city
> +99998   means hut
> +sane number means ordinary value of the victim
> +1       means barbarians wanting to pillage
> +0       means nothing found or error
> +-2*MORT*TRADE_WEIGHTING means nothing found and punit causing unhappiness
>  **************************************************************************/
>  static int ai_military_findvictim(struct player *pplayer, struct unit
> *punit,
> -                               int *dest_x, int *dest_y)
> +                                  int *dest_x, int *dest_y)
>  {
> -  int x, y;
> -  int best = 0, a, b, c, d, e, f;
> -  struct unit *pdef;
> -  struct unit *patt;
> -  struct city *pcity;
> -  x = punit->x;
> -  y = punit->y;
> +  /* Set the tile with our target as the best (with value new_best). */
> +#define SET_BEST(new_best) \
> +  do { best = (new_best); *dest_x = x1; *dest_y = y1; } while (FALSE)
> +
> +  int bellig = unit_belligerence_primitive(punit);
> +  int x = punit->x, y = punit->y;
> +  int best = 0;
> +  
>    *dest_y = y;
>    *dest_x = x;
> -  if (punit->unhappiness) best = 0 - 2 * MORT * TRADE_WEIGHTING; /*
> desperation */
> -  f = unit_type(punit)->build_cost;
> -  c = 0; /* only dealing with adjacent victims here */
> -
> -  if (get_transporter_capacity(punit)) {
> -    unit_list_iterate(map_get_tile(x, y)->units, aunit)
> -      if (!is_sailing_unit(aunit)) return(0);
> -    unit_list_iterate_end;
> -  } /* ferryboats do not attack.  no. -- Syela */
> +  
> +  if (punit->unhappiness > 0) {
> +    /* When we're causing unhappiness, we'll set best even lower, so that we
> +     * will take even targets which we would ignore otherwise (in other
> words -
> +     * we're going to commit a suicide). */

Oh, this makes much more sense. Hmmm, is disbanding/changing support to other
cities not better than suicide? Not that I care about the life of my units.
They should all be glad to die for the greater glory of me ;).

> +    best = 0 - 2 * MORT * TRADE_WEIGHTING;
> +  }
> +
> +  /* Ferryboats with passengers do not attack. -- Syela */
> +  if (punit->ai.passenger > 0) {
> +    return 0;
> +  }
>  
>    adjc_iterate(x, y, x1, y1) {
> -    pdef = get_defender(punit, x1, y1);
> +    struct unit *pdef = get_defender(punit, x1, y1);
> +    
>      if (pdef) {
> -      patt = get_attacker(punit, x1, y1);
> -/* 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 */
> -        d = unit_vulnerability(punit, pdef);
> -        if (map_get_city(x, y) && /* pikemen defend Knights, attack
> Catapults */
> -              get_total_defense_power(pdef, punit) *
> -              get_total_defense_power(punit, pdef) >= /* didn't like > --
> Syela */
> -              get_total_attack_power(patt, punit) * /* patt, not pdef */
> -              get_total_attack_power(punit, pdef) &&
> -              unit_list_size(&(map_get_tile(punit->x, punit->y)->units)) < 2
> &&
> -           get_total_attack_power(patt, punit)) { 
> -       freelog(LOG_DEBUG, "%s defending %s from %s's %s",
> -               unit_type(punit)->name,
> -               map_get_city(x, y)->name,
> -               unit_owner(pdef)->name, unit_type(pdef)->name);
> -        } else {
> -          a = reinforcements_value(punit, pdef->x, pdef->y);
> -          a += unit_belligerence_primitive(punit);
> -          a *= a;
> -          b = unit_type(pdef)->build_cost;
> -          if (map_get_city(x1, y1)) /* bonus restored 980804 -- Syela */
> -            b = (b + 40) * punit->hp / unit_type(punit)->hp;
> -/* c is always equal to zero in this routine, and f is already known */
> -/* arguable that I should use reinforcement_cost here?? -- Syela */
> -          if (a && is_my_turn(punit, pdef)) {
> -            e = ((b * a - f * d) * SHIELD_WEIGHTING / (a + d) - c *
> SHIELD_WEIGHTING);
> -/* no need to amortize! */
> -            if (e > best && ai_fuzzy(pplayer, TRUE)) {
> -           freelog(LOG_DEBUG, "Better than %d is %d (%s)",
> -                         best, e, unit_type(pdef)->name);
> -              best = e; *dest_y = y1; *dest_x = x1;
> -            } else {
> -           freelog(LOG_DEBUG, "NOT better than %d is %d (%s)",
> -                         best, e, unit_type(pdef)->name);
> -         }
> -          } /* end if we have non-zero belligerence */
> +      struct unit *patt = get_attacker(punit, x1, y1);
> +
> +      if (!can_unit_attack_tile(punit, x1, y1))
> +        continue;
> +
> +      /* If we are in the city, let's deeply consider defending it -
> however,
> +       * horsemen in city refused to attack phalanx just outside that was
> +       * bodyguarding catapult; thus, we get the best attacker on the tile
> as
> +       * well, for the case when there are multiple different units on one
> +       * title. Thus we force punit to attack a stack of units if they are
> +       * endangering punit seriously, even if they aren't that weak. */
> +      /* FIXME: The get_total_defense_power(pdef, punit) should probably use
> +       * patt rather than pdef. There also ought to be a better metric for
> +       * determining this. */

Defence power should use pdef.

> +      if (map_get_city(x, y)
> +          && get_total_defense_power(pdef, punit) *
> +             get_total_defense_power(punit, pdef) >= /* didn't like >
> --Syela */
> +             get_total_attack_power(patt, punit) *
> +             get_total_attack_power(punit, pdef)
> +          && unit_list_size(&(map_get_tile(punit->x, punit->y)->units)) < 2
> +          && get_total_attack_power(patt, punit) > 0) {
> +        freelog(LOG_DEBUG, "%s defending %s from %s's %s",
> +                unit_type(punit)->name,
> +                map_get_city(x, y)->name,
> +                unit_owner(pdef)->name, unit_type(pdef)->name);
> +        
> +      } else {
> +        int vuln = unit_vulnerability(punit, pdef);
> +        
> +        /* The total possible attack power we can throw on the victim. Note
> +         * that we will even square this. */
> +        int attack = reinforcements_value(punit, pdef->x, pdef->y)
> +                     + bellig;
> +        

Beautiful equation. Not E = MC2, but compared to the original it's a
masterpiece.

> +        /* Something like 'attractiveness' of the victim, how nice it would
> +         be to destroy it. Larger value, worse loss for enemy. */
> +        int benefit = unit_type(pdef)->build_cost;
> +        
> +        /* We're only dealing with adjacent victims here. */
> +        int move_cost = 0;
> +        
> +        /* The possible loss when we would lose the unit we want to attack.
> */
> +        int loss = unit_type(punit)->build_cost;
> +

Excellent.
        
> +        attack *= attack;
> +

Multiplying attack by attack, and defence by defence then square rooting them.
This is certainly an interesting way to work out odds of winning.
        
> +        /* If the victim is in the city, we increase the benefit and correct
> +         * it with our health because there may be more units in the city
> +         * stacked, and we won't destroy them all at once, so in the next
> +         * turn they may attack us. So we shouldn't send already injured
> +         * units to useless suicide. */
> +        if (map_get_city(x1, y1)) {
> +          /* 40 is something like value of a city, as used in many other
> parts
> +           * of code (?). --pasky */
> +          benefit = (benefit + 40) * punit->hp / unit_type(punit)->hp;
>          }
> -      }
> -    } else { /* no pdef */
> -      pcity = map_get_city(x1, y1);
> -      if (pcity && is_ground_unit(punit) &&
> 

Goddamn yahoo and their truncated messages. It looks good to me. 

Aloha,
Raahul.

__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com


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