Skip to content

Commit

Permalink
refactor check_victory, don't use [side] no_leader attribute
Browse files Browse the repository at this point in the history
1. sides without leaders aren't defeated if
"fight_on_without_leader = true". don't use no_leader
for this purpose anymore.
2. refactor to use a std::set instead of std::vector,
and some related improvements, for what was formerly
the "seen_leaders" data structure
  • Loading branch information
cbeck88 committed Apr 9, 2014
1 parent 04eaedf commit 69e5b15
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/ai/testing.cpp
Expand Up @@ -76,10 +76,10 @@ void ai_testing::log_draw()
recorder.add_log_data("ai_log","result","draw");
}

void ai_testing::log_victory(std::vector<unsigned int> winners)
void ai_testing::log_victory(std::set<unsigned int> winners)
{
recorder.add_log_data("ai_log","result","victory");
for(std::vector<unsigned int>::const_iterator w = winners.begin(); w != winners.end(); ++w) {
for(std::set<unsigned int>::const_iterator w = winners.begin(); w != winners.end(); ++w) {
LOG_AI_TESTING << "WINNER: "<< *w <<std::endl;
recorder.add_log_data("ai_log","winner",str_cast(*w));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ai/testing.hpp
Expand Up @@ -47,7 +47,7 @@ class ai_testing{
* Log in case of victory
* teams vector of winner teams
*/
static void log_victory( std::vector<unsigned int> teams );
static void log_victory( std::set<unsigned int> teams );


/*
Expand Down
24 changes: 14 additions & 10 deletions src/play_controller.cpp
Expand Up @@ -1368,13 +1368,16 @@ void play_controller::check_victory()
{
check_end_level();

std::vector<unsigned> seen_leaders;
std::set<unsigned> not_defeated;
for (unit_map::const_iterator i = units_.begin(),
i_end = units_.end(); i != i_end; ++i)
{
if (i->can_recruit()) {
DBG_NG << "seen leader for side " << i->side() << "\n";
seen_leaders.push_back(i->side());
not_defeated.insert(i->side());
} else if (teams_[i->side()-1].fight_on_without_leader()) {
DBG_NG << "side doesn't require leader " << i->side() << "\n";
not_defeated.insert(i->side());
}
}

Expand All @@ -1383,25 +1386,26 @@ void play_controller::check_victory()
for (std::vector<team>::iterator tm_beg = teams_.begin(), tm = tm_beg,
tm_end = teams_.end(); tm != tm_end; ++tm)
{
if (std::find(seen_leaders.begin(), seen_leaders.end(), tm - tm_beg + 1) == seen_leaders.end()) {
if (not_defeated.find(tm - tm_beg + 1) == not_defeated.end()) {
tm->clear_villages();
// invalidate_all() is overkill and expensive but this code is
// run rarely so do it the expensive way.
gui_->invalidate_all();

if (!tm->no_leader() && remove_from_carryover_on_leaders_loss_) {
if (!tm->fight_on_without_leader() && remove_from_carryover_on_leaders_loss_) {
tm->set_lost();
}
}
}

bool found_player = false;

for (size_t n = 0; n != seen_leaders.size(); ++n) {
size_t side = seen_leaders[n] - 1;
for (std::set<unsigned>::iterator n = not_defeated.begin(); n != not_defeated.end(); ++n) {
size_t side = *n - 1;

for (size_t m = n +1 ; m != seen_leaders.size(); ++m) {
if (teams_[side].is_enemy(seen_leaders[m])) {
std::set<unsigned>::iterator m(n);
for (++m; m != not_defeated.end(); ++m) {
if (teams_[side].is_enemy(*m)) {
return;
}
}
Expand All @@ -1427,13 +1431,13 @@ void play_controller::check_victory()

if (non_interactive()) {
std::cout << "winner: ";
BOOST_FOREACH(unsigned l, seen_leaders) {
BOOST_FOREACH(unsigned l, not_defeated) {
std::string ai = ai::manager::get_active_ai_identifier_for_side(l);
if (ai.empty()) ai = "default ai";
std::cout << l << " (using " << ai << ") ";
}
std::cout << '\n';
ai_testing::log_victory(seen_leaders);
ai_testing::log_victory(not_defeated);
}

DBG_NG << "throwing end level exception...\n";
Expand Down

0 comments on commit 69e5b15

Please sign in to comment.