[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]
--- Petr Baudis <pasky@xxxxxxxxxxx> wrote:
> Attached improved patch based on Mike's suggestion from next thread (TODO
> comment for diplomacy vs. capturing empty cities).
why put TODO when you can DO?
use is_non_allied_city_tile
btw, I'd remove TODOs before movecost and desire thing
you have one TODO concerning want equation, that' enough.
>
> --
>
> Petr "Pasky" Baudis
>
> * elinks maintainer * IPv6 guy (XS26 co-coordinator)
> * IRCnet operator * FreeCiv AI hacker
> .
> No one can feel as helpless as the owner of a sick goldfish.
> .
> Public PGP key && geekcode && homepage: http://pasky.ji.cz/~pasky/
> > 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.26
> diff -u -r1.1.1.8 -r1.26
> --- aiunit.c 19 Feb 2002 19:33:54 -0000 1.1.1.8
> +++ aiunit.c 20 Feb 2002 19:05:15 -0000 1.26
> @@ -733,106 +733,158 @@
> }
>
> /*************************************************************************
> -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.
> **************************************************************************/
> 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 current tile as the best (with value new_best). */
> +#define SET_TARGET(new_best) \
> + do { best = (new_best); *dest_x = x1; *dest_y = y1; } while (0)
> +
> + 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) {
> + best = 0 - 2 * MORT * TRADE_WEIGHTING; /* desperation */
> + }
> +
> + /* 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. */
> + 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;
> + /* 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. */
> + /* TODO: Remove this when moving the desire equation to separate
> + * function. */
> + int move_cost = 0;
> + /* The possible loss when we would loose this unit. */
> + /* TODO: Possibly remove this when moving the desire equation to
> + * separate function? */
> + int loss = unit_type(punit)->build_cost;
> +
> + attack *= attack;
> +
> + /* 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)) {
> + benefit = (benefit + 40) * punit->hp / unit_type(punit)->hp;
> }
> - }
> - } else { /* no pdef */
> - pcity = map_get_city(x1, y1);
> - if (pcity && is_ground_unit(punit) &&
> - map_get_terrain(punit->x, punit->y) != T_OCEAN) {
> - if (pcity->owner != pplayer->player_no) { /* free goodies */
> - best = 99999; *dest_y = y1; *dest_x = x1;
> +
> + /* If we have non-zero belligerence... */
> + if (attack > 0 && is_my_turn(punit, pdef)) {
> + int desire;
> +
> + /* TODO: This equation is simplified version of much worse ones
> in
> + * that long fat routines, but it's still a common pattern, so we
> + * will can this equation to one separate readable function. */
> +
> + /* attractiveness danger */
> + desire = ((benefit * attack - loss * vuln) * SHIELD_WEIGHTING
> + / (attack + vuln) - move_cost * SHIELD_WEIGHTING);
> +
> + /* No need to amortize! */
> +
> + if (desire > best && ai_fuzzy(pplayer, 1)) {
> + freelog(LOG_DEBUG, "Better than %d is %d (%s)",
> + best, desire, unit_type(pdef)->name);
> + SET_TARGET(desire);
> +
> + } else {
> + freelog(LOG_DEBUG, "NOT better than %d is %d (%s)",
> + best, desire, unit_type(pdef)->name);
> + }
> }
> }
> - if (map_has_special(x1, y1, 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;
> +
> + } else {
> + struct city *pcity = map_get_city(x1, y1);
> +
> + /* No defender... */
> +
> + /* ...and free foreign city waiting for us. Who would resist! */
> + /* TODO: When diplomacy is implemented, don't capture enemy cities so
> + * enthusiastically. -- Mike, pasky */
> + if (pcity && pcity->owner != pplayer->player_no &&
> is_ground_unit(punit)
> + && map_get_terrain(punit->x, punit->y) != T_OCEAN) {
> + SET_TARGET(99999);
> + }
> +
> + /* ...or tiny pleasant hut here! */
> + if (map_has_special(x1, y1, S_HUT) && best < 99999
> + && could_unit_move_to_tile(punit, punit->x, punit->y, x1, y1) !=
> 0
> + && !is_barbarian(unit_owner(punit))
> + && punit->ai.ai_role != AIUNIT_ESCORT
> + && punit->ai.charge == 0 /* Above line doesn't seem to work. :(
> */
> + && punit->ai.ai_role != AIUNIT_DEFEND_HOME) {
> + SET_TARGET(99998);
> + }
> +
> + /* If we have nothing to do, we can at least pillage something, hmm?
> */
> + if (is_land_barbarian(pplayer) && best == 0
> + && get_tile_infrastructure_set(map_get_tile(x1, y1)) != 0
> + && could_unit_move_to_tile(punit, punit->x, punit->y, x1, y1) !=
> 0) {
> + SET_TARGET(1);
> }
> - 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;
> - } /* next to nothing is better than nothing */
> }
> } adjc_iterate_end;
>
> return best;
> +
> +#undef SET_BEST
> }
>
> /*************************************************************************
> Index: aiunit.h
> ===================================================================
> RCS file: /home/cvs/aiciv/freeciv-a2/ai/aiunit.h,v
> retrieving revision 1.1.1.4
> retrieving revision 1.6
> diff -u -r1.1.1.4 -r1.6
>
__________________________________________________
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
- [Freeciv-Dev] [POLL] Variables descriptions: Votes on Style, (continued)
- [Freeciv-Dev] [POLL] Variables descriptions: Votes on Style, Raahul Kumar, 2002/02/22
- [Freeciv-Dev] Re: [POLL] Variables descriptions, Raimar Falke, 2002/02/22
- [Freeciv-Dev] Freeciv Combat System, Raahul Kumar, 2002/02/21
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Gregory Berkolaiko, 2002/02/21
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Gregory Berkolaiko, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Mike Kaufman, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Mike Kaufman, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/20
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264),
Gregory Berkolaiko <=
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/21
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Gregory Berkolaiko, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Gregory Berkolaiko, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Mike Kaufman, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Gregory Berkolaiko, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Mike Kaufman, 2002/02/22
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Raahul Kumar, 2002/02/23
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Petr Baudis, 2002/02/23
- [Freeciv-Dev] Re: [PATCH] aiunit.c ai_military_findvictim() cleanup (PR#1264), Raahul Kumar, 2002/02/22
|
|