Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2002:
[Freeciv-Dev] Re: [freeciv-ai] [Patch] Cleanup of process_*_want [1.6] (
Home

[Freeciv-Dev] Re: [freeciv-ai] [Patch] Cleanup of process_*_want [1.6] (

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Gregory Berkolaiko <Gregory.Berkolaiko@xxxxxxxxxxxx>, freeciv-dev@xxxxxxxxxxx
Cc: bugs@xxxxxxxxxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: [freeciv-ai] [Patch] Cleanup of process_*_want [1.6] (PR#1295)
From: Raahul Kumar <raahul_da_man@xxxxxxxxx>
Date: Thu, 2 May 2002 05:43:55 -0700 (PDT)

--- Gregory Berkolaiko <Gregory.Berkolaiko@xxxxxxxxxxxx> wrote:
> And here is the patch.
> I am also faking the patch tracking numbe.
> 
> G.
> 

Looks good to me. A few minor requests, for a sequel to this patch.

<snip>
> +  bool defended = has_a_normal_defender(pcity);
> +  /* Technologies we would like to have. */
> +  int tech_desire[U_LAST];
> +  /* Our favourite unit. */
> +  int best = 0;
> +  Unit_Type_id best_unit_type = 0; /* FIXME: 0 is legal value! */
> +

Make this -1, as in Ross's corecleanups. Otherwise the default will be settler.
If you are going to leave this unchanged, add the comment that 0 is the id of
the settler unit.

> +  memset(tech_desire, 0, sizeof(tech_desire));
> +  
> +  simple_ai_unit_type_iterate (unit_type) {
> +    int move_type = unit_types[unit_type].move_type;
> +    
> +    if (move_type == LAND_MOVING || move_type == SEA_MOVING) {
> +      /* How many technologies away it is? */
> +      int tech_dist = num_unknown_techs_for_goal(pplayer,
> +                        unit_types[unit_type].tech_requirement);
> +      /* How much we want the unit? */
> +      int desire = unit_desirability(unit_type, TRUE);
> +      
> +      /* We won't leave the castle empty when driving out to battlefield. */
> +      if (!defended && unit_type_flag(unit_type, F_FIELDUNIT)) desire = 0;
> +      
> +      desire /= POWER_DIVIDER/2; /* Good enough, no rounding errors. */
> +      desire *= desire;
> +      

Begging for your combat approx later, but not in this patch.



> +I decided this funct wasn't confusing enough, so I made kill_something_with
> +send it some more variables for it to meddle with. -- Syela
>  
> -      if (unit_types[i].move_type == LAND_MOVING && acity &&
> -          c > (player_knows_improvement_tech(city_owner(acity),
> -                                          B_CITY) ? 2 : 4) &&
> -          !unit_type_flag(i, F_IGWALL) && !city_got_citywalls(acity)) d *=
> 9; 
> +TODO: Get rid of these parameters :).
>  
> -      f = unit_types[i].build_cost;
> -      fprime = build_cost_balanced(i);
> +(x,y) is location of the target.
> +(best_value, best_choice) is pre-filled with our current choice, we only 
> +  consider units of the same move_type as best_choice
> +**************************************************************************/
> +static void process_attacker_want(struct player *pplayer, struct city
> *pcity,
> +                                  int value, Unit_Type_id victim_unit_type,
> +                                  bool veteran, int x, int y, bool unhap,
> +                                  int *best_value, int *best_choice,
> +                                  int boatx, int boaty, int boatspeed,
> +                                  int needferry)
> +{ 
> +  /* The enemy city.  acity == NULL means stray enemy unit */
> +  struct city *acity = map_get_city(x, y);
> +  bool shore = is_terrain_near_tile(pcity->x, pcity->y, T_OCEAN);
> +  int orig_move_type = unit_types[*best_choice].move_type;
> +  int victim_move_rate = (acity ? 1
> +                                : (unit_types[victim_unit_type].move_rate *
> +                             (unit_type_flag(victim_unit_type, F_IGTER) ? 3
> +                                                                        :
> 1)));

Yuck! Is this the fault of Yahoo, or does the original look this ugly?


> +    
> +    if ((move_type == LAND_MOVING || (move_type == SEA_MOVING && shore))
> +        && tech_req != A_LAST
> +        && (tech_dist > 0 ||
> +            !can_build_unit_direct(pcity,
> unit_types[unit_type].obsoleted_by))
> +        && unit_types[unit_type].attack_strength > 0 /* or we'll get SIGFPE
> */

Greg, purely as a matter of interest, which function would you have to change
to cope with upgrading obsolete units?

> +        && move_type == orig_move_type) {
> +      /* TODO: Case for B_AIRPORT. -- Raahul */

I thought you were against this ugly piece of code handling vet issues
for air units.

> +      /* Set the move_time appropriatelly. */
> +      
> +      switch(move_type) {
> +      case LAND_MOVING:
> +        if (boatspeed > 0) {
> +          /* It's either city or too far away, so don't bother with
> +           * victim_move_rate. */
> +          move_time = (warmap.cost[boatx][boaty] + move_rate - 1) /
> move_rate
> +                      + 1 + warmap.seacost[x][y] / boatspeed; /* kludge */
> +          if (unit_type_flag(unit_type, F_MARINES)) move_time -= 1;
> +          
> +        } else if (warmap.cost[x][y] <= move_rate) {
> +          /* It's adjacent. */
> +          move_time = 1;
> +

Is it really 1 turn? It could be less. We can fortify with fractional move
points/attack.


> +          /* FIXME? Why we should multiply the cost by move rate?! --pasky
> */
> +          move_time = (warmap.cost[x][y] * victim_move_rate + move_rate - 1)
> +                      / move_rate;

I'm not sure I understand this. Picture this scenario - tank attacker, victim
is
riflemen. Riflemen is 6 squares away. The stats for riflemen are move rate 1,
tank is move rate 3.


So

A few basic facts:

All unit move rates are multiplied by 3. Warmap cost is multiplied by terrain
cost factor, which in this example is grassland, so it is also 3.

move_time = ((6 * 3) = 18) * 3 + (9 - 1) / 9 = 6.888 turns to overtake riflemen
if it tries to run away. I think this figure is wrong. Let's run a thought
experiment.

Turn One

rifleman's turn - he moves away - distance is now 7 squares
tanks turn - he moves towards rifle - distance is now (7-3) = 4 squares

Turn two

rifleman's turn - he moves away - distance is now (4 + 1) = 5 squares
tanks turn - he moves towards rifle - distance is now (5-3) = 2 squares

Turn 3

rifleman's turn - he moves away - distance is now (2 + 1) = 3 squares
tanks turn - he moves towards rifle - distance is now (3-3) = 0 squares

By the 3rd turn the attacker has overtaken the victim!

If I am wrong about warmap multiplying the actual distance in squares by the
cost of moving over them please correct me. I think not however. The current
function is wrong no matter how you slice the salami.

I think this line should be instead

 move_time = (warmap.cost[x][y] / (move_rate - victim_move_rate));

Substitute in for previous example of rifle and tank

move_time = ((6 * 3) = 18) / (9 - 3));

move_time = 3 turns, which is the correct figure! Again, this is certainly
right.

Aloha,
RK.

"Our bombs are smarter than the average high school student. At least they can
find Kuwait." --A. Whitney Brown 

__________________________________________________
Do You Yahoo!?
Yahoo! Health - your guide to health and wellness
http://health.yahoo.com


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