mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-04 05:48:29 +00:00
Forward-port suokko's improvements to AI recruitment,
...previously reverted as an emergency fix, from 2008-09-16T18:14:54Z!paniemin@cc.hut.fi and 2008-09-16T19:26:36Z!paniemin@cc.hut.fi.
This commit is contained in:
parent
172253eb37
commit
e8d3d00d78
49
src/ai.cpp
49
src/ai.cpp
@ -175,18 +175,20 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void do_recruitment() {
|
||||
bool do_recruitment() {
|
||||
const std::set<std::string>& options = current_team().recruits();
|
||||
if (!options.empty()) {
|
||||
if (!options.empty()) {
|
||||
const int choice = (rand()%options.size());
|
||||
std::set<std::string>::const_iterator i = options.begin();
|
||||
std::advance(i,choice);
|
||||
|
||||
const bool res = recruit(*i);
|
||||
if(res) {
|
||||
do_recruitment();
|
||||
return do_recruitment();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@ -296,7 +298,7 @@ ai::ai(ai_interface::info& info) :
|
||||
avoid_(),
|
||||
unit_stats_cache_(),
|
||||
attack_depth_(0),
|
||||
recruiting_prefered_(false)
|
||||
recruiting_preferred_(0)
|
||||
{}
|
||||
|
||||
void ai::new_turn()
|
||||
@ -971,10 +973,31 @@ void ai::play_turn()
|
||||
|
||||
void ai::evaluate_recruiting_value(unit_map::iterator leader)
|
||||
{
|
||||
const int gold = current_team().gold();
|
||||
// const int unit_price = current_team().average_recruit_price();
|
||||
// recruiting_prefered_ = (gold/unit_price) > min_recruiting_value_to_force_recruit && !map_.is_keep();
|
||||
recruiting_prefered_ = gold > min_recruiting_value_to_force_recruit && !map_.is_keep(leader->first);
|
||||
if (recruiting_preferred_ == 2)
|
||||
{
|
||||
recruiting_preferred_ = 0;
|
||||
return;
|
||||
}
|
||||
if (current_team().num_pos_recruits_to_force()< 0.01f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float free_slots = 0.0f;
|
||||
if (map_.is_keep(leader->first))
|
||||
{
|
||||
std::set<location> checked_hexes;
|
||||
checked_hexes.insert(leader->first);
|
||||
free_slots = count_free_hexes_in_castle(leader->first, checked_hexes);
|
||||
}
|
||||
const float gold = current_team().gold();
|
||||
const float unit_price = current_team().average_recruit_price();
|
||||
recruiting_preferred_ = (gold/unit_price) - free_slots > current_team().num_pos_recruits_to_force();
|
||||
DBG_AI << "recruiting preferred: " << (recruiting_preferred_?"yes":"no") <<
|
||||
" units to recruit: " << (gold/unit_price) <<
|
||||
" unit_price: " << unit_price <<
|
||||
" free slots: " << free_slots <<
|
||||
" limit: " << current_team().num_pos_recruits_to_force() << "\n";
|
||||
}
|
||||
|
||||
void ai::do_move()
|
||||
@ -1157,7 +1180,7 @@ bool ai::do_combat(std::map<map_location,paths>& possible_moves, const move_map&
|
||||
LOG_AI << "attack option rated at " << rating << " ("
|
||||
<< current_team().aggression() << ")\n";
|
||||
|
||||
if (recruiting_prefered_)
|
||||
if (recruiting_preferred_)
|
||||
{
|
||||
unit_map::unit_iterator u = units_.find(it->movements[0].first);
|
||||
if (u != units_.end()
|
||||
@ -1814,11 +1837,11 @@ void ai::analyze_potential_recruit_movements()
|
||||
}
|
||||
}
|
||||
|
||||
void ai::do_recruitment()
|
||||
bool ai::do_recruitment()
|
||||
{
|
||||
const unit_map::const_iterator leader = find_leader(units_,team_num_);
|
||||
if(leader == units_.end()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const location& start_pos = nearest_keep(leader->first);
|
||||
@ -1892,12 +1915,16 @@ void ai::do_recruitment()
|
||||
options.push_back("");
|
||||
}
|
||||
// Buy units as long as we have room and can afford it.
|
||||
bool ret = false;
|
||||
while (recruit_usage(options[rand()%options.size()])) {
|
||||
ret = true;
|
||||
options = current_team().recruitment_pattern();
|
||||
if (options.empty()) {
|
||||
options.push_back("");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ai::move_leader_to_goals( const move_map& enemy_dstsrc)
|
||||
|
@ -91,7 +91,7 @@ protected:
|
||||
const unit_map::const_iterator un, const move_map& srcdst,
|
||||
const move_map& dstsrc, const move_map& enemy_dstsrc, double caution);
|
||||
|
||||
virtual void do_recruitment();
|
||||
virtual bool do_recruitment();
|
||||
|
||||
virtual void move_leader_to_keep(const move_map& enemy_dstsrc);
|
||||
virtual void move_leader_after_recruit(const move_map& srcdst,
|
||||
@ -377,7 +377,7 @@ private:
|
||||
const std::map<map_location,paths>& possible_moves,
|
||||
const std::multimap<map_location,map_location>& enemy_dstsrc) const;
|
||||
|
||||
bool recruiting_prefered_;
|
||||
int recruiting_preferred_;
|
||||
static const int min_recruiting_value_to_force_recruit = 28;
|
||||
};
|
||||
|
||||
|
@ -853,7 +853,7 @@ void ai::move_leader_to_keep(const move_map& enemy_dstsrc)
|
||||
:0);
|
||||
const int enemy = (power_projection(*i, enemy_dstsrc) * 8 * leader->second.total_movement())/leader->second.hitpoints();
|
||||
int multiturn_move_penalty = 0;
|
||||
if (recruiting_prefered_)
|
||||
if (recruiting_preferred_)
|
||||
multiturn_move_penalty = 2;
|
||||
|
||||
const int distance_value = (distance > leader->second.movement_left()?
|
||||
|
@ -262,7 +262,7 @@ void ai::find_villages(
|
||||
{
|
||||
std::map<location, double> vulnerability;
|
||||
|
||||
const bool passive_leader = recruiting_prefered_ ||
|
||||
const bool passive_leader = recruiting_preferred_ ||
|
||||
utils::string_bool(current_team().ai_parameters()["passive_leader"]);
|
||||
|
||||
size_t min_distance = 100000;
|
||||
|
@ -1771,10 +1771,10 @@ bool formula_ai::execute_variant(const variant& var, bool commandline)
|
||||
}
|
||||
|
||||
|
||||
void formula_ai::do_recruitment()
|
||||
bool formula_ai::do_recruitment()
|
||||
{
|
||||
if(!recruit_formula_) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
variant var = recruit_formula_->execute(*this);
|
||||
@ -1787,17 +1787,19 @@ void formula_ai::do_recruitment()
|
||||
vars.push_back(var);
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
for(std::vector<variant>::const_iterator i = vars.begin(); i != vars.end(); ++i) {
|
||||
if(!i->is_string()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!recruit(i->as_string())) {
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
|
||||
do_recruitment();
|
||||
return do_recruitment();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -153,7 +153,7 @@ private:
|
||||
void handle_exception(game_logic::formula_error& e);
|
||||
void handle_exception(game_logic::formula_error& e, const std::string& failed_operation);
|
||||
void display_message(const std::string& msg);
|
||||
void do_recruitment();
|
||||
bool do_recruitment();
|
||||
bool make_move(game_logic::const_formula_ptr formula_, const game_logic::formula_callable& variables);
|
||||
bool execute_variant(const variant& var, bool commandline=false);
|
||||
virtual variant get_value(const std::string& key) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user