[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]
--- 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
|
|