added new ai parameters. Tweaked settings of Isle of Anduin scenario
This commit is contained in:
parent
861a887613
commit
6105dc96f3
11 changed files with 198 additions and 73 deletions
|
@ -5,19 +5,19 @@ sscccccssssssscccddccsccccssssss
|
|||
sccddcccsssssccccgddcccccccccsss
|
||||
ccdggdccscccscddcggddccdddcccsss
|
||||
sccdtdccccccccdgcgggddddddddccss
|
||||
sccdtdcccdddcdgtcggggddggdddccss
|
||||
sccdgdcccdddcdgtcggggddggdddccss
|
||||
sccdggdcdgggcdgccggtggggggddccss
|
||||
ccdggggdggggcggcfgggggggfffddccs
|
||||
ccdggttgggggcgccfggggggCCCfgddcc
|
||||
ccdtgggggggtcgcffgggggtC1Cfgddcc
|
||||
sccdggggggggcccfggggggfCCCffdccs
|
||||
sccdggggtggggccftfggggftftffdccs
|
||||
scccdgggggggggcfffggtfffffffddcc
|
||||
sccdtgggggggggcfffggffffffffddcc
|
||||
ccdgggggggggtgccmmmfffffffffgddc
|
||||
ccdggggggggggmmcmmmffffffgggddcc
|
||||
scctgtgggthhmmmccmmmfftfftggddcs
|
||||
scddggggghhhmmccccmmggggggggdcss
|
||||
ccdggggdgfggcggcggggggggfffddccs
|
||||
ccdgggtggffgcgccgggggggCCCfgddcc
|
||||
ccdtgggggggtcgcgggggggtC1Cfgddcc
|
||||
sccdgffgggggcccgggggggfCCCffdccs
|
||||
sccdggggtggggccgtgggggftftffdccs
|
||||
scccdggggfggffcgggggtfffffffddcc
|
||||
sccdtgfgggfgggcgggggffffffffddcc
|
||||
ccdggggfggggtgccmmmfffffffffgddc
|
||||
ccdgggfggggggmmcmmmffffffgggddcc
|
||||
scctgggggthhmmmccmmmfftfftggddcs
|
||||
scddgghhghhhmmccccmmggggggggdcss
|
||||
ssdgggggghhhmmcccccmmhgggggfgdcs
|
||||
sssddgggghhhmmcccccmmhgggggffdcs
|
||||
sssssdtggghhhmmccccmmhggggggftdc
|
||||
|
|
|
@ -59,6 +59,24 @@ Defeat:
|
|||
x=19
|
||||
y=23
|
||||
[/unit]
|
||||
[ai]
|
||||
village_value=0.0
|
||||
leader_value=0.0
|
||||
[target]
|
||||
description=Konrad
|
||||
value=8.0
|
||||
[/target]
|
||||
|
||||
[protect_unit]
|
||||
description=Konrad
|
||||
radius=12
|
||||
value=40.0
|
||||
[/protect_unit]
|
||||
|
||||
[leader_goal]
|
||||
x,y=1,1
|
||||
[/leader_goal]
|
||||
[/ai]
|
||||
[/side]
|
||||
|
||||
#ifdef HARD
|
||||
|
|
|
@ -62,9 +62,19 @@ Defeat:
|
|||
side=2
|
||||
canrecruit=1
|
||||
recruit=Orcish Grunt,Wolf Rider,Orcish Archer,Troll Whelp,Saurian
|
||||
recruitment_pattern=scout,scout,fighter,fighter,archer
|
||||
{GOLD 80 160 260}
|
||||
{GOLD 40 120 180}
|
||||
enemy=1
|
||||
[ai]
|
||||
recruitment_pattern=scout,scout,fighter,fighter,archer
|
||||
[/ai]
|
||||
|
||||
#make the AI alot more aggressive at night
|
||||
[ai]
|
||||
time_of_day=dusk,first_watch,second_watch
|
||||
aggression=0.75
|
||||
caution=0
|
||||
grouping=no
|
||||
[/ai]
|
||||
[/side]
|
||||
|
||||
#make the orcs start with a whole slew of villages
|
||||
|
|
72
src/ai.cpp
72
src/ai.cpp
|
@ -516,8 +516,9 @@ void ai::find_threats()
|
|||
const protected_item& item = *k;
|
||||
|
||||
for(unit_map::const_iterator u = units_.begin(); u != units_.end(); ++u) {
|
||||
if(current_team().is_enemy(u->second.side()) && distance_between(u->first,item.loc) < item.radius) {
|
||||
add_target(target(u->first,item.value,target::THREAT));
|
||||
const int distance = distance_between(u->first,item.loc);
|
||||
if(current_team().is_enemy(u->second.side()) && distance < item.radius) {
|
||||
add_target(target(u->first,item.value*double(item.radius-distance)/double(item.radius),target::THREAT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -574,6 +575,8 @@ void ai::do_move()
|
|||
}
|
||||
}
|
||||
|
||||
move_leader_to_goals(enemy_dstsrc);
|
||||
|
||||
AI_DIAGNOSTIC("get villages phase");
|
||||
|
||||
std::cerr << "villages...\n";
|
||||
|
@ -622,6 +625,7 @@ void ai::do_move()
|
|||
|
||||
//recruitment phase and leader movement phase
|
||||
if(leader != units_.end()) {
|
||||
|
||||
if(!passive_leader) {
|
||||
move_leader_to_keep(enemy_dstsrc);
|
||||
}
|
||||
|
@ -699,7 +703,7 @@ bool ai::do_combat(std::map<gamemap::location,paths>& possible_moves, const move
|
|||
|
||||
attack_enemy(to,target_loc,weapon);
|
||||
|
||||
//if this is the only unit in the planned attack, and the target
|
||||
//if this is the only unit in the attack, and the target
|
||||
//is still alive, then also summon reinforcements
|
||||
if(choice_it->movements.size() == 1 && units_.count(target_loc)) {
|
||||
add_target(target(target_loc,3.0,target::BATTLE_AID));
|
||||
|
@ -708,20 +712,6 @@ bool ai::do_combat(std::map<gamemap::location,paths>& possible_moves, const move
|
|||
return true;
|
||||
|
||||
} else {
|
||||
log_scope("summoning reinforcements...\n");
|
||||
|
||||
std::set<gamemap::location> already_done;
|
||||
|
||||
for(std::vector<attack_analysis>::iterator it = analysis.begin(); it != analysis.end(); ++it) {
|
||||
assert(it->movements.empty() == false);
|
||||
const gamemap::location& loc = it->movements.front().first;
|
||||
if(already_done.count(loc) > 0)
|
||||
continue;
|
||||
|
||||
add_target(target(loc,3.0,target::BATTLE_AID));
|
||||
already_done.insert(loc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1425,11 +1415,57 @@ void ai::do_recruitment()
|
|||
}
|
||||
}
|
||||
|
||||
void ai::move_leader_to_goals(const move_map& enemy_dstsrc)
|
||||
{
|
||||
const config* const goal = current_team().ai_parameters().child("leader_goal");
|
||||
|
||||
if(goal == NULL) {
|
||||
AI_LOG("No goal found");
|
||||
return;
|
||||
}
|
||||
|
||||
const gamemap::location dst(*goal);
|
||||
|
||||
const unit_map::iterator leader = find_leader(units_,team_num_);
|
||||
if(leader == units_.end() || leader->second.incapacitated()) {
|
||||
AI_LOG("leader not found");
|
||||
return;
|
||||
}
|
||||
|
||||
AI_LOG("Doing recruitment before goals");
|
||||
|
||||
do_recruitment();
|
||||
|
||||
const paths::route route = a_star_search(leader->first,dst,1000.0,shortest_path_calculator(leader->second,current_team(),units_,teams_,map_,state_));
|
||||
if(route.steps.empty()) {
|
||||
AI_LOG("route empty");
|
||||
return;
|
||||
}
|
||||
|
||||
const paths leader_paths(map_,state_,gameinfo_,units_,leader->first,teams_,false,false);
|
||||
|
||||
std::map<gamemap::location,paths> possible_moves;
|
||||
possible_moves.insert(std::pair<gamemap::location,paths>(leader->first,leader_paths));
|
||||
|
||||
gamemap::location loc;
|
||||
for(std::vector<gamemap::location>::const_iterator itor = route.steps.begin(); itor != route.steps.end(); ++itor) {
|
||||
if(leader_paths.routes.count(*itor) == 1) {
|
||||
loc = *itor;
|
||||
}
|
||||
}
|
||||
|
||||
if(loc.valid()) {
|
||||
AI_LOG("Moving leader to goal");
|
||||
move_unit(leader->first,loc,possible_moves);
|
||||
}
|
||||
}
|
||||
|
||||
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.stone())
|
||||
if(leader == units_.end() || leader->second.incapacitated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//find where the leader can move
|
||||
const paths leader_paths(map_,state_,gameinfo_,units_,leader->first,teams_,false,false);
|
||||
|
|
|
@ -340,6 +340,7 @@ protected:
|
|||
|
||||
virtual void move_leader_to_keep(const move_map& enemy_dstsrc);
|
||||
virtual void move_leader_after_recruit(const move_map& enemy_dstsrc);
|
||||
virtual void move_leader_to_goals(const move_map& enemy_dstsrc);
|
||||
|
||||
virtual bool recruit_usage(const std::string& usage);
|
||||
|
||||
|
|
|
@ -523,7 +523,7 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
access_points(srcdst,best->first,best_target->loc,locs);
|
||||
|
||||
if(locs.empty() == false) {
|
||||
AI_DIAGNOSTIC("supporting unit at " + str_cast(best_target->loc.x+1) + "," + str_cast(best_target->loc.y+1));
|
||||
AI_LOG("supporting unit at " + str_cast(best_target->loc.x+1) + "," + str_cast(best_target->loc.y+1));
|
||||
location best_loc;
|
||||
int best_defense = 0;
|
||||
double best_vulnerability = 0.0;
|
||||
|
@ -578,14 +578,14 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
}
|
||||
|
||||
if(dangerous) {
|
||||
AI_DIAGNOSTIC("dangerous path");
|
||||
AI_LOG("dangerous path");
|
||||
std::set<location> group, enemies;
|
||||
const location dst = form_group(best_route.steps,dstsrc,srcdst,group);
|
||||
enemies_along_path(best_route.steps,enemy_dstsrc,enemy_srcdst,enemies);
|
||||
|
||||
const double our_strength = compare_groups(group,enemies,best_route.steps);
|
||||
|
||||
if(our_strength > 1.0 + current_team().caution()) {
|
||||
if(our_strength > 0.5 + current_team().caution()) {
|
||||
AI_DIAGNOSTIC("moving group");
|
||||
const bool res = move_group(dst,best_route.steps,group);
|
||||
AI_DIAGNOSTIC("");
|
||||
|
@ -599,7 +599,7 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
|
||||
}
|
||||
} else {
|
||||
AI_DIAGNOSTIC("massing to attack " + str_cast(best_target->loc.x+1) + "," + str_cast(best_target->loc.y+1) + " " + str_cast(our_strength));
|
||||
AI_LOG("massing to attack " + str_cast(best_target->loc.x+1) + "," + str_cast(best_target->loc.y+1) + " " + str_cast(our_strength));
|
||||
|
||||
const double value = best_target->value;
|
||||
const location target_loc = best_target->loc;
|
||||
|
@ -644,6 +644,9 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
}
|
||||
}
|
||||
|
||||
AI_LOG("Best route is " + best->second.type().name() + " " + str_cast(best_route.steps.front().x+1) + "," + str_cast(best_route.steps.front().y+1) + " -> "
|
||||
+ str_cast(best_route.steps.back().x+1) + "," + str_cast(best_route.steps.back().y+1));
|
||||
|
||||
for(std::vector<location>::reverse_iterator ri =
|
||||
best_route.steps.rbegin(); ri != best_route.steps.rend(); ++ri) {
|
||||
|
||||
|
@ -673,9 +676,12 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
} else {
|
||||
targets.erase(best_target);
|
||||
}
|
||||
|
||||
AI_LOG("Moving to " + str_cast(its.first->first.x+1) + "," + str_cast(its.first->first.y+1));
|
||||
|
||||
return std::pair<location,location>(its.first->second,its.first->first);
|
||||
} else {
|
||||
AI_LOG("dangerous!");
|
||||
is_dangerous = true;
|
||||
}
|
||||
}
|
||||
|
@ -685,7 +691,7 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
}
|
||||
|
||||
if(best != units_.end()) {
|
||||
std::cerr << "Could not make good move, staying still\n";
|
||||
AI_LOG("Could not make good move, staying still");
|
||||
|
||||
//this sounds like the road ahead might be dangerous, and that's why we don't advance.
|
||||
//create this as a target, attempting to rally units around
|
||||
|
@ -693,7 +699,7 @@ std::pair<gamemap::location,gamemap::location> ai::choose_move(std::vector<targe
|
|||
return std::pair<location,location>(best->first,best->first);
|
||||
}
|
||||
|
||||
std::cerr << "Could not find anywhere to move!\n";
|
||||
AI_LOG("Could not find anywhere to move!");
|
||||
return std::pair<location,location>();
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ void read_game_cfg(preproc_map& defines, std::vector<line_source>& line_src, con
|
|||
if(defines.size() < 4) {
|
||||
bool is_valid = true;
|
||||
std::stringstream str;
|
||||
str << "-v" << game_config::version;
|
||||
for(preproc_map::const_iterator i = defines.begin(); i != defines.end(); ++i) {
|
||||
if(i->second.value != "" || i->second.arguments.empty() == false) {
|
||||
is_valid = false;
|
||||
|
|
|
@ -1052,8 +1052,6 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
|
|||
std::cerr << "placed castles\n";
|
||||
std::cerr << (SDL_GetTicks() - ticks) << "\n"; ticks = SDL_GetTicks();
|
||||
|
||||
|
||||
|
||||
if(nvillages > 0) {
|
||||
const config* const naming = cfg.child("village_naming");
|
||||
config naming_cfg;
|
||||
|
@ -1070,16 +1068,20 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
|
|||
//alternate between incrementing the x and y value. When they are high enough
|
||||
//to equal or exceed the tiles_per_village, then we have them to the value
|
||||
//we want them at.
|
||||
size_t* village_ptr = &village_x;
|
||||
while(village_x*village_y < tiles_per_village) {
|
||||
(*village_ptr)++;
|
||||
village_ptr = (village_ptr == &village_x ? &village_y : &village_x);
|
||||
if(village_x < village_y) {
|
||||
++village_x;
|
||||
} else {
|
||||
++village_y;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> used_names;
|
||||
|
||||
for(size_t vx = 0; vx < width; vx += village_x) {
|
||||
std::cerr << "village at " << vx << "\n";
|
||||
for(size_t vy = rand()%village_y; vy < height; vy += village_y) {
|
||||
|
||||
const size_t add_x = rand()%3;
|
||||
const size_t add_y = rand()%3;
|
||||
const size_t x = (vx + add_x) - 1;
|
||||
|
|
|
@ -459,6 +459,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
|
|||
calculate_healing(gui,status,map,units,player_number,teams);
|
||||
}
|
||||
|
||||
team_it->set_time_of_day(status.get_time_of_day());
|
||||
|
||||
gui.set_playing_team(size_t(player_number-1));
|
||||
|
||||
clear_shroud(gui,status,map,gameinfo,units,teams,player_number-1);
|
||||
|
|
102
src/team.cpp
102
src/team.cpp
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include "game_config.hpp"
|
||||
#include "gamestatus.hpp"
|
||||
#include "network.hpp"
|
||||
#include "replay.hpp"
|
||||
#include "team.hpp"
|
||||
|
@ -47,6 +48,31 @@ void team::target::write(config& cfg) const
|
|||
|
||||
team::team_info::team_info(const config& cfg)
|
||||
{
|
||||
//parse the ai parameters. AI parameters appear in [ai] tags. There may be multiple [ai] tags, which are
|
||||
//appended onto each other. If an [ai] tag has a 'time_of_day' attribute, it is only active for that time
|
||||
//of the day, and so we place it as part of a special map that gets calculated in team::new_turn
|
||||
const config::child_list& ai_parameters = cfg.get_children("ai");
|
||||
for(config::child_list::const_iterator aiparam = ai_parameters.begin(); aiparam != ai_parameters.end(); ++aiparam) {
|
||||
|
||||
const config& parm = **aiparam;
|
||||
std::cerr << "parsing aiparam: '" << parm.write() << "'\n";
|
||||
const std::string& tod = parm["time_of_day"];
|
||||
if(tod == "") {
|
||||
std::cerr << "appending to params\n";
|
||||
ai_params.append(parm);
|
||||
} else {
|
||||
const std::vector<std::string>& tods = config::split(tod);
|
||||
for(std::vector<std::string>::const_iterator i = tods.begin(); i != tods.end(); ++i) {
|
||||
std::cerr << "appending to '" << *i << "'\n";
|
||||
ai_params_tod[*i].append(parm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(string_map::const_iterator s = cfg.values.begin(); s != cfg.values.end(); ++s) {
|
||||
ai_params[s->first] = s->second;
|
||||
}
|
||||
|
||||
gold = cfg["gold"];
|
||||
income = cfg["income"];
|
||||
name = cfg["name"];
|
||||
|
@ -62,18 +88,6 @@ team::team_info::team_info(const config& cfg)
|
|||
else
|
||||
income_per_village = atoi(village_income.c_str());
|
||||
|
||||
const std::string& aggression_val = cfg["aggression"];
|
||||
if(aggression_val.empty())
|
||||
aggression = 0.5;
|
||||
else
|
||||
aggression = atof(aggression_val.c_str());
|
||||
|
||||
const std::string& caution_val = cfg["caution"];
|
||||
if(caution_val.empty())
|
||||
caution = 0.25;
|
||||
else
|
||||
caution = atof(caution_val.c_str());
|
||||
|
||||
const std::string& enemies_list = cfg["enemy"];
|
||||
if(!enemies_list.empty()) {
|
||||
std::vector<std::string> venemies = config::split(enemies_list);
|
||||
|
@ -94,27 +108,40 @@ team::team_info::team_info(const config& cfg)
|
|||
|
||||
ai_algorithm = cfg["ai_algorithm"];
|
||||
|
||||
|
||||
const config::child_list& ai_parameters = cfg.get_children("ai");
|
||||
for(config::child_list::const_iterator aiparam = ai_parameters.begin(); aiparam != ai_parameters.end(); ++aiparam) {
|
||||
ai_params.append(**aiparam);
|
||||
if(ai_algorithm.empty()) {
|
||||
ai_algorithm = ai_params["ai_algorithm"];
|
||||
}
|
||||
|
||||
std::string scouts_val = cfg["villages_per_scout"];
|
||||
|
||||
if(scouts_val.empty()) {
|
||||
scouts_val = ai_params["villages_per_scout"];
|
||||
}
|
||||
|
||||
const std::string& scouts_val = cfg["villages_per_scout"];
|
||||
if(scouts_val.empty()) {
|
||||
villages_per_scout = 4;
|
||||
} else {
|
||||
villages_per_scout = atoi(scouts_val.c_str());
|
||||
}
|
||||
|
||||
const std::string& leader_val = cfg["leader_value"];
|
||||
std::string leader_val = cfg["leader_value"];
|
||||
|
||||
if(leader_val.empty()) {
|
||||
leader_val = ai_params["leader_value"];
|
||||
}
|
||||
|
||||
if(leader_val.empty()) {
|
||||
leader_value = 3.0;
|
||||
} else {
|
||||
leader_value = atof(leader_val.c_str());
|
||||
}
|
||||
|
||||
const std::string& village_val = cfg["village_value"];
|
||||
std::string village_val = cfg["village_value"];
|
||||
|
||||
if(village_val.empty()) {
|
||||
village_val = ai_params["village_value"];
|
||||
}
|
||||
|
||||
if(village_val.empty()) {
|
||||
village_value = 1.0;
|
||||
} else {
|
||||
|
@ -126,7 +153,12 @@ team::team_info::team_info(const config& cfg)
|
|||
can_recruit.insert(*i);
|
||||
}
|
||||
|
||||
recruitment_pattern = config::split(cfg["recruitment_pattern"]);
|
||||
std::string recruit_pattern = cfg["recruitment_pattern"];
|
||||
if(recruit_pattern.empty()) {
|
||||
recruit_pattern = ai_params["recruitment_pattern"];
|
||||
}
|
||||
|
||||
recruitment_pattern = config::split(recruit_pattern);
|
||||
|
||||
//default recruitment pattern is to buy 2 fighters for every 1 archer
|
||||
if(recruitment_pattern.empty()) {
|
||||
|
@ -136,8 +168,12 @@ team::team_info::team_info(const config& cfg)
|
|||
}
|
||||
|
||||
//additional targets
|
||||
for(config::const_child_itors tgts = cfg.child_range("target");
|
||||
tgts.first != tgts.second; ++tgts.first) {
|
||||
config::const_child_itors tgts;
|
||||
for(tgts = cfg.child_range("target"); tgts.first != tgts.second; ++tgts.first) {
|
||||
targets.push_back(target(**tgts.first));
|
||||
}
|
||||
|
||||
for(tgts = ai_params.child_range("target"); tgts.first != tgts.second; ++tgts.first) {
|
||||
targets.push_back(target(**tgts.first));
|
||||
}
|
||||
|
||||
|
@ -153,6 +189,11 @@ team::team_info::team_info(const config& cfg)
|
|||
|
||||
void team::team_info::write(config& cfg) const
|
||||
{
|
||||
cfg.add_child("ai",ai_params);
|
||||
for(std::map<std::string,config>::const_iterator ai = ai_params_tod.begin(); ai != ai_params_tod.end(); ++ai) {
|
||||
cfg.add_child("ai",ai->second)["time_of_day"] = ai->first;
|
||||
}
|
||||
|
||||
cfg["gold"] = gold;
|
||||
cfg["income"] = income;
|
||||
cfg["name"] = name;
|
||||
|
@ -163,9 +204,6 @@ void team::team_info::write(config& cfg) const
|
|||
sprintf(buf,"%d",income_per_village);
|
||||
cfg["village_gold"] = buf;
|
||||
|
||||
sprintf(buf,"%f",aggression);
|
||||
cfg["aggression"] = buf;
|
||||
|
||||
std::stringstream enemies_str;
|
||||
for(std::vector<int>::const_iterator en = enemies.begin(); en != enemies.end(); ++en) {
|
||||
enemies_str << *en;
|
||||
|
@ -304,6 +342,14 @@ void team::new_turn()
|
|||
gold_ += income();
|
||||
}
|
||||
|
||||
void team::set_time_of_day(const time_of_day& tod)
|
||||
{
|
||||
aiparams_ = info_.ai_params;
|
||||
aiparams_.append(info_.ai_params_tod[tod.id]);
|
||||
|
||||
std::cerr << "for time of day '" << tod.id << "' set ai_params to: ---\n" << aiparams_.write() << "\n---\n";
|
||||
}
|
||||
|
||||
void team::spend_gold(int amount)
|
||||
{
|
||||
gold_ -= amount;
|
||||
|
@ -360,12 +406,12 @@ bool team::is_enemy(int n) const
|
|||
|
||||
double team::aggression() const
|
||||
{
|
||||
return info_.aggression;
|
||||
return lexical_cast_default<double>(ai_parameters()["aggression"],0.5);
|
||||
}
|
||||
|
||||
double team::caution() const
|
||||
{
|
||||
return info_.caution;
|
||||
return lexical_cast_default<double>(ai_parameters()["caution"],0.25);
|
||||
}
|
||||
|
||||
bool team::is_human() const
|
||||
|
@ -415,7 +461,7 @@ const std::string& team::ai_algorithm() const
|
|||
|
||||
const config& team::ai_parameters() const
|
||||
{
|
||||
return info_.ai_params;
|
||||
return aiparams_;
|
||||
}
|
||||
|
||||
void team::make_network()
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#include "map.hpp"
|
||||
#include "unit.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
|
@ -66,7 +65,6 @@ public:
|
|||
int income_per_village;
|
||||
std::set<std::string> can_recruit;
|
||||
std::vector<std::string> recruitment_pattern;
|
||||
double aggression, caution;
|
||||
std::vector<int> enemies;
|
||||
std::string team_name;
|
||||
|
||||
|
@ -77,6 +75,8 @@ public:
|
|||
std::string ai_algorithm;
|
||||
config ai_params;
|
||||
|
||||
std::map<std::string,config> ai_params_tod;
|
||||
|
||||
int villages_per_scout;
|
||||
double leader_value, village_value;
|
||||
|
||||
|
@ -100,6 +100,7 @@ public:
|
|||
int gold() const;
|
||||
int income() const;
|
||||
void new_turn();
|
||||
void set_time_of_day(const struct time_of_day& tod);
|
||||
void get_shared_maps();
|
||||
void spend_gold(int amount);
|
||||
void set_income(int amount);
|
||||
|
@ -173,6 +174,8 @@ private:
|
|||
bool auto_shroud_updates_;
|
||||
|
||||
team_info info_;
|
||||
|
||||
config aiparams_;
|
||||
};
|
||||
|
||||
struct teams_manager {
|
||||
|
|
Loading…
Add table
Reference in a new issue