Author: esr
Date: Wed Oct 22 20:55:30 2008
New Revision: 30309

URL: http://svn.gna.org/viewcvs/wesnoth?rev=30309&view=rev
Log:
Forward-port suokko's improvements in moving leader to keep from 29484
and r29498.

Modified:
    trunk/src/ai_move.cpp

Modified: trunk/src/ai_move.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/ai_move.cpp?rev=30309&r1=30308&r2=30309&view=diff
==============================================================================
--- trunk/src/ai_move.cpp (original)
+++ trunk/src/ai_move.cpp Wed Oct 22 20:55:30 2008
@@ -25,10 +25,9 @@
 #include <cassert>
 #include <iostream>
 
-#include <queue>
-
 #define LOG_AI LOG_STREAM(info, ai)
 #define DBG_AI LOG_STREAM(debug, ai)
+#define ERR_AI LOG_STREAM(err, ai)
 
 struct move_cost_calculator : cost_calculator
 {
@@ -802,26 +801,12 @@
        }
 }
 
-struct keep_value {
-       size_t value;
-       map_location loc;
-
-       keep_value(size_t v, const map_location& l) : value(v), loc(l)
-       {}
-       bool operator<(const keep_value& val) const 
-       {
-               return value > val.value;
-       }
-};
-
-
 void ai::move_leader_to_keep(const move_map& enemy_dstsrc)
 {
        const unit_map::iterator leader = find_leader(units_,team_num_);
        if(leader == units_.end() 
                || leader->second.incapacitated() 
-               || leader->second.movement_left() == 0
-               || !recruiting_prefered_) {
+               || leader->second.movement_left() == 0) {
                return;
        }
 
@@ -829,14 +814,16 @@
        std::map<map_location,paths>::iterator path_itor = 
possible_moves.insert(std::make_pair(leader->first, paths())).first;
 
        // Guess how many units we want to recruit
-       const int number_of_recruit = current_team().gold() / 15;
+       const int number_of_recruit = current_team().gold() / 
current_team().average_recruit_price();
 
        // If the leader is not on his starting location, move him there.
+       if (number_of_recruit)
        {
                {
                        // Make a map of the possible locations the leader can 
move to,
                        // ordered by the distance from the keep.
-                       std::priority_queue<keep_value> moves_toward_keep;
+                       int best_value = INT_MAX;
+                       map_location best_target;
 
                        // 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.
@@ -854,37 +841,55 @@
                                const int distance = 
route->second.steps.size()-1;
                                checked_hexes.insert(*i);
                                const int free_slots = 
count_free_hexes_in_castle(*i, checked_hexes);
-                               const int tactical_value = 
leader->second.total_movement() * 0;
+                               const int tactical_value =  
std::sqrt(std::pow(static_cast<float>(map_.w()/2 - i->x),2) +
+                                                       
std::pow(static_cast<float>(map_.h()/2 - i->y),2))*2;
                                const int empty_slots = 
leader->second.total_movement() * std::max(number_of_recruit - free_slots,0);
                                unit_map::const_iterator u = units_.find(*i);
                                const int reserved_penalty = 
leader->second.total_movement() * 
-                                       (u != units_.end()?
-                                               
(current_team().is_enemy(u->second.side())?4:2)
+                                       (u != units_.end() 
+                                               && &teams_[u->second.side()-1] 
!= &current_team() 
+                                               && 
!u->second.invisible(u->first, units_, teams_)
+                                                       
?(current_team().is_enemy(u->second.side())?6:3)
                                        :0);
-                               const int enemy = 
leader->second.total_movement() * enemy_dstsrc.count(*i);
+                               const int enemy = (power_projection(*i, 
enemy_dstsrc) * 8 * leader->second.total_movement())/leader->second.hitpoints();
+                               int multiturn_move_penalty = 0;
+                               if (recruiting_prefered_)
+                                       multiturn_move_penalty = 2;
+
+                               const int distance_value = (distance > 
leader->second.movement_left()? 
+                                               ((distance - 
leader->second.movement_left())/leader->second.total_movement()+multiturn_move_penalty)*leader->second.total_movement()
 : 0);
+                               const int value = distance_value + empty_slots 
+ enemy + tactical_value + reserved_penalty;
+       
+                               if (value > best_value)
+                                       continue;
+
                                map_location target;
                                if (distance > leader->second.movement_left())
                                {
-                                       target = 
route->second.steps[leader->second.movement_left()+1];
-                                       
route->second.steps.erase(route->second.steps.begin() + 
leader->second.movement_left(),route->second.steps.end());
+                                       target = 
route->second.steps[leader->second.movement_left()];
+                                       
route->second.steps.erase(route->second.steps.begin() + 
leader->second.movement_left()+1,route->second.steps.end());
                                        route->second.move_left = 0;
                                } else {
                                        target = *i;
                                        route->second.move_left = 
leader->second.movement_left() - distance;
                                }
-                               DBG_AI << "Considiring keep: " << *i << 
+                               best_value = value;
+                               best_target = target;
+                               DBG_AI << "Considering keep: " << *i << 
                                        " empty slots: " << empty_slots << 
                                        " distance: " << distance << 
                                        " enemy: " << enemy << 
+                                       " tactical_value: " << tactical_value 
<< 
+                                       " reserved_penalty: " << 
reserved_penalty << 
                                        " target: " << target <<
+                                       " value: " << value <<
                                    " route: " << route->second.steps.size() << 
" " << route->second.move_left <<       
                                        "\n";
-                               moves_toward_keep.push(keep_value(distance + 
empty_slots + enemy + tactical_value + reserved_penalty ,target));
-                       }
+               }
 
                        // Find the location with the best value
-                       if (leader->first != moves_toward_keep.top().loc)
-                               
move_unit(leader->first,moves_toward_keep.top().loc,possible_moves);
+                       if (leader->first != best_target)
+                               
move_unit(leader->first,best_target,possible_moves);
                }
        }
 }
@@ -903,7 +908,9 @@
                        ret += count_free_hexes_in_castle(adj[n], 
checked_hexes);
                        if (u == units_.end() 
                                || (current_team().is_enemy(u->second.side()) 
-                                       && u->second.invisible(adj[n], units_, 
teams_))) {
+                                       && u->second.invisible(adj[n], units_, 
teams_))
+                               || ((&teams_[u->second.side()-1]) == 
&current_team()
+                                       && u->second.movement_left() > 0)) {
                                ret += 1;
                        }
                }


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to