[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: |
Tue, 26 Apr 2005 15:58:17 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12840 >
<URL:
http://bugs.freeciv.org/Ticket/Display.html?id=12840>
Here is a patch that fixes (to a large extent) the
proplems of delay in autosettler pollution cleanup in
the late game.
In the current algorithm, a worker that cannot begin
cleanup in the present turn will reserve a polluted
tile, preventing other, more ready, workers from
responding.
My patch records the worker moving to a given tile (if
any) by its ID, along with its ETA. Another worker
may consider this tile, and displace the worker
currently en route, if either:
1) it can arrive at the tile sooner
2) it will arrive at the same time, but will have to
traverse fewer squares to do so.
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
diff -Nur -Xfreeciv/diff_ignore freeciv/common/map.c
freeciv_nopollute/common/map.c
--- freeciv/common/map.c 2005-04-26 11:12:32.000000000 -0400
+++ freeciv_nopollute/common/map.c 2005-04-26 13:14:04.740438744 -0400
@@ -344,6 +344,7 @@
ptile->assigned = 0; /* bitvector */
ptile->owner = NULL; /* Tile not claimed by any nation. */
ptile->spec_sprite = NULL;
+ ptile->inbound = -1;
}
/****************************************************************************
diff -Nur -Xfreeciv/diff_ignore freeciv/common/tile.h
freeciv_nopollute/common/tile.h
--- freeciv/common/tile.h 2005-04-26 11:12:32.000000000 -0400
+++ freeciv_nopollute/common/tile.h 2005-04-26 13:16:35.273554232 -0400
@@ -38,6 +38,10 @@
Continent_id continent;
struct player *owner; /* Player owning this tile, or NULL. */
char *spec_sprite;
+
+ int inbound;
+ int inbound_eta;
+
};
/* get 'struct tile_list' and related functions: */
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-26 14:30:52.482955408 -0400
@@ -16,6 +16,7 @@
#endif
#include <assert.h>
+#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -835,10 +836,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.
+
+ travel_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 *travel_time)
{
struct city *mycity = tile_get_city(punit->tile);
struct player *pplayer = unit_owner(punit);
@@ -858,6 +862,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 +876,83 @@
continue;
}
in_use = (get_worker_city(pcity, i, j) == C_TILE_WORKER);
+ inbound = unit_list_find(pplayer->units, ptile->inbound);
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=INT_MAX, inbound_distance=INT_MAX;
int time;
+ if(inbound) {
+ eta = ptile->inbound_eta;
+ 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) {
+ *travel_time = mv_turns;
}
- } 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 +987,8 @@
enum unit_activity best_act;
struct tile *best_tile = NULL;
struct ai_data *ai = ai_data_get(pplayer);
+ int travel_time = 0; /* time it will take worker to reach
+ its destination tile */
CHECK_UNIT(punit);
@@ -1014,7 +1041,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,
&travel_time);
TIMING_LOG(AIT_WORKERS, TIMER_STOP);
}
@@ -1064,6 +1091,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, best_tile->inbound);
+ best_tile->inbound = punit->id;
+ best_tile->inbound_eta = travel_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");
@@ -1259,6 +1297,8 @@
static void assign_settlers(void)
{
whole_map_iterate(ptile) {
+ ptile->inbound = -1;
+ ptile->inbound_eta = INT_MAX;
ptile->assigned = 0;
} whole_map_iterate_end;
@@ -1416,6 +1456,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 travel_time;
if (unit_type == U_LAST) {
freelog(LOG_DEBUG, "No F_SETTLERS role unit available");
@@ -1425,7 +1466,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, &travel_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 <=
- [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, 2005/04/29
- [Freeciv-Dev] Re: (PR#12840) delay in pollution patrol (possible causes), Brian Dunstan, 2005/04/30
|
|