Index: ai/Makefile.am =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/Makefile.am,v retrieving revision 1.8 diff -u -r1.8 Makefile.am --- ai/Makefile.am 2001/12/11 16:16:25 1.8 +++ ai/Makefile.am 2002/08/21 00:22:40 @@ -27,6 +27,8 @@ advtrade.h \ aicity.c \ aicity.h \ + aidata.c \ + aidata.h \ aihand.c \ aihand.h \ aitech.c \ Index: ai/advdomestic.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/advdomestic.c,v retrieving revision 1.86 diff -u -r1.86 advdomestic.c --- ai/advdomestic.c 2002/07/21 00:48:38 1.86 +++ ai/advdomestic.c 2002/08/21 00:22:41 @@ -29,110 +29,11 @@ #include "aicity.h" #include "aitools.h" #include "aiunit.h" +#include "aidata.h" #include "advdomestic.h" /************************************************************************** - Make and cache lots of calculations needed for other functions, notably: - ai_eval_defense_land, ai_eval_defense_nuclear, ai_eval_defense_sea and - ai_eval_defense_air. - - FIXME: We should try to find the lowest common defence strength of our - defending units, and ignore enemy units that are incapable of harming - us, instead of just checking attack strength > 1. -**************************************************************************/ -void ai_eval_threat_init(struct player *pplayer) { - int i, nuke_units = num_role_units(F_NUCLEAR); - bool got_nukes = FALSE; - bool have_antisea = can_player_build_improvement(pplayer, B_COASTAL); - bool have_antiair = can_player_build_improvement(pplayer, B_SAM); - bool have_antinuke = can_player_build_improvement(pplayer, B_SDI); - bool have_antimissile = can_player_build_improvement(pplayer, B_SDI); - - pplayer->ai.eval_threat.continent = - fc_calloc(map.num_continents + 1, sizeof(bool)); - pplayer->ai.eval_threat.invasions = FALSE; - pplayer->ai.eval_threat.air = FALSE; - pplayer->ai.eval_threat.nuclear = 0; - pplayer->ai.eval_threat.sea = FALSE; - - players_iterate(aplayer) { - /* allies and ourselves we trust, we don't trust peace treaties that much */ - if (pplayers_allied(pplayer, aplayer)) continue; - - /* 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. */ - city_list_iterate(aplayer->cities, acity) { - int continent = map_get_continent(acity->x, acity->y); - pplayer->ai.eval_threat.continent[continent] = TRUE; - } city_list_iterate_end; - - unit_list_iterate(aplayer->units, punit) { - if (is_sailing_unit(punit)) { - - /* If the enemy has not started sailing yet, or we have total - * control over the seas, don't worry, keep attacking. */ - if (is_ground_units_transport(punit)) { - pplayer->ai.eval_threat.invasions = TRUE; - } - - /* 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 (have_antisea && unit_type(punit)->attack_strength > 1) { - pplayer->ai.eval_threat.sea = TRUE; - } - } - - /* 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 (have_antiair && (is_air_unit(punit) || is_heli_unit(punit)) - && unit_type(punit)->attack_strength > 1) { - pplayer->ai.eval_threat.air = TRUE; - } - - /* If our enemy builds missiles, worry about missile defence. */ - if (have_antimissile && unit_flag(punit, F_MISSILE) - && unit_type(punit)->attack_strength > 1) { - pplayer->ai.eval_threat.missile = TRUE; - } - - /* If he builds nukes, worry a lot. */ - if (have_antinuke && unit_flag(punit, F_NUCLEAR)) got_nukes = TRUE; - - /* If all our darkest fears have come true, we're done here. It - * can't possibly get any worse! */ - if ((pplayer->ai.eval_threat.air || !have_antiair) - && (pplayer->ai.eval_threat.missile || !have_antimissile) - && (got_nukes || !have_antinuke) - && (pplayer->ai.eval_threat.sea || !have_antisea) - && pplayer->ai.eval_threat.invasions) { - break; - } - } 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); - if (can_player_build_unit_direct(aplayer, nuke)) { - pplayer->ai.eval_threat.nuclear = 1; - } - } - } players_iterate_end; - - /* Increase from fear to terror if opponent actually has nukes */ - if (got_nukes) pplayer->ai.eval_threat.nuclear++; -} - -/************************************************************************** - Clean up our mess. -**************************************************************************/ -void ai_eval_threat_done(struct player *pplayer) { - free(pplayer->ai.eval_threat.continent); -} - -/************************************************************************** Calculate desire for land defense. First look for potentially hostile cities on our continent, indicating danger of being attacked by land. Then check if we are on the shoreline because we want to stop invasions @@ -147,6 +48,7 @@ **************************************************************************/ static int ai_eval_threat_land(struct player *pplayer, struct city *pcity) { + struct ai_data *ai = ai_data_get(pplayer); int continent; bool vulnerable; @@ -156,9 +58,9 @@ } continent = map_get_continent(pcity->x, pcity->y); - vulnerable = pplayer->ai.eval_threat.continent[continent] + vulnerable = ai->threats.continent[continent] || city_got_building(pcity, B_PALACE) - || (pplayer->ai.eval_threat.invasions + || (ai->threats.invasions && is_water_adjacent_to_tile(pcity->x, pcity->y)); /* 40 is a magic number inherited from Syela */ @@ -170,13 +72,15 @@ **************************************************************************/ static int ai_eval_threat_sea(struct player *pplayer, struct city *pcity) { + struct ai_data *ai = ai_data_get(pplayer); + /* 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_threat.sea ? 40 : 1; + return ai->threats.sea ? 40 : 1; } /************************************************************************** @@ -184,6 +88,7 @@ **************************************************************************/ static int ai_eval_threat_air(struct player *pplayer, struct city *pcity) { + struct ai_data *ai = ai_data_get(pplayer); int continent; bool vulnerable; @@ -193,8 +98,8 @@ } continent = map_get_continent(pcity->x, pcity->y); - vulnerable = pplayer->ai.eval_threat.air - && (pplayer->ai.eval_threat.continent[continent] + vulnerable = ai->threats.air + && (ai->threats.continent[continent] || is_water_adjacent_to_tile(pcity->x, pcity->y) || city_got_building(pcity, B_PALACE)); @@ -212,6 +117,7 @@ **************************************************************************/ static int ai_eval_threat_nuclear(struct player *pplayer, struct city *pcity) { + struct ai_data *ai = ai_data_get(pplayer); int continent; int vulnerable = 1; @@ -221,10 +127,10 @@ } /* No non-allied player has nuclear capability yet. */ - if (pplayer->ai.eval_threat.nuclear == 0) { return 0; } + if (ai->threats.nuclear == 0) { return 0; } continent = map_get_continent(pcity->x, pcity->y); - vulnerable += pplayer->ai.eval_threat.continent[continent] + vulnerable += ai->threats.continent[continent] || is_water_adjacent_to_tile(pcity->x, pcity->y) || city_got_building(pcity, B_PALACE); @@ -232,7 +138,7 @@ 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_threat.nuclear + vulnerable) * 20); + return ((ai->threats.nuclear + vulnerable) * 20); } /************************************************************************** @@ -240,14 +146,15 @@ **************************************************************************/ static int ai_eval_threat_missile(struct player *pplayer, struct city *pcity) { + struct ai_data *ai = ai_data_get(pplayer); int continent = map_get_continent(pcity->x, pcity->y); bool vulnerable = is_water_adjacent_to_tile(pcity->x, pcity->y) - || pplayer->ai.eval_threat.continent[continent] + || ai->threats.continent[continent] || city_got_building(pcity, B_PALACE); /* Only build missile defence if opponent builds them, and we are in a vulnerable spot. FIXME: 10 is a totally arbitrary Syelaism. - Per */ - return (pplayer->ai.eval_threat.missile && vulnerable) ? 10 : 0; + return (ai->threats.missile && vulnerable) ? 10 : 0; } /************************************************************************** Index: ai/aiunit.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v retrieving revision 1.205 diff -u -r1.205 aiunit.c --- ai/aiunit.c 2002/08/17 09:00:52 1.205 +++ ai/aiunit.c 2002/08/21 00:22:41 @@ -44,6 +44,7 @@ #include "aicity.h" #include "aihand.h" #include "aitools.h" +#include "aidata.h" #include "aiunit.h" @@ -265,6 +266,13 @@ int move_rate = unit_move_rate(punit); /* Range of unit's vision */ int range; + struct ai_data *ai = ai_data_get(pplayer); + + /* Abort if all is explored on this continent */ + if (is_ground_unit(punit) && map_get_terrain(x, y) != T_OCEAN + && !ai->explore.continent[map_get_continent(x, y)]) { + return FALSE; + } /* Get the range */ /* FIXME: The vision range should NOT take into account watchtower benefit. Index: common/player.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/player.h,v retrieving revision 1.80 diff -u -r1.80 player.h --- common/player.h 2002/08/07 21:38:03 1.80 +++ common/player.h 2002/08/21 00:22:41 @@ -113,19 +113,6 @@ int spaceship; }; -/* these variables are used for improvements evaluations in - * ai/advdomestic.c, only valid between ai_eval_threat_init() - * and ai_eval_threat_done() - */ -struct eval_threat_type { - bool invasions; /* check if we need to consider invasions */ - bool *continent; /* non-allied cities on continent? */ - bool sea; /* check if exists non-allied offensive ships */ - bool air; /* check for non-allied offensive aircraft */ - bool missile; /* check for non-allied missiles */ - int nuclear; /* nuke check: 0=no, 1=capability, 2=built */ -}; - struct player_ai { bool control; int tech_goal; @@ -139,7 +126,6 @@ int expand; /* percentage factor to value new cities */ int warmth; /* threat of global warming */ enum barbarian_type barbarian_type; - struct eval_threat_type eval_threat; }; /* Diplomatic states (how one player views another). Index: server/plrhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v retrieving revision 1.242 diff -u -r1.242 plrhand.c --- server/plrhand.c 2002/08/10 17:07:28 1.242 +++ server/plrhand.c 2002/08/21 00:22:42 @@ -41,7 +41,7 @@ #include "unittools.h" #include "advmilitary.h" -#include "advdomestic.h" +#include "aidata.h" #include "aihand.h" #include "aitech.h" @@ -1649,7 +1649,7 @@ /* Not sure if this is necessary, but might be a good idea to avoid doing some ai calculations with bogus data: */ - ai_eval_threat_init(cplayer); + ai_data_turn_init(cplayer); assess_danger_player(cplayer); if (pplayer->ai.control) { assess_danger_player(pplayer); Index: server/settlers.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v retrieving revision 1.140 diff -u -r1.140 settlers.c --- server/settlers.c 2002/08/14 01:44:59 1.140 +++ server/settlers.c 2002/08/21 00:22:42 @@ -32,6 +32,7 @@ #include "aicity.h" #include "aiunit.h" +#include "aidata.h" #include "settlers.h" @@ -1568,6 +1569,8 @@ struct unit virtualunit; int want; int best_act, gx, gy; /* dummies */ + struct tile *ptile = map_get_tile(pcity->x, pcity->y); + struct ai_data *ai = ai_data_get(pplayer); memset(&virtualunit, 0, sizeof(struct unit)); virtualunit.id = 0; @@ -1590,6 +1593,12 @@ want = -199; } unit_list_iterate_end; #endif + + /* modify our desire based on available statistics to prevent + * overflooding with worker type units if they come cheap in + * the ruleset */ + want /= MAX(1, ai->stats.workers[ptile->continent] + / MAX(1, ai->stats.cities[ptile->continent])); assert(want >= 0); pcity->ai.settler_want = want; Index: server/srv_main.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v retrieving revision 1.90 diff -u -r1.90 srv_main.c --- server/srv_main.c 2002/08/19 23:05:35 1.90 +++ server/srv_main.c 2002/08/21 00:22:43 @@ -90,7 +90,7 @@ #include "unittools.h" #include "advmilitary.h" -#include "advdomestic.h" +#include "aidata.h" #include "aihand.h" #include "srv_main.h" @@ -397,7 +397,7 @@ pplayer->player_no, pplayer->name); begin_player_turn(pplayer); /* human players also need this for building advice */ - ai_eval_threat_init(pplayer); + ai_data_turn_init(pplayer); } players_iterate_end; players_iterate(pplayer) { @@ -432,7 +432,7 @@ nocity_send = FALSE; players_iterate(pplayer) { send_player_cities(pplayer); - ai_eval_threat_done(pplayer); + ai_data_turn_done(pplayer); } players_iterate_end; flush_packets(); /* to curb major city spam */