[Freeciv-Dev] [PATCH] ai_manage_explorer splitup
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
With this patch I split up ai_manage_explorer into 4 parts. This
patch is only for code clarity. I tried not to alter code. At
least according to profiler functions are called alike. And
savegames are same.
Before:
------------------------------------------------------------------------
% cumulative self self total
time seconds seconds calls ms/call ms/call name
14.68 1.12 1.12 926 1.21 2.82 ai_manage_explorer
6.42 1.61 0.49 9044747 0.00 0.00 map_get_tile
6.16 2.08 0.47 2168963 0.00 0.00 map_get_special
5.37 2.49 0.41 8535883 0.00 0.00 tech_exists
4.19 2.81 0.32 2048453 0.00 0.00 map_get_terrain
4.19 3.13 0.32 1435 0.22 0.44 really_generate_warmap
3.01 3.36 0.23 22 10.45 17.90 check_fow
2.49 3.55 0.19 1000854 0.00 0.00 food_weighting
2.23 3.72 0.17 16898 0.01 0.02 find_prerequisites
1.97 3.87 0.15 1375 0.11 0.31 find_the_shortest_path
1.83 4.01 0.14 6357317 0.00 0.00 get_player
1.83 4.15 0.14 2272707 0.00 0.00 map_get_city
1.70 4.28 0.13 282670 0.00 0.00 myrand
1.57 4.40 0.12 2760258 0.00 0.00 find_genlist_position
1.57 4.52 0.12 1943989 0.00 0.00 map_get_player_tile
1.44 4.63 0.11 43462 0.00 0.01 unfog_area
1.44 4.74 0.11 26722 0.00 0.02 city_desirability
1.31 4.84 0.10 3070509 0.00 0.00 get_invention
1.31 4.94 0.10 11972 0.01 0.03 update_research
1.18 5.03 0.09 65627 0.00 0.00 unit_win_chance
1.18 5.12 0.09 10 9.00 13.08 player_save
1.05 5.20 0.08 448054 0.00 0.00 add_to_mapqueue
1.05 5.28 0.08 133 0.60 3.23 ai_select_tech
After:
------------------------------------------------------------------------
% cumulative self self total
time seconds seconds calls ms/call ms/call name
10.25 0.78 0.78 626 1.25 2.35 ai_manage_explorer_3
8.41 1.42 0.64 9044747 0.00 0.00 map_get_tile
5.91 1.87 0.45 2168963 0.00 0.00 map_get_special
4.60 2.22 0.35 8535883 0.00 0.00 tech_exists
3.81 2.51 0.29 2048453 0.00 0.00 map_get_terrain
3.68 2.79 0.28 2272707 0.00 0.00 map_get_city
3.29 3.04 0.25 22 11.36 21.64 check_fow
3.02 3.27 0.23 1435 0.16 0.42 really_generate_warmap
2.50 3.46 0.19 964 0.20 0.74 ai_manage_explorer_1
2.37 3.64 0.18 6357317 0.00 0.00 get_player
2.23 3.81 0.17 1943989 0.00 0.00 map_get_player_tile
1.97 3.96 0.15 282670 0.00 0.00 myrand
1.97 4.11 0.15 26722 0.01 0.02 city_desirability
1.84 4.25 0.14 11972 0.01 0.03 update_research
1.71 4.38 0.13 258 0.50 3.89 evaluate_city_building
1.58 4.50 0.12 1000854 0.00 0.00 food_weighting
1.58 4.62 0.12 43462 0.00 0.02 unfog_area
1.45 4.73 0.11 2759581 0.00 0.00 genlist_iterator_init
1.45 4.84 0.11 797457 0.00 0.00 map_get_continent
1.45 4.95 0.11 16898 0.01 0.02 find_prerequisites
1.45 5.06 0.11 1375 0.08 0.31 find_the_shortest_path
1.31 5.16 0.10 452222 0.00 0.00 get_from_mapqueue
1.05 5.24 0.08 3070509 0.00 0.00 get_invention
1.05 5.32 0.08 1902503 0.00 0.00 map_get_known
1.05 5.40 0.08 94786 0.00 0.00 shared_vision_change_seen
1.05 5.48 0.08 10 8.00 13.46 player_save
...
0.00 7.61 0.00 926 0.00 2.70 ai_manage_explorer
0.00 7.61 0.00 742 0.00 0.09 ai_manage_explorer_2
0.00 7.61 0.00 256 0.00 0.01 ai_manage_explorer_4
...
-----------------------------------------------
index % time self children called name
0.78 0.69 626/626 ai_manage_explorer [6]
[10] 19.3 0.78 0.69 626 ai_manage_explorer_3 [10]
0.00 0.24 370/1375 do_unit_goto [13]
0.18 0.00 2504000/9044747 map_get_tile [18]
0.00 0.16 626/2487 generate_warmap [20]
0.03 0.05 746370/1902503 map_get_known [48]
0.00 0.01 82981/83221 tile_is_accessible [180]
0.00 0.01 89479/284961 is_non_allied_unit_tile [141]
0.00 0.00 84427/259566 is_non_allied_city_tile [201]
0.00 0.00 1925/282670 myrand [57]
0.00 0.00 429/729 handle_unit_activity_request
[387]
0.00 0.00 626/2272707 map_get_city [44]
0.00 0.00 626/1903 unit_move_rate [389]
0.00 0.00 23298/609979 is_sailing_unit [555]
0.00 0.00 3732/344462 is_barbarian [556]
-----------------------------------------------
Produced by:
------------------------------------------------------------------------
set xsize 80
set ysize 50
set maxplayers 30
set aifill 10
set explorer 10
set timeout 1
set randseed 1
set seed 3
set endyear -3500
create maage
hard
start
------------------------------------------------------------------------
--
//Markus
--- freeciv-cvs/ai/aiunit.c Wed Aug 22 10:25:35 2001
+++ freeciv/ai/aiunit.c Wed Aug 22 11:42:45 2001
@@ -53,6 +53,14 @@
static void ai_manage_barbarian_leader(struct player *pplayer,
struct unit *leader);
+static int ai_manage_explorer_1(struct unit *punit, struct player *pplayer);
+static int ai_manage_explorer_2(struct unit *punit, struct player *pplayer,
+ int con, int range);
+static int ai_manage_explorer_3(struct unit *punit, struct player *pplayer,
+ int con, int range);
+static void ai_manage_explorer_4(struct unit *punit, struct player *pplayer,
+ int con);
+
static void ai_military_findjob(struct player *pplayer,struct unit *punit);
static void ai_military_gohome(struct player *pplayer,struct unit *punit);
static void ai_military_attack(struct player *pplayer,struct unit *punit);
@@ -178,78 +186,73 @@
return 0;
}
-
-/**************************************************************************
-Explores unknown territory, finds huts.
-Returns whether there is any more territory to be explored.
-**************************************************************************/
-int ai_manage_explorer(struct unit *punit)
-{
- struct player *pplayer = unit_owner(punit);
- int x, y; /* is the position of the unit; updated inside the function */
- int con; /* continent the unit is on */
- struct city *pcity;
- int id = punit->id; /* we can now die because easy AI may accidently
- stumble on huts it fuzzily ignored */
- int best_x = -1, best_y = -1;
- int range = get_unit_type(punit->type)->vision_range;
- int move_rate = unit_move_rate(punit);
- if (punit->activity != ACTIVITY_IDLE)
- handle_unit_activity_request(punit, ACTIVITY_IDLE);
-
- x = punit->x; y = punit->y;
- if (is_ground_unit(punit)) con = map_get_continent(x, y);
- else con = 0; /* Thanks, Tony */
-
- /* CPU-expensive but worth it -- Syela */
- generate_warmap(map_get_city(x, y), punit);
+/**************************************************************************
+ Exploring is split into parts.
- /* BEGIN PART ONE: Look for huts. Non-Barbarian Ground units ONLY. */
- if (!is_barbarian(pplayer)
- && is_ground_unit(punit)) { /* boats don't hunt huts */
- int maxcost = pplayer->ai.control ? 2 * THRESHOLD : 3;
- int bestcost = maxcost * SINGLE_MOVE + 1;
-
- /* Iterating outward so that with two tiles with the same movecost
- the nearest is used */
- iterate_outward(x, y, maxcost, x1, y1) {
- if (map_get_special(x1, y1) & S_HUT
- && warmap.cost[x1][y1] < bestcost
- && (!ai_handicap(pplayer, H_HUTS) || map_get_known(x1, y1, pplayer))
- && tile_is_accessible(punit, x1, y1)
- && ai_fuzzy(pplayer, 1)) {
- best_x = x1;
- best_y = y1;
- bestcost = warmap.cost[best_x][best_y];
- }
- } iterate_outward_end;
- if (bestcost <= maxcost * SINGLE_MOVE) {
- punit->goto_dest_x = best_x;
- punit->goto_dest_y = best_y;
- set_unit_activity(punit, ACTIVITY_GOTO);
- do_unit_goto(punit, GOTO_MOVE_ANY, 0);
- if (!player_find_unit_by_id(pplayer, id))
- return 0; /* died */
+ First we try to explore near and valuable targets. Later we
+ focus targets at greater distance.
+**************************************************************************/
- if (punit->moves_left) {
- if (punit->x == best_x && punit->y == best_y) {
- return ai_manage_explorer(punit);
- } else {
- /* Something went wrong; fall through. This should almost never
happen. */
- if (punit->x != x || punit->y != y)
- generate_warmap(map_get_city(punit->x, punit->y), punit);
- x = punit->x; y = punit->y;
- /* Fallthough to next fase */
- }
+/* BEGIN PART ONE: Look for huts. */
+static int ai_manage_explorer_1(struct unit *punit, struct player *pplayer)
+{
+ int maxcost = pplayer->ai.control ? 2 * THRESHOLD : 3;
+ int bestcost = maxcost * SINGLE_MOVE + 1;
+ int best_x = -1, best_y = -1, x = punit->x, y = punit->y;
+
+ /* Iterating outward so that with two tiles with the same movecost
+ the nearest is used */
+ iterate_outward(x, y, maxcost, x1, y1) {
+ if (map_get_special(x1, y1) & S_HUT
+ && warmap.cost[x1][y1] < bestcost
+ && (!ai_handicap(pplayer, H_HUTS) || map_get_known(x1, y1, pplayer))
+ && tile_is_accessible(punit, x1, y1)
+ && ai_fuzzy(pplayer, 1)) {
+ best_x = x1;
+ best_y = y1;
+ bestcost = warmap.cost[best_x][best_y];
+ }
+ } iterate_outward_end;
+ if (bestcost <= maxcost * SINGLE_MOVE) {
+ int id = punit->id; /* we can now die because easy AI may accidently
+ stumble on huts it fuzzily ignored */
+ punit->goto_dest_x = best_x;
+ punit->goto_dest_y = best_y;
+
+ set_unit_activity(punit, ACTIVITY_GOTO);
+ do_unit_goto(punit, GOTO_MOVE_ANY, 0);
+
+ if (!player_find_unit_by_id(pplayer, id))
+ return 0; /* died */
+
+ if (punit->moves_left) {
+ /* If we have moves left */
+ if (punit->x == best_x && punit->y == best_y) {
+ /* and reached destination, start again, we call this
+ recursive */
+ return -2;
} else {
- return 1;
+ /* Something went wrong; fall through. This should
+ almost never happen. */
+ if (punit->x != x || punit->y != y)
+ generate_warmap(map_get_city(punit->x, punit->y), punit);
}
+ } else {
+ return 1;
}
}
+ return -1;
+}
+
+/* BEGIN PART TWO: Move into unexplored territory */
+/* move the unit as long as moving will unveil unknown territory */
+static int ai_manage_explorer_2(struct unit *punit, struct player *pplayer,
+ int con, int range)
+{
+ int best_x = -1, best_y = -1, x = punit->x, y = punit->y;
+ struct city *pcity;
- /* BEGIN PART TWO: Move into unexplored territory */
- /* move the unit as long as moving will unveil unknown territory */
while (punit->moves_left) {
int most_unknown = 0;
int unknown;
@@ -269,7 +272,7 @@
&& (landnear || !unit_flag(punit->type, F_TRIREME))
&& map_get_continent(x1, y1) == con
&& can_unit_move_to_tile(punit, x1, y1, 0)
- && !((pcity = map_get_city(x1,y1))
+ && !((pcity = map_get_city(x1, y1))
&& (unit_flag(punit->type, F_DIPLOMAT)
|| unit_flag(punit->type, F_CARAVAN)))
&& !(is_barbarian(pplayer) && map_get_special(x1, y1) & S_HUT)) {
@@ -280,6 +283,8 @@
} square_iterate_end;
if (most_unknown > 0) { /* a tile have unexplored territory adjacent */
+ int id = punit->id; /* we can now die because easy AI may accidently
+ stumble on huts it fuzzily ignored */
int res = handle_unit_move_request(punit, best_x, best_y, FALSE, FALSE);
if (!res) /* This shouldn't happen */
break;
@@ -293,74 +298,137 @@
if (!punit->moves_left) return 1;
- /* BEGIN PART THREE: Go towards unexplored territory */
- /* no adjacent squares help us to explore - really slow part follows */
+ return -1;
+}
+
+/* BEGIN PART THREE: Go towards unexplored territory */
+/* no adjacent squares help us to explore - really slow part follows */
+static int ai_manage_explorer_3(struct unit *punit, struct player *pplayer,
+ int con, int range)
+{
+ int best_x = -1, best_y = -1, x = punit->x, y = punit->y;
+ int unknown, most_unknown = 0;
+ int move_rate = unit_move_rate(punit);
+ int threshold = THRESHOLD * move_rate;
+
generate_warmap(map_get_city(x, y), punit);
- {
- int unknown, most_unknown = 0;
- int threshold = THRESHOLD * move_rate;
- whole_map_iterate(x1, y1) {
- struct tile *ptile = map_get_tile(x1, y1);
- unknown = 0;
- if (ptile->continent == con
- && !is_non_allied_unit_tile(ptile, punit->owner)
- && !is_non_allied_city_tile(ptile, punit->owner)
- && tile_is_accessible(punit, x1, y1)) {
- square_iterate(x1, y1, range, x2, y2) {
- if (!map_get_known(x2, y2, pplayer))
- unknown++;
- } square_iterate_end;
- if (unknown) {
- if (is_sailing_unit(punit))
- unknown += 9 * (threshold - warmap.seacost[x1][y1]);
- else
- unknown += 9 * (threshold - warmap.cost[x1][y1]);
- if ((unknown > most_unknown || (unknown == most_unknown && myrand(2)))
- && !(is_barbarian(pplayer) && ptile->special & S_HUT)) {
- best_x = x1;
- best_y = y1;
- most_unknown = unknown;
- }
+ whole_map_iterate(x1, y1) {
+ struct tile *ptile = map_get_tile(x1, y1);
+ unknown = 0;
+ if (ptile->continent == con
+ && !is_non_allied_unit_tile(ptile, punit->owner)
+ && !is_non_allied_city_tile(ptile, punit->owner)
+ && tile_is_accessible(punit, x1, y1)) {
+ square_iterate(x1, y1, range, x2, y2) {
+ if (!map_get_known(x2, y2, pplayer))
+ unknown++;
+ } square_iterate_end;
+ if (unknown) {
+ if (is_sailing_unit(punit))
+ unknown += 9 * (threshold - warmap.seacost[x1][y1]);
+ else
+ unknown += 9 * (threshold - warmap.cost[x1][y1]);
+ if ((unknown > most_unknown || (unknown == most_unknown && myrand(2)))
+ && !(is_barbarian(pplayer) && ptile->special & S_HUT)) {
+ best_x = x1;
+ best_y = y1;
+ most_unknown = unknown;
}
}
- } whole_map_iterate_end;
+ }
+ } whole_map_iterate_end;
- if (most_unknown > 0) {
- punit->goto_dest_x = best_x;
- punit->goto_dest_y = best_y;
- handle_unit_activity_request(punit, ACTIVITY_GOTO);
- do_unit_goto(punit, GOTO_MOVE_ANY, 0);
- if (punit->moves_left) {
- if (punit->x != best_x || punit->y != best_y) {
- handle_unit_activity_request(punit, ACTIVITY_IDLE);
- return 1; /* Something wrong; what to do but return? */
- } else
- return ai_manage_explorer(punit);
- } else {
- return 1;
- }
- } /* no candidates; fall-through */
- }
+ if (most_unknown > 0) {
+ punit->goto_dest_x = best_x;
+ punit->goto_dest_y = best_y;
+ handle_unit_activity_request(punit, ACTIVITY_GOTO);
+ do_unit_goto(punit, GOTO_MOVE_ANY, 0);
+ if (punit->moves_left) {
+ if (punit->x != best_x || punit->y != best_y) {
+ handle_unit_activity_request(punit, ACTIVITY_IDLE);
+ return 1; /* Something wrong; what to do but return? */
+ } else
+ return -2;
+ } else {
+ return 1;
+ }
+ } /* no candidates; fall-through */
+
+ return -1;
+}
+
+/* BEGIN PART FOUR: maybe go to another continent */
+static void ai_manage_explorer_4(struct unit *punit, struct player *pplayer,
+ int con)
+{
+ int x = punit->x, y = punit->y;
+ struct city *pcity;
- /* BEGIN PART FOUR: maybe go to another continent */
freelog(LOG_DEBUG, "%s's %s at (%d,%d) failed to explore.",
pplayer->name, unit_types[punit->type].name, punit->x, punit->y);
handle_unit_activity_request(punit, ACTIVITY_IDLE);
- if (pplayer->ai.control && is_military_unit(punit)) {
- pcity = find_city_by_id(punit->homecity);
- if (pcity && map_get_continent(pcity->x, pcity->y) == con)
- ai_military_gohome(pplayer, punit);
- else if (pcity) {
- if (!find_boat(pplayer, &x, &y, 0)) /* Gilligan's Island */
- punit->ai.ferryboat = -1;
- else {
- punit->goto_dest_x = x;
- punit->goto_dest_y = y;
- do_unit_goto(punit, GOTO_MOVE_ANY, 0);
- }
+ if (!pplayer->ai.control || !is_military_unit(punit))
+ return;
+
+ pcity = find_city_by_id(punit->homecity);
+ if (!pcity)
+ return;
+
+ if (map_get_continent(pcity->x, pcity->y) == con)
+ ai_military_gohome(pplayer, punit);
+ else {
+ if (!find_boat(pplayer, &x, &y, 0)) /* Gilligan's Island */
+ punit->ai.ferryboat = -1;
+ else {
+ punit->goto_dest_x = x;
+ punit->goto_dest_y = y;
+ do_unit_goto(punit, GOTO_MOVE_ANY, 0);
}
}
+}
+
+/**************************************************************************
+Explores unknown territory, finds huts.
+Returns whether there is any more territory to be explored.
+**************************************************************************/
+int ai_manage_explorer(struct unit *punit)
+{
+ struct player *pplayer = unit_owner(punit);
+ int rv;
+ int x, y;
+ int con; /* continent the unit is on */
+ int range;
+
+ if (punit->activity != ACTIVITY_IDLE)
+ handle_unit_activity_request(punit, ACTIVITY_IDLE);
+
+ x = punit->x; y = punit->y;
+ if (is_ground_unit(punit)) con = map_get_continent(x, y);
+ else con = 0; /* Thanks, Tony */
+
+ /* CPU-expensive but worth it -- Syela */
+ generate_warmap(map_get_city(x, y), punit);
+
+ /* Barbarians and boats don't hunt huts */
+ if (!is_barbarian(pplayer) && is_ground_unit(punit))
+ {
+ rv = ai_manage_explorer_1(punit, pplayer);
+ if (rv >= 0) return rv;
+ if (rv == -2) return ai_manage_explorer(punit);
+ }
+
+ range = get_unit_type(punit->type)->vision_range;
+
+ rv = ai_manage_explorer_2(punit, pplayer, con, range);
+ if (rv >= 0) return rv;
+ if (rv == -2) return ai_manage_explorer(punit);
+
+ rv = ai_manage_explorer_3(punit, pplayer, con, range);
+ if (rv >= 0) return rv;
+ if (rv == -2) return ai_manage_explorer(punit);
+
+ ai_manage_explorer_4(punit, pplayer, con);
return 0;
}
- [Freeciv-Dev] [PATCH] ai_manage_explorer splitup,
Markus Linnala <=
|
|