mail[Wesnoth-commits] r33361 - in /trunk/src: formula_ai.cpp formula_ai.hpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by dragonking on March 05, 2009 - 23:25:
Author: dragonking
Date: Thu Mar  5 23:25:39 2009
New Revision: 33361

URL: http://svn.gna.org/viewcvs/wesnoth?rev=33361&view=rev
Log:
Code cleanup and pathfinding improvmements for formula ai

Modified:
    trunk/src/formula_ai.cpp
    trunk/src/formula_ai.hpp

Modified: trunk/src/formula_ai.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_ai.cpp?rev=33361&r1=33360&r2=33361&view=diff
==============================================================================
--- trunk/src/formula_ai.cpp (original)
+++ trunk/src/formula_ai.cpp Thu Mar  5 23:25:39 2009
@@ -472,6 +472,9 @@
                const map_location src = 
convert_variant<location_callable>(args()[0]->evaluate(variables))->loc();
                const map_location dst = 
convert_variant<location_callable>(args()[1]->evaluate(variables))->loc();
 
+                if( src == dst )
+                    return variant(&locations);
+                
                unit_map::iterator unit_it = ai_.get_info().units.find(src);
                if( unit_it == ai_.get_info().units.end() ) {
                        std::ostringstream str;
@@ -479,19 +482,23 @@
                        throw formula_error( str.str(), "", "", 0);
                }
 
-               if( (ai_.get_possible_moves().count(src) > 0) ) {
-                       std::map<map_location,paths>::const_iterator path = 
ai_.get_possible_moves().find(src);
-
-                       shortest_path_calculator calc(unit_it->second, 
ai_.current_team(), ai_.get_info().units, ai_.get_info().teams, 
ai_.get_info().map);
-                       paths::route route = a_star_search(src, dst, 1000.0, 
&calc, ai_.get_info().map.w(), ai_.get_info().map.h());
-
-                        if( route.steps.size() == 0 )
-                            return variant();
-
-                       for (std::vector<map_location>::const_iterator 
loc_iter = route.steps.begin() + 1 ; loc_iter !=route.steps.end(); 
++loc_iter) {
-                               locations.push_back( variant( new 
location_callable(*loc_iter) ));
-                       }
-               }
+                std::set<map_location> allowed_teleports = 
ai_.get_allowed_teleports(unit_it);
+
+                paths::route route = ai_.shortest_path_calculator( src, dst, 
unit_it, allowed_teleports );
+
+                if( route.steps.size() == 0 ) {
+                    emergency_path_calculator em_calc(unit_it->second, 
ai_.get_info().map);
+
+                    route = a_star_search(src, dst, 1000.0, &em_calc, 
ai_.get_info().map.w(), ai_.get_info().map.h(), &allowed_teleports);
+
+                    if( route.steps.size() < 2 ) {
+                        return variant(&locations);
+                    }
+                }
+
+                for (std::vector<map_location>::const_iterator loc_iter = 
route.steps.begin() + 1 ; loc_iter !=route.steps.end(); ++loc_iter) {
+                        locations.push_back( variant( new 
location_callable(*loc_iter) ));
+                }
 
                return variant(&locations);
        }
@@ -1574,83 +1581,100 @@
        return execute_variant(var);
 }
 
+paths::route formula_ai::shortest_path_calculator(const map_location& src, 
const map_location& dst, unit_map::iterator& unit_it, std::set<map_location>& 
allowed_teleports) const {
+
+    map_location destination = dst;
+
+    shortest_path_calculator::shortest_path_calculator calc(unit_it->second, 
current_team(), units_, get_info().teams, get_info().map);
+
+    unit_map::const_iterator dst_un = units_.find(destination);
+
+    map_location res;
+
+    if( dst_un != units_.end() ) {
+        //there is unit standing at dst, let's try to find free hex to move 
to
+        const map_location::DIRECTION preferred = 
destination.get_relative_dir(src);
+
+        int best_rating = 100;//smaller is better
+        map_location adj[6];
+        get_adjacent_tiles(destination,adj);
+
+        for(size_t n = 0; n != 6; ++n) {
+                if(map_.on_board(adj[n]) == false) {
+                        continue;
+                }
+
+                if(units_.find(adj[n]) != units_.end()) {
+                        continue;
+                }
+
+                static const size_t NDIRECTIONS = map_location::NDIRECTIONS;
+                unsigned int difference = abs(int(preferred - n));
+                if(difference > NDIRECTIONS/2) {
+                        difference = NDIRECTIONS - difference;
+                }
+
+                const int rating = difference * 2;
+                if(rating < best_rating || res.valid() == false) {
+                       best_rating = rating;
+                       res = adj[n];
+                }
+        }
+    }
+
+    if( res != map_location() ) {
+        destination = res;
+    }
+
+    paths::route route = a_star_search(src, destination, 1000.0, &calc,
+            get_info().map.w(), get_info().map.h(), &allowed_teleports);
+
+    return route;
+}
+
+std::set<map_location> formula_ai::get_allowed_teleports(unit_map::iterator& 
unit_it) const {
+    std::set<map_location> allowed_teleports;
+
+    if(unit_it->second.get_ability_bool("teleport",unit_it->first)) {
+            for(std::set<map_location>::const_iterator i = 
current_team().villages().begin();
+                            i != current_team().villages().end(); ++i) {
+                    //if (viewing_team().is_enemy(unit_it->second.side()) && 
viewing_team().fogged(*i))
+                    //        continue;
+
+                    unit_map::const_iterator occupant = units_.find(*i);
+                    if (occupant != units_.end() && occupant != unit_it)
+                            continue;
+
+                    allowed_teleports.insert(*i);
+            }
+    }
+
+    return allowed_teleports;
+}
+
 map_location formula_ai::path_calculator(const map_location& src, const 
map_location& dst, unit_map::iterator& unit_it) const{
     std::map<map_location,paths>::iterator path = possible_moves_.find(src);
     
     map_location destination = dst;
 
     //check if destination is within unit's reach, if not, calculate where 
to move
-    if( path->second.routes.count(destination) == 0) {
+    if( path->second.routes.count(dst) == 0) {
+
+            std::set<map_location> allowed_teleports = 
get_allowed_teleports(unit_it);
             //destination is too far, check where unit can go
-            shortest_path_calculator calc(unit_it->second, current_team(), 
units_, get_info().teams, get_info().map);
-
-            std::set<map_location> allowed_teleports;
-
-            if(unit_it->second.get_ability_bool("teleport",unit_it->first)) {
-                    for(std::set<map_location>::const_iterator i = 
current_team().villages().begin();
-                                    i != current_team().villages().end(); 
++i) {
-                            //if 
(viewing_team().is_enemy(unit_it->second.side()) && viewing_team().fogged(*i))
-                            //        continue;
-
-                            unit_map::const_iterator occupant = 
units_.find(*i);
-                            if (occupant != units_.end() && occupant != 
unit_it)
-                                    continue;
-
-                            allowed_teleports.insert(*i);
-                    }
-            }
-
-            unit_map::const_iterator dst_un = units_.find(destination);
-
-            map_location res;
-
-            if( dst_un != units_.end() ) {
-                //there is unit standing at dst, let's try to find free hex 
to move to
-                const map_location::DIRECTION preferred = 
destination.get_relative_dir(src);
-
-                int best_rating = 100;//smaller is better
-                map_location adj[6];
-                get_adjacent_tiles(destination,adj);
-
-                for(size_t n = 0; n != 6; ++n) {
-                        if(map_.on_board(adj[n]) == false) {
-                                continue;
-                        }
-
-                        if(units_.find(adj[n]) != units_.end()) {
-                                continue;
-                        }
-
-                        static const size_t NDIRECTIONS = 
map_location::NDIRECTIONS;
-                        unsigned int difference = abs(int(preferred - n));
-                        if(difference > NDIRECTIONS/2) {
-                                difference = NDIRECTIONS - difference;
-                        }
-
-                        const int rating = difference * 2;
-                        if(rating < best_rating || res.valid() == false) {
-                               best_rating = rating;
-                               res = adj[n];
-                        }
-                }
-            }
-
-            if( res != map_location() ) {
-                destination = res;
-            }
-
-            paths::route route = a_star_search(src, destination, 1000.0, 
&calc,
-                    get_info().map.w(), get_info().map.h(), 
&allowed_teleports);
+
+             paths::route route = shortest_path_calculator( src, dst, 
unit_it, allowed_teleports );
 
             if( route.steps.size() == 0 ) {
                 emergency_path_calculator em_calc(unit_it->second, 
get_info().map);
 
-                route = a_star_search(src, destination, 1000.0, &em_calc, 
get_info().map.w(), get_info().map.h(), &allowed_teleports);
+                route = a_star_search(src, dst, 1000.0, &em_calc, 
get_info().map.w(), get_info().map.h(), &allowed_teleports);
 
                 if( route.steps.size() < 2 ) {
                     return map_location();
                 }
             }
+
             for (std::vector<map_location>::const_iterator loc_iter = 
route.steps.begin() + 1 ; loc_iter !=route.steps.end(); ++loc_iter) {
                typedef formula_ai::move_map::const_iterator Itor;
                std::pair<Itor,Itor> range = srcdst_.equal_range(src);

Modified: trunk/src/formula_ai.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/formula_ai.hpp?rev=33361&r1=33360&r2=33361&view=diff
==============================================================================
--- trunk/src/formula_ai.hpp (original)
+++ trunk/src/formula_ai.hpp Thu Mar  5 23:25:39 2009
@@ -152,6 +152,9 @@
        void handle_exception(game_logic::formula_error& e) const;
        void handle_exception(game_logic::formula_error& e, const 
std::string& failed_operation) const;
 
+        std::set<map_location> get_allowed_teleports(unit_map::iterator& 
unit_it) const;
+        paths::route shortest_path_calculator(const map_location& src, const 
map_location& dst, unit_map::iterator& unit_it, std::set<map_location>& 
allowed_teleports) const;
+
         void invalidate_move_maps() const { move_maps_valid_ = false; }
 
 private:
@@ -169,6 +172,7 @@
        void prepare_move() const;
        void build_move_list();
        void make_candidate_moves();
+
         map_location path_calculator(const map_location& src, const 
map_location& dst, unit_map::iterator& unit_it) const;
        mutable bool move_maps_valid_;
        mutable move_map srcdst_, dstsrc_, full_srcdst_, full_dstsrc_, 
enemy_srcdst_, enemy_dstsrc_;




Related Messages


Powered by MHonArc, Updated Fri Mar 06 00:20:31 2009