Author: crab
Date: Thu Apr 9 00:55:55 2009
New Revision: 34641
URL: http://svn.gna.org/viewcvs/wesnoth?rev=34641&view=rev
Log:
Changed AI keep lookup behavior when returning leader to keep. Made it use, in
order of decreasing preference: nearest (by pathfinding) empty keep reachable
within 1 turn, nearest (by pathfinding) occupied keep reachable within 1 turn,
old nearest_keep() implementation. This fixes bug #13352. note: backport of
this to 1.6 depends on r34430 being backported.
Modified:
trunk/src/ai.hpp
trunk/src/ai_move.cpp
Modified: trunk/src/ai.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/ai.hpp?rev=34641&r1=34640&r2=34641&view=diff
==============================================================================
--- trunk/src/ai.hpp (original)
+++ trunk/src/ai.hpp Thu Apr 9 00:55:55 2009
@@ -351,6 +351,8 @@
/** Functions to deal with keeps. */
const std::set<location>& keeps();
const location& nearest_keep(const location& loc);
+ /** get most suitable keep for leader - nearest free that can be
reached in 1 turn, if none - return nearest occupied that can be reached in 1
turn, if none - return null_location */
+ const map_location& suitable_keep( const location& leader_location,
const paths& leader_paths );
int count_free_hexes_in_castle(const map_location& loc,
std::set<map_location>&);
void evaluate_recruiting_value(unit_map::iterator leader);
Modified: trunk/src/ai_move.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/ai_move.cpp?rev=34641&r1=34640&r2=34641&view=diff
==============================================================================
--- trunk/src/ai_move.cpp (original)
+++ trunk/src/ai_move.cpp Thu Apr 9 00:55:55 2009
@@ -860,6 +860,51 @@
}
}
+const map_location& ai::suitable_keep(const map_location& leader_location,
const paths& leader_paths){
+ if (map_.is_keep(leader_location)) {
+ return leader_location; //if leader already on keep, then
return leader_location
+ }
+
+ map_location const* best_free_keep = &map_location::null_location;
+ double cost_to_best_free_keep = 0.0;
+
+ map_location const* best_occupied_keep = &map_location::null_location;
+ double cost_to_best_occupied_keep = 0.0;
+
+ for(std::map<location,paths::route>::const_iterator rt =
leader_paths.routes.begin(); rt != leader_paths.routes.end(); ++rt) {
+ const map_location& loc = rt->first;
+ if (map_.is_keep(loc)){
+ //@todo: .move_left for 1-turn-moves is really
"cost_to_get_there", it is just not renamed there yet. see r34430 for more
detais.
+ const int cost_to_loc = rt->second.move_left;
+ if (units_.count(loc) == 0) {
+ if
((*best_free_keep==map_location::null_location)||(cost_to_loc<cost_to_best_free_keep)){
+ best_free_keep = &loc;
+ cost_to_best_free_keep = cost_to_loc;
+ }
+ } else {
+ if
((*best_occupied_keep==map_location::null_location)||(cost_to_loc<cost_to_best_occupied_keep)){
+ best_occupied_keep = &loc;
+ cost_to_best_occupied_keep =
cost_to_loc;
+ }
+ }
+ }
+ }
+
+ if (*best_free_keep != map_location::null_location){
+ return *best_free_keep; // if there is a free keep reachable
during current turn, return it
+ }
+
+ if (*best_occupied_keep != map_location::null_location){
+ return *best_occupied_keep; // if there is an occupied keep
reachable during current turn, return it
+ }
+
+ if (*best_occupied_keep != map_location::null_location){
+ return nearest_keep(leader_location); // return nearest keep
+ }
+
+ return map_location::null_location; // return dummy location
+}
+
void ai::move_leader_to_keep(const move_map& enemy_dstsrc)
{
const unit_map::iterator leader = find_leader(units_,team_num_);
@@ -870,16 +915,16 @@
// Find where the leader can move
const paths leader_paths(map_, units_, leader->first,
teams_, false, false, current_team());
- const map_location& start_pos = nearest_keep(leader->first);
+ const map_location& keep = suitable_keep(leader->first,leader_paths);
std::map<map_location,paths> possible_moves;
possible_moves.insert(std::pair<map_location,paths>(leader->first,leader_paths));
- // If the leader is not on his starting location, move him there.
- if(leader->first != start_pos) {
- const paths::routes_map::const_iterator itor =
leader_paths.routes.find(start_pos);
- if(itor != leader_paths.routes.end() && units_.count(start_pos)
== 0) {
- move_unit(leader->first,start_pos,possible_moves);
+ // If the leader is not on keep, move him there.
+ if(leader->first != keep) {
+ const paths::routes_map::const_iterator itor =
leader_paths.routes.find(keep);
+ if(itor != leader_paths.routes.end() && units_.count(keep) ==
0) {
+ move_unit(leader->first,keep,possible_moves);
} else {
// Make a map of the possible locations the leader can
move to,
// ordered by the distance from the keep.
@@ -887,11 +932,11 @@
// The leader can't move to his keep, try to move to
the closest location
// to the keep where there are no enemies in range.
- const int current_distance =
distance_between(leader->first,start_pos);
+ const int current_distance =
distance_between(leader->first,keep);
for(paths::routes_map::const_iterator i =
leader_paths.routes.begin();
i != leader_paths.routes.end(); ++i) {
- const int new_distance =
distance_between(i->first,start_pos);
+ const int new_distance =
distance_between(i->first,keep);
if(new_distance < current_distance) {
moves_toward_keep.insert(std::pair<int,map_location>(new_distance,i->first));
}
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits