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

Reply via email to