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]
!= ¤t_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]) ==
¤t_team()
+ && u->second.movement_left() > 0)) {
ret += 1;
}
}
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits