diff ai/advdomestic.c ai/advdomestic.c --- ai/advdomestic.c Thu Jan 11 11:01:45 2001 +++ ai/advdomestic.c Fri Jan 12 10:35:43 2001 @@ -31,12 +31,6 @@ #include "advdomestic.h" -/********************************************************************** -... this function should assign a value to choice and want and type, where - want is a value between 1 and 100. - if want is 0 this advisor doesn't want anything - type = 1 means unit, type = 0 means building -***********************************************************************/ static int ai_best_tile_value(struct city *pcity) { @@ -523,7 +517,13 @@ } return; -} +} + +/********************************************************************** +... this function should assign a value to choice and want and type, where + want is a value between 1 and 100. + if want is 0 this advisor doesn't want anything +***********************************************************************/ void domestic_advisor_choose_build(struct player *pplayer, struct city *pcity, struct ai_choice *choice) @@ -538,7 +538,7 @@ choice->choice = 0; choice->want = 0; - choice->type = 0; + choice->type = CT_NONE; con = map_get_continent(pcity->x, pcity->y); utid = best_role_unit(pcity, F_SETTLERS); @@ -553,11 +553,11 @@ freelog(LOG_DEBUG, "%s (%d, %d) desires settlers with passion %d", pcity->name, pcity->x, pcity->y, want); choice->want = want; - choice->type = 1; + choice->type = CT_NONMIL; ai_choose_role_unit(pplayer, pcity, choice, F_SETTLERS, want); } else if (want < 0) { /* need boats to colonize! */ choice->want = 0 - want; - choice->type = 1; + choice->type = CT_NONMIL; choice->choice = best_role_unit(pcity, F_SETTLERS); /* default */ ai_choose_ferryboat(pplayer, pcity, choice); } @@ -576,11 +576,11 @@ freelog(LOG_DEBUG, "%s (%d, %d) desires founders with passion %d", pcity->name, pcity->x, pcity->y, want); choice->want = want; - choice->type = 1; + choice->type = CT_NONMIL; ai_choose_role_unit(pplayer, pcity, choice, F_CITIES, want); } else if (want < -choice->want) { /* need boats to colonize! */ choice->want = 0 - want; - choice->type = 1; + choice->type = CT_NONMIL; choice->choice = best_role_unit(pcity, F_CITIES); /* default */ ai_choose_ferryboat(pplayer, pcity, choice); } @@ -617,7 +617,7 @@ if (can_build_unit_direct(pcity, iunit)) { if (want > choice->want) { choice->want = want; - choice->type = 1; + choice->type = CT_NONMIL; ai_choose_role_unit(pplayer, pcity, choice, F_CARAVAN, dw/2); } } else @@ -631,7 +631,7 @@ choice->want = cur.want; /* if (choice->want > 100) choice->want = 100; */ /* want > 100 means BUY RIGHT NOW */ - choice->type = 0; + choice->type = CT_BUILDING; } /* allowing buy of peaceful units after much testing -- Syela */ @@ -643,7 +643,7 @@ } if (iunit != U_LAST) { choice->want = 1; - choice->type = 1; + choice->type = CT_NONMIL; choice->choice = iunit; } } diff ai/advmilitary.c ai/advmilitary.c --- ai/advmilitary.c Thu Jan 11 11:01:45 2001 +++ ai/advmilitary.c Fri Jan 12 10:13:00 2001 @@ -527,7 +527,7 @@ } choice->choice = bestid; choice->want = danger; - choice->type = 3; + choice->type = CT_DEFENDER; return; } @@ -861,11 +861,11 @@ choice->choice = B_BARRACKS2; else choice->choice = B_BARRACKS; choice->want = e; - choice->type = 0; + choice->type = CT_BUILDING; } else { if (!myunit->id) { choice->choice = v; - choice->type = 2; /* type == 2 identifies attackers */ + choice->type = CT_ATTACKER; choice->want = e; if (needferry) ai_choose_ferryboat(pplayer, pcity, choice); freelog(LOG_DEBUG, "%s has chosen attacker, %s", @@ -874,7 +874,7 @@ choice->choice = ai_choose_defender(pcity); freelog(LOG_DEBUG, "%s has chosen defender, %s", pcity->name, unit_types[choice->choice].name); - choice->type = 1; + choice->type = CT_NONMIL; choice->want = e; } if (is_sailing_unit(myunit) && improvement_exists(B_PORT) @@ -883,7 +883,7 @@ if (get_invention(pplayer, tech) == TECH_KNOWN) { choice->choice = B_PORT; choice->want = e; - choice->type = 0; + choice->type = CT_BUILDING; } else pplayer->ai.tech_want[tech] += e; } } @@ -921,7 +921,6 @@ ... this function should assign a value to choice and want and type, where want is a value between 1 and 100. if want is 0 this advisor doesn't want anything - type = 1 means unit, type = 0 means building ***********************************************************************/ void military_advisor_choose_build(struct player *pplayer, struct city *pcity, struct ai_choice *choice) @@ -935,7 +934,7 @@ struct unit *aunit = 0; choice->choice = 0; choice->want = 0; - choice->type = 0; + choice->type = CT_NONE; /* TODO: recognize units that can DEFEND_HOME but are in the field. -- Syela */ @@ -954,7 +953,7 @@ freelog(LOG_DEBUG, "A diplomat will be built in city %s.", pcity->name); choice->want = 16000; /* diplomat more important than soldiers */ pcity->ai.urgency = 1; - choice->type = 3; /* defender */ + choice->type = CT_DEFENDER; choice->choice = u; return; } else if (num_role_units(F_DIPLOMAT)>0) { @@ -987,7 +986,7 @@ choice->choice = B_CITY; /* great wall is under domestic */ choice->want = pcity->ai.building_want[B_CITY]; /* hacked by assess_danger */ if (!urgency && choice->want > 100) choice->want = 100; - choice->type = 0; + choice->type = CT_BUILDING; } else if (pcity->ai.building_want[B_COASTAL] && def && can_build_improvement(pcity, B_COASTAL) && (danger < 101 || unit_list_size(&ptile->units) > 1) && @@ -995,7 +994,7 @@ choice->choice = B_COASTAL; /* great wall is under domestic */ choice->want = pcity->ai.building_want[B_COASTAL]; /* hacked by assess_danger */ if (!urgency && choice->want > 100) choice->want = 100; - choice->type = 0; + choice->type = CT_BUILDING; } else if (pcity->ai.building_want[B_SAM] && def && can_build_improvement(pcity, B_SAM) && (danger < 101 || unit_list_size(&ptile->units) > 1) && @@ -1003,7 +1002,7 @@ choice->choice = B_SAM; /* great wall is under domestic */ choice->want = pcity->ai.building_want[B_SAM]; /* hacked by assess_danger */ if (!urgency && choice->want > 100) choice->want = 100; - choice->type = 0; + choice->type = CT_BUILDING; } else if (danger > 0 && unit_list_size(&ptile->units) <= urgency) { process_defender_want(pplayer, pcity, danger, choice); if (!urgency && unit_types[choice->choice].defense_strength == 1) { @@ -1037,7 +1036,7 @@ if (want > choice->want) { choice->want = want; choice->choice = v; - choice->type = 1; + choice->type = CT_NONMIL; /* Why not CT_DEFENDER? -- Caz */ } } diff ai/aicity.c ai/aicity.c --- ai/aicity.c Thu Jan 11 11:01:45 2001 +++ ai/aicity.c Fri Jan 12 06:41:02 2001 @@ -14,6 +14,7 @@ #include #endif +#include #include #include #include @@ -184,7 +185,7 @@ bestchoice.choice = A_NONE; bestchoice.want = 0; - bestchoice.type = 0; + bestchoice.type = CT_NONE; if( is_barbarian(pplayer) ) { /* always build best attack unit */ Unit_Type_id i, iunit, bestunit = -1; @@ -207,7 +208,7 @@ if (bestunit != -1) { bestchoice.choice = bestunit; bestchoice.want = 101; - bestchoice.type = 2; + bestchoice.type = CT_ATTACKER; } else { freelog(LOG_VERBOSE, "Barbarians don't know what to build!\n"); @@ -260,7 +261,7 @@ establish_city_distances(pplayer, pcity); /* for caravans in other cities */ } else { pcity->currently_building = bestchoice.choice; - pcity->is_building_unit = (bestchoice.type > 0); + pcity->is_building_unit = is_unit_choice_type(bestchoice.type); } return; @@ -330,7 +331,7 @@ break; bestchoice.want = 0; - bestchoice.type = 0; + bestchoice.type = CT_NONE; bestchoice.choice = 0; city_list_iterate(pplayer->cities, acity) if (acity->anarchy) continue; @@ -343,8 +344,12 @@ city_list_iterate_end; if (!bestchoice.want) break; + + ASSERT_REAL_CHOICE_TYPE(bestchoice.type); - if (bestchoice.type && (!frugal || bestchoice.want > 200)) { /* if we want a unit */ + if (is_unit_choice_type(bestchoice.type) && + (!frugal || bestchoice.want > 200)) { /* if we want a unit */ + buycost = city_buy_cost(pcity); unit_list_iterate(map_get_tile(pcity->x, pcity->y)->units, punit) id = can_upgrade_unittype(pplayer, punit->type); @@ -401,40 +406,45 @@ pplayer->research.researching == A_NONE) { /* nothing else to do */ buycost = city_buy_cost(pcity); if (!pcity->shield_stock) ; - else if (!bestchoice.type && is_wonder(bestchoice.choice) && - buycost >= 200) ; /* wait for more vans */ - else if (bestchoice.type && unit_flag(bestchoice.choice, F_SETTLERS) && - !city_got_effect(pcity, B_GRANARY) && (pcity->size < 2 || - pcity->food_stock < pcity->size * game.foodbox)) ; - else if (bestchoice.type && bestchoice.type < 3 && /* not a defender */ - buycost > unit_types[bestchoice.choice].build_cost * 2) { /* too expensive */ + else if (bestchoice.type == CT_BUILDING && + is_wonder(bestchoice.choice) && + buycost >= 200); /* wait for more vans */ + + else if (is_unit_choice_type(bestchoice.type) && + unit_flag(bestchoice.choice, F_SETTLERS) && + !city_got_effect(pcity, B_GRANARY) && (pcity->size < 2 || + pcity->food_stock < pcity->size * game.foodbox)); + else if (is_unit_choice_type(bestchoice.type) && + bestchoice.type != CT_DEFENDER && + buycost > unit_types[bestchoice.choice].build_cost * 2) { /* too expensive */ if (unit_flag(bestchoice.choice, F_CARAVAN) && pplayer->ai.maxbuycost < 100) pplayer->ai.maxbuycost = 100; - } #ifdef GRAVEDANGERWORKS - else if (bestchoice.type == 3 && pcity->size == 1 && - pcity->ai.grave_danger > (assess_defense_quadratic(pcity) + - ai_city_defender_value(pcity, U_LEGION, bestchoice.choice)) * 2 && + } else if (bestchoice.type == CT_DEFENDER && pcity->size == 1 && + pcity->ai.grave_danger > (assess_defense_quadratic(pcity) + + ai_city_defender_value(pcity, U_LEGION, bestchoice.choice)) * 2 && pcity->food_stock + pcity->food_surplus < 10) { /* We're DOOMED */ freelog(LOG_VERBOSE, "%s is DOOMED!", pcity->name); try_to_sell_stuff(pplayer, pcity); /* and don't buy stuff */ pcity->currently_building = ai_choose_defender_limited(pcity, pcity->shield_stock + pcity->shield_surplus, 0); - } #endif - else if ((pplayer->economic.gold-pplayer->ai.est_upkeep) >= buycost + } else if ((pplayer->economic.gold-pplayer->ai.est_upkeep) >= buycost && (!frugal || bestchoice.want > 200)) { if (ai_fuzzy(pplayer,1) || (pcity->ai.grave_danger && !assess_defense(pcity))) { really_handle_city_buy(pplayer, pcity); /* adequately tested now */ } - } else if (bestchoice.type || !is_wonder(bestchoice.choice)) { + } else if (is_unit_choice_type(bestchoice.type) || + !is_wonder(bestchoice.choice)) { freelog(LOG_DEBUG, "%s wants %s but can't afford to buy it" " (%d < %d).", pcity->name, - (bestchoice.type ? unit_name(bestchoice.choice) - : get_improvement_name(bestchoice.choice)), - pplayer->economic.gold, buycost); - if (bestchoice.type && !unit_flag(bestchoice.choice, F_NONMIL)) { + (is_unit_choice_type(bestchoice.type) ? + unit_name(bestchoice.choice) : + get_improvement_name(bestchoice.choice)), + pplayer->economic.gold, buycost); + if (is_unit_choice_type(bestchoice.type) && + !unit_flag(bestchoice.choice, F_NONMIL)) { if (pcity->ai.grave_danger && !assess_defense(pcity)) { /* oh dear */ try_to_sell_stuff(pplayer, pcity); if ((pplayer->economic.gold-pplayer->ai.est_upkeep) >= buycost) @@ -445,10 +455,14 @@ } else if (buycost > pplayer->ai.maxbuycost) pplayer->ai.maxbuycost = buycost; /* possibly upgrade units here */ } /* end panic subroutine */ - if (bestchoice.type && unit_flag(bestchoice.choice, F_CARAVAN)) - if (buycost > pplayer->ai.maxbuycost) pplayer->ai.maxbuycost = buycost; + if (is_unit_choice_type(bestchoice.type) && + unit_flag(bestchoice.choice, F_CARAVAN)) { + if (buycost > pplayer->ai.maxbuycost) + pplayer->ai.maxbuycost = buycost; /* Gudy reminded me AI was slow to build wonders, I thought of the above -- Syela */ - if (!bestchoice.type) switch (bestchoice.choice) { + } + if (bestchoice.type == CT_BUILDING) { + switch (bestchoice.choice) { case B_AQUEDUCT: if (city_happy(pcity)) break; /* PASS THROUGH */ @@ -463,7 +477,8 @@ if (buycost > pplayer->ai.maxbuycost) pplayer->ai.maxbuycost = buycost; break; /* granaries/harbors/wonders not worth the tax increase */ - } /* end switch */ + } /* end switch */ + } /* I just saw Alexander save up for walls then buy a granary. Never again! -- Syela */ /* if (bestchoice.want > 200 && pplayer->ai.maxbuycost) frugal++; */ if (pplayer->ai.maxbuycost) frugal++; /* much more frugal -- Syela */ diff ai/aihand.c ai/aihand.c --- ai/aihand.c Thu Jan 11 11:01:46 2001 +++ ai/aihand.c Thu Jan 11 15:07:34 2001 @@ -513,3 +513,9 @@ freelog(LOG_DEBUG, "Done with %s.", pplayer->name); } + +int is_unit_choice_type(enum choice_type type) +{ + return type == CT_NONMIL || type == CT_ATTACKER || type == CT_DEFENDER; +} + diff ai/aihand.h ai/aihand.h --- ai/aihand.h Sat Jun 12 10:41:38 1999 +++ ai/aihand.h Thu Jan 11 15:07:38 2001 @@ -18,4 +18,6 @@ void ai_do_first_activities(struct player *pplayer); void ai_do_last_activities(struct player *pplayer); +int is_unit_choice_type(enum choice_type type); + #endif /* FC__AIHAND_H */ diff ai/aitools.c ai/aitools.c --- ai/aitools.c Thu Jan 11 11:01:46 2001 +++ ai/aitools.c Thu Jan 11 22:24:37 2001 @@ -169,7 +169,7 @@ } choice->want = want; choice->choice = id; - choice->type = 0; + choice->type = CT_BUILDING; } diff common/city.h common/city.h --- common/city.h Mon Jan 1 15:59:11 2001 +++ common/city.h Thu Jan 11 22:49:56 2001 @@ -116,11 +116,19 @@ } +enum choice_type { CT_NONE = 0, CT_BUILDING = 0, CT_NONMIL, CT_ATTACKER, + CT_DEFENDER, CT_LAST }; + + +#define ASSERT_REAL_CHOICE_TYPE(type) \ + assert(type >= 0 && type < CT_LAST && \ + (CT_NONE == CT_BUILDING || type != CT_NONE)); + struct ai_choice { int choice; /* what the advisor wants */ int want; /* how bad it wants it (0-100) */ - int type; /* unit/building or other depending on question */ + enum choice_type type; /* unit/building or other depending on question */ }; struct ai_city {