[freeciv-ai] Re: (PR#8992) Patch: Building ferries
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8992 >
Gregory Berkolaiko wrote:
...
> I am forwarding the last patch I made in this series. It is pretty old
> (8 Aug)
...
> It
> contains some code that should be deleted rather than commented out. It
> is not likely to apply to CVS.
...
Attached is a version of the patch, updated to the 2004-10-03 CVS
snapshot. I've deleted the commented out code. I ran some auto games and
examined one game, so it hardly counts as tested.
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/ai/advdomestic.c
freeciv.PR8992/ai/advdomestic.c
--- vendor.freeciv.current/ai/advdomestic.c 2004-10-03 11:40:07.000000000
+0100
+++ freeciv.PR8992/ai/advdomestic.c 2004-10-07 00:23:00.000000000 +0100
@@ -200,7 +200,6 @@
choice->type = CT_NONMIL;
choice->choice = unit_type; /* default */
choice->need_boat = TRUE;
- ai_choose_role_unit(pplayer, pcity, choice, L_FERRYBOAT, -want);
}
}
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/ai/advmilitary.c
freeciv.PR8992/ai/advmilitary.c
--- vendor.freeciv.current/ai/advmilitary.c 2004-10-03 11:40:07.000000000
+0100
+++ freeciv.PR8992/ai/advmilitary.c 2004-10-07 00:23:00.000000000 +0100
@@ -1118,11 +1118,9 @@
if (best_choice.want > choice->want) {
/* We want attacker more that what we have selected before */
copy_if_better_choice(&best_choice, choice);
- if (go_by_boat && !ferryboat) {
- ai_choose_role_unit(pplayer, pcity, choice, L_FERRYBOAT, choice->want);
- }
- freelog(LOG_DEBUG, "%s has chosen attacker, %s, want=%d",
- pcity->name, unit_types[choice->choice].name, choice->want);
+ CITY_LOG(LOG_DEBUG, pcity, "has chosen attacker, %s, want=%d%s",
+ unit_types[choice->choice].name, choice->want,
+ (best_choice.need_boat ? "(need boat)" : ""));
}
}
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/ai/aicity.c
freeciv.PR8992/ai/aicity.c
--- vendor.freeciv.current/ai/aicity.c 2004-10-03 11:40:07.000000000 +0100
+++ freeciv.PR8992/ai/aicity.c 2004-10-07 00:23:00.000000000 +0100
@@ -46,6 +46,7 @@
#include "advdomestic.h"
#include "advmilitary.h"
#include "aidata.h"
+#include "aiferry.h"
#include "aihand.h"
#include "ailog.h"
#include "aitools.h"
@@ -980,6 +981,8 @@
ai_city_choose_build(pplayer, pcity);
} city_list_iterate_end;
+ aiferry_choose_build_global(pplayer);
+
ai_spend_gold(pplayer);
}
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/ai/aiferry.c
freeciv.PR8992/ai/aiferry.c
--- vendor.freeciv.current/ai/aiferry.c 2004-10-03 11:40:07.000000000 +0100
+++ freeciv.PR8992/ai/aiferry.c 2004-10-07 00:23:00.000000000 +0100
@@ -27,6 +27,7 @@
#include "aidata.h"
#include "aiexplorer.h"
+#include "aihand.h"
#include "ailog.h"
#include "aitools.h"
#include "aiunit.h"
@@ -44,7 +45,7 @@
* The below is used only by passengers in ai.ferryboat field
*/
#define FERRY_WANTED -1 /* Needs a boat */
-#define FERRY_NONE 0 /* Has no boa and doesn't need one */
+#define FERRY_NONE 0 /* Has no boat and doesn't need one */
/* =================== group log levels, debug options ================= */
@@ -58,7 +59,6 @@
/* Extra consistency checks */
#define DEBUG_FERRY_STATS 0
-
/* ========= managing statistics and boat/passanger assignments ======== */
/**************************************************************************
@@ -73,7 +73,7 @@
ai->stats.available_boats = 0;
unit_list_iterate(pplayer->units, punit) {
- if (is_sailing_unit(punit) && is_ground_units_transport(punit)) {
+ if (unit_has_role(punit->type, L_FERRYBOAT)) {
ai->stats.boats++;
if (punit->ai.passenger == FERRY_AVAILABLE) {
ai->stats.available_boats++;
@@ -95,8 +95,8 @@
struct ai_data *ai = ai_data_get(pplayer);
int n = 1;
- freelog(LOG_NORMAL, "Boat stats for %s[%d]",
- pplayer->name, pplayer->player_no);
+ freelog(LOG_NORMAL, "Boat stats for %s[%d] in turn %d",
+ pplayer->name, pplayer->player_no, game.turn);
freelog(LOG_NORMAL, "Registered: %d free out of total %d",
ai->stats.available_boats, ai->stats.boats);
unit_list_iterate(pplayer->units, punit) {
@@ -855,3 +855,189 @@
return;
}
+
+/**************************************************************************
+ A cost function for a sea unit which allows going one step into the land.
+
+ Things to remember: we should prevent going from land to anywhere, unless
+ we are leaving a city, in which case we can move into the ocean but not
+ into the land.
+**************************************************************************/
+static int overlap_move(const struct tile *ptile, enum direction8 dir,
+ const struct tile *ptile1, struct pf_parameter *param)
+{
+ if (is_ocean(map_get_terrain(ptile))) {
+ return SINGLE_MOVE;
+ } else if (is_allied_city_tile(ptile, param->owner)
+ && is_ocean(map_get_terrain(ptile1))) {
+ return SINGLE_MOVE;
+ }
+
+ return PF_IMPOSSIBLE_MC;
+}
+
+/* Least Common Denominator of 2,3,..,8 (a very divisible number) */
+#define DENOM 840
+/****************************************************************************
+ A global ferry build selector. Estimates our want for the boats and finds
+ cities who will build them.
+
+ FIXME: Gross hack, uses pcity->ai.founder_want field for its local
+ calculations.
+****************************************************************************/
+void aiferry_choose_build_global(struct player *pplayer)
+{
+ struct city *pcity;
+ int inf_loop_guard = city_list_size(&pplayer->cities);
+ /* Path-finding stuff */
+ struct pf_map *pfmap;
+ struct pf_parameter parameter;
+
+ /* Initialize */
+ city_list_iterate(pplayer->cities, acity) {
+ acity->ai.founder_want = 0;
+ } city_list_iterate_end;
+ parameter.turn_mode = TM_NONE;
+ parameter.get_MC = overlap_move;
+ parameter.get_TB = NULL;
+ parameter.get_EC = NULL;
+ parameter.get_costs = NULL;
+ parameter.get_zoc = NULL;
+ parameter.is_pos_dangerous = NULL;
+ BV_CLR_ALL(parameter.unit_flags);
+ parameter.owner = pplayer;
+ parameter.omniscience = !ai_handicap(pplayer, H_MAP);
+ /* These don't matter */
+ parameter.moves_left_initially = 0;
+ parameter.move_rate = 3;
+
+ do {
+ int future_psngrs = 0, psngrs = 0;
+ int boats = 0, avail_boats = 0;
+ int boats_to_be_built;
+
+ /* Find unprocessed city */
+ pcity = NULL;
+ city_list_iterate(pplayer->cities, acity) {
+ if (acity->ai.founder_want == 0
+ && is_ocean_near_tile(acity->tile)) {
+ pcity = acity;
+ break;
+ }
+ } city_list_iterate_end;
+
+ if (!pcity) {
+ break;
+ }
+
+ /* Part 1: estimate the demand for the boats */
+
+ parameter.start_tile = pcity->tile;
+ pfmap = pf_create_map(¶meter);
+
+ /* We want to consider the place we are currently in too, hence the
+ * do-while loop */
+ do {
+ struct pf_position pos;
+ struct city *acity;
+
+ pf_next_get_position(pfmap, &pos);
+ acity = map_get_city(pos.tile);
+
+ if (acity && acity->owner == pplayer->player_no) {
+ assert(acity->ai.founder_want == 0);
+ acity->ai.founder_want = 1;
+
+ if (acity->ai.choice.need_boat) {
+ int turns_to_build =
+ city_turns_to_build(acity, acity->ai.choice.choice,
+ is_unit_choice_type(acity->ai.choice.type),
+ TRUE);
+
+ future_psngrs += DENOM / turns_to_build;
+ }
+ }
+
+ unit_list_iterate(pos.tile->units, aunit) {
+ if (aunit->owner != pplayer->player_no) {
+ continue;
+ }
+ if (unit_has_role(aunit->type, L_FERRYBOAT)) {
+ boats++;
+ if (aunit->ai.passenger == FERRY_AVAILABLE) {
+ avail_boats++;
+ }
+ if (aunit->ai.passenger == 0) {
+ freelog(LOG_ERROR, "Passenger field set to 0");
+ avail_boats++;
+ }
+ } else if (aunit->ai.ferryboat == FERRY_WANTED) {
+ psngrs++;
+ }
+ } unit_list_iterate_end;
+ } while (pf_next(pfmap));
+
+ pf_destroy_map(pfmap);
+
+ freelog(LOG_NORMAL, "Sea area accessible from %s has %d boats (%d free)"
+ " and %d units waiting for boats",
+ pcity->name, boats, avail_boats, psngrs);
+ freelog(LOG_NORMAL, "Future passenger score is %d.", future_psngrs);
+
+ /* Part 2: Decide on how many boats we want built */
+
+ /* WAG rules: idle boats count twice, future passangers
+ * count as half */
+ psngrs = psngrs * DENOM + MAX(0, future_psngrs - boats * DENOM);
+ boats = (boats + avail_boats) * DENOM;
+ boats_to_be_built = (psngrs > boats ? 1 : 0);
+
+ freelog(LOG_NORMAL, "Boat-want is %d, so %d boats will be built",
+ psngrs - boats, boats_to_be_built);
+
+ /* Part 3: Decide where to build it */
+
+ while (boats_to_be_built > 0) {
+ Unit_Type_id boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
+ int best = FC_INFINITY;
+ struct city *bestcity = NULL;
+
+ if (boattype == U_LAST) {
+ /* Stimulate tech A LOT!!! */
+ break;
+ }
+
+ city_list_iterate(pplayer->cities, acity) {
+ if (acity->ai.founder_want == 1
+ && acity->ai.choice.need_boat
+ && city_turns_to_build(acity, boattype, TRUE, TRUE) < best) {
+ assert(is_ocean_near_tile(pcity->tile));
+ best = city_turns_to_build(acity, boattype, TRUE, TRUE);
+ bestcity = acity;
+ }
+ } city_list_iterate_end;
+
+ if (!bestcity) {
+ break;
+ }
+
+ /* FIXME: separate a function ai_set_build from
+ * aicity.c:ai_city_choose_build and use it here */
+ CITY_LOG(LOG_NORMAL, bestcity, "will build a boat");
+ bestcity->currently_building = boattype;
+ pcity->is_building_unit = TRUE;
+ boats_to_be_built--;
+ }
+
+ /* Part 4: Cleanup */
+ city_list_iterate(pplayer->cities, acity) {
+ if (acity->ai.founder_want == 1) {
+ acity->ai.founder_want = 2;
+ }
+ } city_list_iterate_end;
+
+ inf_loop_guard--;
+ } while(inf_loop_guard > 0);
+}
+
+#undef DENOM
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/ai/aiferry.h
freeciv.PR8992/ai/aiferry.h
--- vendor.freeciv.current/ai/aiferry.h 2004-10-03 11:40:07.000000000 +0100
+++ freeciv.PR8992/ai/aiferry.h 2004-10-07 00:23:00.000000000 +0100
@@ -48,4 +48,10 @@
*/
void ai_manage_ferryboat(struct player *pplayer, struct unit *punit);
+/*
+ * A function for a centralized (i.e. per-civilization rather than per-city
+ * estimation of need to build more ferries and where to build them
+ */
+void aiferry_choose_build_global(struct player *pplayer);
+
#endif /* FC__AIFERRY_H */
diff -Nur -Xfreeciv.PR8992/diff_ignore vendor.freeciv.current/diff_ignore
freeciv.PR8992/diff_ignore
--- vendor.freeciv.current/diff_ignore 2004-09-05 21:01:58.000000000 +0100
+++ freeciv.PR8992/diff_ignore 2004-10-07 00:23:00.000000000 +0100
@@ -17,6 +17,7 @@
*~
.#*
.deps
+.svn
CVS
Freeciv.h
Makefile
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries,
Benedict Adamson <=
- [freeciv-ai] (PR#8992) Patch: Centralised ferry building, Benedict Adamson, 2004/10/12
- [freeciv-ai] (PR#8992) Patch: Centralised ferry building, Benedict Adamson, 2004/10/23
- [freeciv-ai] (PR#8992) Patch: Building ferries, Jason Short, 2004/10/24
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Benedict Adamson, 2004/10/30
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Per I. Mathisen, 2004/10/30
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Benedict Adamson, 2004/10/30
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Per I. Mathisen, 2004/10/30
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Benoit Hudson, 2004/10/30
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Benedict Adamson, 2004/10/31
- [freeciv-ai] Re: (PR#8992) Patch: Building ferries, Benedict Adamson, 2004/10/31
|
|