[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: |
Fri, 29 Apr 2005 15:12:02 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12840 >
OK, here is the patch with that change made.
--- Jason Short <jdorje@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> <URL:
> http://bugs.freeciv.org/Ticket/Display.html?id=12840
> >
>
> unit_list_find is super-slow, O(n). You should be
> using
> player_find_unit_by_id instead. This does a hash
> lookup and is about O(1).
>
> -jason
>
>
__________________________________________________
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 22:24:35.495276424 -0400
@@ -835,10 +835,21 @@
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 travel to
+ and complete work at best_tile
+
+ tile_inbound is, for each tile, the unit id of the worker en route
+ tile_inbound_time is the eta of this worker (if any). This information
+ is used to possibly displace this previously assigned worker.
+ if these two arrays are NULL, workers are never displaced.
****************************************************************************/
static int evaluate_improvements(struct unit *punit,
enum unit_activity *best_act,
- struct tile **best_tile)
+ struct tile **best_tile,
+ int *completion_time,
+ int *tile_inbound,
+ int *tile_inbound_time)
{
struct city *mycity = tile_get_city(punit->tile);
struct player *pplayer = unit_owner(punit);
@@ -858,6 +869,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 +883,85 @@
continue;
}
in_use = (get_worker_city(pcity, i, j) == C_TILE_WORKER);
+ if(tile_inbound) {
+ inbound = player_find_unit_by_id(pplayer, 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... */
-
- activity_type_iterate(act) {
+ /* 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);
- 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;
@@ -955,13 +989,18 @@
Find some work for our settlers and/or workers.
**************************************************************************/
#define LOG_SETTLER LOG_DEBUG
-static void auto_settler_findwork(struct player *pplayer, struct unit *punit)
+static void auto_settler_findwork(struct player *pplayer,
+ struct unit *punit,
+ int *tile_inbound,
+ int *tile_inbound_time)
{
struct cityresult result;
int best_impr = 0; /* best terrain improvement we can do */
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 +1053,9 @@
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, tile_inbound,
+ tile_inbound_time);
TIMING_LOG(AIT_WORKERS, TIMER_STOP);
}
@@ -1064,7 +1105,18 @@
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,
+ tile_inbound, tile_inbound_time);
+ }
} else {
UNIT_LOG(LOG_DEBUG, punit, "giving up trying to improve terrain");
return; /* We cannot do anything */
@@ -1085,7 +1137,8 @@
if (punit->ai.ai_role == AIUNIT_BUILD_CITY
&& punit->moves_left > 0) {
- auto_settler_findwork(pplayer, punit);
+ auto_settler_findwork(pplayer, punit,
+ tile_inbound, tile_inbound_time);
}
}
#undef LOG_SETTLER
@@ -1169,6 +1222,9 @@
{
static struct timer *t = NULL; /* alloc once, never free */
+ int tile_inbound[MAP_INDEX_SIZE];
+ int tile_inbound_time[MAP_INDEX_SIZE];
+
t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
if (pplayer->ai.control) {
@@ -1176,6 +1232,11 @@
citymap_turn_init(pplayer);
}
+ whole_map_iterate(ptile) {
+ tile_inbound[ptile->index] = -1;
+ tile_inbound_time[ptile->index] = FC_INFINITY;
+ } whole_map_iterate_end;
+
/* Initialize the infrastructure cache, which is used shortly. */
initialize_infrastructure_cache(pplayer);
@@ -1214,7 +1275,8 @@
handle_unit_activity_request(punit, ACTIVITY_IDLE);
}
if (punit->activity == ACTIVITY_IDLE) {
- auto_settler_findwork(pplayer, punit);
+ auto_settler_findwork(pplayer, punit,
+ tile_inbound, tile_inbound_time);
}
}
}
@@ -1416,6 +1478,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 +1488,9 @@
/* 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,
+ NULL, NULL);
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, 2005/04/27
- [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 <=
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/30
|
|