Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2001:
[Freeciv-Dev] Re: RFC: Fixing movement code
Home

[Freeciv-Dev] Re: RFC: Fixing movement code

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Raahul Kumar <raahul_da_man@xxxxxxxxx>
Cc: freeciv development list <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: RFC: Fixing movement code
From: Petr Baudis <pasky@xxxxxxxxxxx>
Date: Thu, 22 Nov 2001 14:19:24 +0100

> ai_military_find_victim
> 
> Any ideas for something better than a,b,c,d,e,f
> 
> f should be unit_build_cost

f is only once assigned and once used. why we shouldn't use the
unit_type(punit)->build_cost?

> what the hell is b? 
>           b = unit_type(pdef)->build_cost;
/* bonus restored 980804 -- Syela */ - so b == bonus?
> b = (b + 40) * punit->hp / unit_type(punit)->hp;
and finally..
e = ((b * a - f * d) * SHIELD_WEIGHTING / (a + d) - c * SHIELD_WEIGHTING);
(final calculation)

i see no other usage of it. looks really like bonus enemy unit has against our
one.

c is zero everytime, no other assigment, so we can safely remove it imho.

d is unit_vulnerability(punit, pdef); so we can call it vuln. used in the
final calculation only as well.

e is used as final coeficient used to choose best victim. so what about coef?

a is most misterious. however, after some study of code, it seems to me it
is kinda 'aggressivity'. in the mind comes that we can pre-compute something
before, so it will speed things a bit.

so, after also some indendation etc, it would look this nice way:

static int ai_military_findvictim(struct player *pplayer, struct unit *punit,
                                  int *dest_x, int *dest_y)
{
  int x, y;
  int best = 0, belligerence;
  struct unit *pdef;
  struct unit *patt;
  struct city *pcity;

  x = punit->x;
  y = punit->y;
  *dest_y = y;
  *dest_x = x;
  if (punit->unhappiness) best = 0 - 2 * MORT * TRADE_WEIGHTING; /* desperation 
*/

  belligerence = unit_belligerence_primitive(punit);

  /* ferryboats do not attack.  no. -- Syela */
  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;
  }

  adjc_iterate(x, y, x1, y1) {
    pdef = get_defender(punit, x1, y1);
    if (pdef) {

      /* horsemen in city refused to attack phalanx just outside that was
      bodyguarding catapult - patt will resolve this bug nicely -- Syela */
      patt = get_attacker(punit, x1, y1);

      if (can_unit_attack_tile(punit, x1, y1)) { /* thanks, Roar */
        int vuln;
        vuln = 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 {
          int agress, bonus, coef;

          agress = reinforcements_value(punit, pdef->x, pdef->y);
          agress += belligerence;
          agress *= agress;

          bonus = unit_type(pdef)->build_cost;
          if (map_get_city(x1, y1)) /* bonus restored 980804 -- Syela */
            bonus = (bonus + 40) * punit->hp / unit_type(punit)->hp;

          /* arguable that I should use reinforcement_cost here?? -- Syela */
          if (a && is_my_turn(punit, pdef)) {
            coef = ((bonus * agress - unit_type(punit)->build_cost * vuln) * 
SHIELD_WEIGHTING /
                    (agress + vuln) * SHIELD_WEIGHTING);

            /* no need to amortize! */
            if (coef > best && ai_fuzzy(pplayer, 1)) {
              freelog(LOG_DEBUG, "Better than %d is %d (%s)",
                            best, coef, unit_type(pdef)->name);
              best = coef; *dest_y = y1; *dest_x = x1;
            } else {
              freelog(LOG_DEBUG, "NOT better than %d is %d (%s)",
                            best, coef, unit_type(pdef)->name);
            }
          } /* end if we have non-zero belligerence */
        }
      }

    } else { /* no pdef */
      pcity = map_get_city(x1, y1);

      if (pcity && is_ground_unit(punit) &&
          map_get_terrain(punit->x, punit->y) != T_OCEAN &&
          pcity->owner != pplayer->player_no) { /* free goodies */
        best = 99999; *dest_y = y1; *dest_x = x1;
      }

      if (map_get_tile(x1, y1)->special & S_HUT &&
          best < 99999 &&
          could_unit_move_to_tile(punit, punit->x, punit->y, x1, y1) &&
          !is_barbarian(unit_owner(punit)) &&
/*          zoc_ok_move(punit, x1, y1) &&
          !is_sailing_unit(punit) && */
          punit->ai.ai_role != AIUNIT_ESCORT && /* makes life easier */
          !punit->ai.charge && /* above line seems not to work. :( */
          punit->ai.ai_role != AIUNIT_DEFEND_HOME) { /* Oops! -- Syela */
        best = 99998; *dest_y = y1; *dest_x = x1;
      }

      /* next to nothing is better than nothing */
      if (is_land_barbarian(pplayer) && best == 0 &&
          get_tile_infrastructure_set(map_get_tile(x1, y1)) &&
          could_unit_move_to_tile(punit, punit->x, punit->y, x1, y1)) {
        best = 1; *dest_y = y1; *dest_x = x1;
      }
    }
  } adjc_iterate_end;

  return best;
}

-- 

                                Petr "Pasky" Baudis

UN*X programmer, UN*X administrator, hobbies = IPv6, IRC
Real Users hate Real Programmers.
Public PGP key, geekcode and stuff: http://pasky.ji.cz/~pasky/


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