[Freeciv-Dev] Re: patch rfc: stop ai from building useless wall, sam, co
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Dear diary, on Thu, Apr 04, 2002 at 03:47:54AM CEST, I got a letter,
where "Per I. Mathisen" <Per.Inge.Mathisen@xxxxxxxxxxx> told me, that...
> It makes the AI make some crude calculations about whether it needs city
> walls, SAM, coastal fortress and SDI defences before building them. The
> calculations are documented in the source, so I won't go into them here.
> Unlike Peter's code, mine caches everything and uses a minimal extra CPU
> per city.
I think I like it ;).
> Index: common/player.h
> ===================================================================
> RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
> retrieving revision 1.75
> diff -u -r1.75 player.h
> --- common/player.h 2002/03/05 19:13:44 1.75
> +++ common/player.h 2002/04/04 01:42:14
> @@ -115,6 +115,11 @@
>
> struct player_ai {
> bool control;
> + bool eval_wall_gate; /* check if we need walls to stop invasions */
> + bool *eval_wall; /* do we need to build city walls yet? */
> + bool eval_coastal; /* do we need to build coastal defences yet? */
> + int eval_sdi; /* need to build SDI defences? 0=no, 1=maybe, 2=yes! */
> + bool eval_sam; /* do we need to build SAMs yet? */
> int tech_goal;
> int prev_gold;
> int maxbuycost;
I vote for special structure for storing these values. I plan to create it for
assess_danger() & family anyway...
> Index: ai/advdomestic.c
> ===================================================================
> RCS file: /home/freeciv/CVS/freeciv/ai/advdomestic.c,v
> retrieving revision 1.83
> diff -u -r1.83 advdomestic.c
> --- ai/advdomestic.c 2002/03/18 01:49:36 1.83
> +++ ai/advdomestic.c 2002/04/04 01:42:14
> @@ -31,8 +32,166 @@
>
> #include "advdomestic.h"
>
> +/**************************************************************************
> + Make and cache lots of calculations needed for other functions, notably:
> + ai_eval_walls, ai_eval_sdi, ai_eval_coastal and ai_eval_sam.
> +
> + FIXME 1: We need to write this so that it will work for generalised
> + improvements somehow. Need to think about this. - Per
> +
> + FIXME 2: We should check if many of the enemies units on a continent
> + have the F_IGWALL ability, and drop want for city walls if that is the
> + case. - Per
> +**************************************************************************/
> +static void ai_eval_init(struct player *pplayer) {
> + int i, nuke_units = num_role_units(F_NUCLEAR);
> + bool got_nukes = FALSE;
> +
> + pplayer->ai.eval_wall = fc_calloc(map.num_continents, sizeof(got_nukes));
I think sizeof(bool) is better. What if got_nukes type ever changes?
> + pplayer->ai.eval_wall_gate = FALSE;
> + pplayer->ai.eval_sam = FALSE;
> + pplayer->ai.eval_sdi = FALSE;
> + pplayer->ai.eval_coastal = FALSE;
> +
> + players_iterate(aplayer) {
> + if (pplayers_allied(pplayer, aplayer)) {
> + /* Just allies, we don't trust peace treaties _that_ much */
> + continue;
> + }
> +
> + city_list_iterate(aplayer->cities, acity) {
> + /* The idea is that if there aren't any hostile cities on
> + our continent, the danger of land attacks is not big
> + enough to warrant city walls. Concentrate instead on
> + coastal fortresses and hunting down enemy transports. */
> + pplayer->ai.eval_wall[map_get_continent(acity->x, acity->y)] = TRUE;
> + } city_list_iterate_end;
> +
> + unit_list_iterate(aplayer->units, punit) {
> + /* If the enemy has not started sailing yet, or we have total
> + control over the seas, don't worry, keep attacking. */
> + if (is_sailing_unit(punit)) {
> + pplayer->ai.eval_wall_gate = TRUE;
> + }
Blank line please.
> + /* The idea is that while our enemies don't have any offensive
> + seaborne units, we don't have to worry. Go on the offensive! */
> + if (unit_type(punit)->attack_strength > 1 && is_sailing_unit(punit)) {
> + pplayer->ai.eval_coastal = TRUE;
> + }
Blank line please.
> + /* The next idea is that if our enemies don't have any offensive
> + airborne units, we don't have to worry. Go on the offensive! */
> + if (unit_type(punit)->attack_strength > 0 && (is_air_unit(punit)
> + ||is_heli_unit(punit))) {
+ if (unit_type(punit)->attack_strength > 0 && (is_air_unit(punit) ||
+ is_heli_unit(punit))) {
> + pplayer->ai.eval_sam = TRUE;
> + }
Blank line please.
> + if (unit_flag(punit, F_NUCLEAR)) { got_nukes = TRUE; }
> + if (pplayer->ai.eval_sam && pplayer->ai.eval_coastal && got_nukes) {
> + break;
> + }
Eh? :) I don't get mean of the last if, sorry :).
> + } unit_list_iterate_end;
> +
> + /* Check for nuke capability */
> + for (i = 0; i < nuke_units; i++) {
> + Unit_Type_id nuke = get_role_unit(F_NUCLEAR, i);
Blank line please.
> + if (can_player_build_unit_direct(aplayer, nuke)) {
> + pplayer->ai.eval_sdi = 1;
> + }
> + }
> + } players_iterate_end;
Blank line please.
> + if (got_nukes) { pplayer->ai.eval_sdi++; } /* increase fear */
> +}
> +
> +/**************************************************************************
> + Clean up our mess.
> +**************************************************************************/
> +static void ai_eval_done(struct player *pplayer) {
> + free(pplayer->ai.eval_wall);
> +}
>
> /**************************************************************************
> + Calculates need for city walls. Looks for potentially hostile cities
> + on our continent. We quite intentionally don't rely on the great wall,
> + since we suddenly might find our cities helpless in the field without
> + city walls. We want city walls also in cities in the shorelines to
> + stop invasions, but only if a non-allied player has started using sea
> + units yet. If they are slow to go on the offensive, we should expand or
> + attack.
> +
> + FIXME: We should have a concept of "oceans" just like we do for
> + continents. Too many times I've seen the AI build destroyers and
> + coastal defences in inlands cities with a small pond adjacent. - Per
> +**************************************************************************/
> +static int ai_eval_walls(struct player *pplayer, struct city *pcity)
> +{
> + bool vulnerable = (is_water_adjacent_to_tile(pcity->x, pcity->y)
> + && pplayer->ai.eval_wall_gate)
> + || pplayer->ai.eval_wall[map_get_continent(pcity->x, pcity->y)];
> +
> + /* make easy AI dumb */
> + if (ai_handicap(pplayer, H_DEFENSIVE)) {
> + return 40;
> + }
> +
> + /* 40 is a magic number inherited from Syela */
I think it would be nice to have global #defines for those widely used magic
numbers (just a long-term goal; does NOT apply to your +20 ;).
> + return vulnerable ? 40 : 1;
> +}
> +
> +/**************************************************************************
> + Calculates need for costal defence.
> +**************************************************************************/
> +static int ai_eval_coastal(struct player *pplayer, struct city *pcity)
> +{
> + /* make easy AI stay dumb */
> + if (ai_handicap(pplayer, H_DEFENSIVE)) {
> + return 40;
> + }
> +
> + /* 40 is a magic number inherited from Syela */
> + return pplayer->ai.eval_coastal ? 40 : 1;
> +}
> +
> +/**************************************************************************
> + Calculates need for air defence.
> +**************************************************************************/
> +static int ai_eval_sam(struct player *pplayer, struct city *pcity)
> +{
> + /* make easy AI dumber */
> + if (ai_handicap(pplayer, H_DEFENSIVE)) {
> + return 50;
> + }
> +
> + /* 50 is a magic number inherited from Syela */
> + return pplayer->ai.eval_sam ? 50 : 0;
> +}
> +
> +/**************************************************************************
> + Calculates need for SDI defence. Looks for players capable of building
> + nuclear weapons. Capable of building, not has, because at this stage in
> + the game we can get nukes and use nukes faster than we can manage to
> + build SDIs. We also look if players _have_ nukes, and increase our
> + want for SDIs correspondingly. Lastly, we check if we are in a strategic
> + position (ie near water or on a continent with non-allied cities).
> +**************************************************************************/
> +static int ai_eval_sdi(struct player *pplayer, struct city *pcity)
> +{
> + int vulnerable = 1;
> +
> + /* make easy AI really dumb, like it was before */
> + if (ai_handicap(pplayer, H_DEFENSIVE)) {
> + return 50;
> + }
> +
> + vulnerable += is_water_adjacent_to_tile(pcity->x, pcity->y) ||
> + pplayer->ai.eval_wall[map_get_continent(pcity->x, pcity->y)];
> +
> + /* 20 is just a new magic number, which will be +20 if we are
> + in a vulnerable spot, and +20 if someone we are not allied
> + with really have built nukes. This might be overkill, but
> + at least it is not as bad as it used to be. */
> + return ((pplayer->ai.eval_sdi + vulnerable) * 20);
> +}
> +
> +/**************************************************************************
> Get value of best usable tile on city map.
> **************************************************************************/
> static int ai_best_tile_value(struct city *pcity)
I like the patch. It makes sense ;). Also, nicely commented and formatted!
--
Petr "Pasky" Baudis
* ELinks maintainer * IPv6 guy (XS26 co-coordinator)
* IRCnet operator * FreeCiv AI hacker
.
Teamwork is essential -- it allows you to blame someone else.
.
Public PGP key && geekcode && homepage: http://pasky.ji.cz/~pasky/
|
|