[Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes) |
From: |
"Brian Dunstan" <bdunstan149@xxxxxxxxx> |
Date: |
Wed, 27 Apr 2005 14:54:54 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12840 >
--- Jason Short <jdorje@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> <URL:
> http://bugs.freeciv.org/Ticket/Display.html?id=12840
> >
>
> I like the design. A few things about the
> implementation need fixing:
>
> - Unit_type_id is not what you think it is. It
> gives the type of a
> unit, not its ID. The ID is just an int (I think?).
>
> - Don't add new fields to the tile struct. Instead
> make a new array of
> tile data in settlers.c. This array can be
> reinitialized when the map
> is resized or on every turn or whatever. See the
> warmap struct in
> gotohand.c or the map_deco struct in
> mapview_common.c or the
> pf_map->lattice struct in path_finding.c for other
> examples.
>
> - Use FC_INFINITY, not INT_MAX.
I'm sending a new patch that fixes this.
> - Instead of using the "travel time" shouldn't you
> use the
> turns-to-completion? E.g., if we have a
> high-priority task it's better
> to assign an engineer to it. (Not entirely sure
> about this.)
on balance I think you're right. The only time this
will affect behavior is when a worker and an engineer
both want to work the same tile; the engineer should
be given priority then imo. So this has been changed
in the new patch.
-Brian
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
diff -Nur -Xfreeciv/diff_ignore freeciv/server/settlers.c
freeciv_nopollute/server/settlers.c
--- freeciv/server/settlers.c 2005-04-26 11:12:40.000000000 -0400
+++ freeciv_nopollute/server/settlers.c 2005-04-27 14:55:21.596891816 -0400
@@ -55,6 +55,9 @@
BV_DEFINE(enemy_mask, MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS);
static enemy_mask enemies[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
+static int *tile_inbound;
+static int *tile_inbound_time;
+
static bool is_already_assigned(struct unit *myunit, struct player *pplayer,
struct tile *ptile);
@@ -835,10 +838,13 @@
this return value is >0, then (gx,gy) indicates the tile chosen and bestact
indicates the activity it wants to do. If 0 is returned then there are no
worthwhile activities available.
+
+ completion_time is the time that would be taken by punit to reach best_tile
****************************************************************************/
static int evaluate_improvements(struct unit *punit,
enum unit_activity *best_act,
- struct tile **best_tile)
+ struct tile **best_tile,
+ int *completion_time)
{
struct city *mycity = tile_get_city(punit->tile);
struct player *pplayer = unit_owner(punit);
@@ -858,6 +864,9 @@
int best_newv = 0;
enemy_mask my_enemies = enemies[pplayer->player_no]; /* optimalization */
+ struct unit *inbound = NULL; /* closest worker, if any, headed towards
+ target tile */
+
generate_warmap(mycity, punit);
city_list_iterate(pplayer->cities, pcity) {
@@ -869,65 +878,83 @@
continue;
}
in_use = (get_worker_city(pcity, i, j) == C_TILE_WORKER);
+ inbound = unit_list_find(pplayer->units, tile_inbound[ptile->index]);
if (tile_get_continent(ptile) == ucont
&& WARMAP_COST(ptile) <= THRESHOLD * mv_rate
&& !BV_CHECK_MASK(TERRITORY(ptile), my_enemies)
- /* pretty good, hope it's enough! -- Syela */
- && !is_already_assigned(punit, pplayer, ptile)) {
- /* calling is_already_assigned once instead of four times
- for obvious reasons; structure is much the same as it once
- was but subroutines are not -- Syela */
+ && (!(is_already_assigned(punit, pplayer, ptile)
+ || (inbound
+ && inbound->owner == pplayer->player_no)))) {
+
+ int eta=FC_INFINITY, inbound_distance=FC_INFINITY;
int time;
+ if(inbound) {
+ eta = tile_inbound_time[ptile->index];
+ inbound_distance = real_map_distance(ptile, inbound->tile);
+ }
mv_turns = (WARMAP_COST(ptile)) / mv_rate;
oldv = city_tile_value(pcity, i, j, 0, 0);
- /* now, consider various activities... */
+ /* only consider this tile if we are closer in time and space to it than
+ our other worker (if any) travelling to the site */
+ if(mv_turns < eta ||
+ (mv_turns == eta &&
+ real_map_distance(ptile, punit->tile) < inbound_distance)) {
+
+ /* now, consider various activities... */
+
+ activity_type_iterate(act) {
+
+ if(pcity->ai.act_value[act][i][j] >= 0 &&
+ can_unit_do_activity_targeted_at(punit, act,
+ S_NO_SPECIAL, ptile)) {
+ int extra = 0;
+ int base_value = pcity->ai.act_value[act][i][j];
+ int old_best_value = best_newv;
+ time = mv_turns + get_turns_for_activity_at(punit, act, ptile);
+ if(act == ACTIVITY_ROAD) {
+ extra = road_bonus(ptile, S_ROAD) * 5;
+ if (can_rr) {
+ /* if we can make railroads eventually, consider making
+ * road here, and set extras and time to to consider
+ * railroads in main consider_settler_action call */
+ consider_settler_action(pplayer, ACTIVITY_ROAD,
+ extra,
+
pcity->ai.act_value[ACTIVITY_ROAD][i][j],
+ oldv, in_use, time,
+ &best_newv, &best_oldv,
+ best_act, best_tile,
+ ptile);
+
+ base_value = pcity->ai.act_value[ACTIVITY_RAILROAD][i][j];
+
+ /* Count road time plus rail time. */
+ time += get_turns_for_activity_at(punit, ACTIVITY_RAILROAD,
+ ptile);
+ }
+ } else if (act == ACTIVITY_RAILROAD) {
+ extra = road_bonus(ptile, S_RAILROAD) * 3;
+ } else if (act == ACTIVITY_FALLOUT) {
+ extra = pplayer->ai.frost;
+ } else if (act == ACTIVITY_POLLUTION) {
+ extra = pplayer->ai.warmth;
+ }
+
+ consider_settler_action(pplayer, act,
+ extra,
+ base_value, oldv,
+ in_use, time,
+ &best_newv, &best_oldv,
+ best_act, best_tile,
+ ptile);
- activity_type_iterate(act) {
-
- if(pcity->ai.act_value[act][i][j] >= 0 &&
- can_unit_do_activity_targeted_at(punit, act,
- S_NO_SPECIAL, ptile)) {
- int extra = 0;
- int base_value = pcity->ai.act_value[act][i][j];
- time = mv_turns + get_turns_for_activity_at(punit, act, ptile);
- if(act == ACTIVITY_ROAD) {
- extra = road_bonus(ptile, S_ROAD) * 5;
- if (can_rr) {
- /* if we can make railroads eventually, consider making
- * road here, and set extras and time to to consider
- * railroads in main consider_settler_action call */
- consider_settler_action(pplayer, ACTIVITY_ROAD,
- extra,
-
pcity->ai.act_value[ACTIVITY_ROAD][i][j],
- oldv, in_use, time,
- &best_newv, &best_oldv,
- best_act, best_tile,
- ptile);
-
- base_value = pcity->ai.act_value[ACTIVITY_RAILROAD][i][j];
-
- /* Count road time plus rail time. */
- time += get_turns_for_activity_at(punit, ACTIVITY_RAILROAD,
- ptile);
+ if(best_newv > old_best_value) {
+ *completion_time = time;
}
- } else if (act == ACTIVITY_RAILROAD) {
- extra = road_bonus(ptile, S_RAILROAD) * 3;
- } else if (act == ACTIVITY_FALLOUT) {
- extra = pplayer->ai.frost;
- } else if (act == ACTIVITY_POLLUTION) {
- extra = pplayer->ai.warmth;
- }
-
- consider_settler_action(pplayer, act,
- extra,
- base_value, oldv,
- in_use, time,
- &best_newv, &best_oldv,
- best_act, best_tile,
- ptile);
- } /* endif: can the worker perform this action */
- } activity_type_iterate_end;
+
+ } /* endif: can the worker perform this action */
+ } activity_type_iterate_end;
+ } /* endif: are we closer than the currenly assigned worker, if any? */
} /* endif: are we travelling to a legal destination? */
} city_map_checked_iterate_end;
} city_list_iterate_end;
@@ -962,6 +989,8 @@
enum unit_activity best_act;
struct tile *best_tile = NULL;
struct ai_data *ai = ai_data_get(pplayer);
+ int completion_time = 0; /* time it will take worker to complete
+ its given task */
CHECK_UNIT(punit);
@@ -1014,7 +1043,7 @@
if (unit_flag(punit, F_SETTLERS)) {
TIMING_LOG(AIT_WORKERS, TIMER_START);
- best_impr = evaluate_improvements(punit, &best_act, &best_tile);
+ best_impr = evaluate_improvements(punit, &best_act, &best_tile,
&completion_time);
TIMING_LOG(AIT_WORKERS, TIMER_STOP);
}
@@ -1064,6 +1093,17 @@
if (punit->ai.ai_role == AIUNIT_AUTO_SETTLER) {
/* Mark the square as taken. */
if (best_tile) {
+ struct unit *displaced =
+ unit_list_find(pplayer->units, tile_inbound[best_tile->index]);
+ tile_inbound[best_tile->index] = punit->id;
+ tile_inbound_time[best_tile->index] = completion_time;
+
+ best_tile->assigned = best_tile->assigned | 1 << pplayer->player_no;
+
+ if(displaced) {
+ displaced->goto_tile = displaced->tile;
+ auto_settler_findwork(pplayer, displaced);
+ }
best_tile->assigned = best_tile->assigned | 1 << pplayer->player_no;
} else {
UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
@@ -1258,7 +1298,10 @@
**************************************************************************/
static void assign_settlers(void)
{
+
whole_map_iterate(ptile) {
+ tile_inbound[ptile->index] = -1;
+ tile_inbound_time[ptile->index] = FC_INFINITY;
ptile->assigned = 0;
} whole_map_iterate_end;
@@ -1354,6 +1397,9 @@
**************************************************************************/
void auto_settlers_init(void)
{
+ tile_inbound = fc_realloc(tile_inbound, MAP_INDEX_SIZE*(sizeof(int)));
+ tile_inbound_time = fc_realloc(tile_inbound_time,
MAP_INDEX_SIZE*(sizeof(int)));
+
assign_settlers();
assign_territory();
recount_enemy_masks();
@@ -1416,6 +1462,7 @@
struct tile *ptile = pcity->tile;
struct ai_data *ai = ai_data_get(pplayer);
Unit_Type_id unit_type = best_role_unit(pcity, F_SETTLERS);
+ int completion_time;
if (unit_type == U_LAST) {
freelog(LOG_DEBUG, "No F_SETTLERS role unit available");
@@ -1425,7 +1472,8 @@
/* Create a localized "virtual" unit to do operations with. */
virtualunit = create_unit_virtual(pplayer, pcity, unit_type, 0);
virtualunit->tile = pcity->tile;
- want = evaluate_improvements(virtualunit, &best_act, &best_tile);
+ want = evaluate_improvements(virtualunit, &best_act,
+ &best_tile, &completion_time);
free(virtualunit);
/* Massage our desire based on available statistics to prevent
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Jason Short, 2005/04/19
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/19
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/26
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/26
- [Freeciv-Dev] (PR#12840) delay in pollution patrol (possible causes), Jason Short, 2005/04/27
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes),
Brian Dunstan <=
- [Freeciv-Dev] (PR#12840) delay in pollution patrol (possible causes), Jason Short, 2005/04/27
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/27
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/28
- [Freeciv-Dev] (PR#12840) delay in pollution patrol (possible causes), Jason Short, 2005/04/29
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/29
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/30
|
|