[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 16:23:10 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12840 >
Hm, revised version, the same except:
+ Unit_Type_id inbound;
instead of:
+ int inbound;
--- Brian Dunstan <bdunstan149@xxxxxxxxx> wrote:
>
> <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,
>
=== message truncated ===
__________________________________________________
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.000000000 -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 16:24:40.695909256 -0400
@@ -38,6 +38,10 @@
Continent_id continent;
struct player *owner; /* Player owning this tile, or NULL. */
char *spec_sprite;
+
+ Unit_Type_id 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.000000000 -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, 2005/04/26
- [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] (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
|
|