fix some tournament state bugs
This commit is contained in:
+40
-18
@@ -122,7 +122,7 @@ Tournament::Match::Match(
|
|||||||
if (this->preceding_a->round_num != this->preceding_b->round_num) {
|
if (this->preceding_a->round_num != this->preceding_b->round_num) {
|
||||||
throw logic_error("preceding matches have different round numbers");
|
throw logic_error("preceding matches have different round numbers");
|
||||||
}
|
}
|
||||||
this->round_num = this->preceding_a->round_num;
|
this->round_num = this->preceding_a->round_num + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tournament::Match::Match(
|
Tournament::Match::Match(
|
||||||
@@ -136,15 +136,17 @@ Tournament::Match::Match(
|
|||||||
|
|
||||||
string Tournament::Match::str() const {
|
string Tournament::Match::str() const {
|
||||||
string winner_str = this->winner_team ? this->winner_team->str() : "(none)";
|
string winner_str = this->winner_team ? this->winner_team->str() : "(none)";
|
||||||
return "[Match winner=" + winner_str + "]";
|
return string_printf("[Match round=%zu winner=%s]", this->round_num, winner_str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tournament::Match::resolve_if_no_players() {
|
bool Tournament::Match::resolve_if_no_players() {
|
||||||
|
if (this->winner_team) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// If both matches before this one are resolved and neither winner team has
|
// If both matches before this one are resolved and neither winner team has
|
||||||
// any humans on it, skip this match entirely and just make one team advance
|
// any humans on it, skip this match entirely and just make one team advance
|
||||||
// arbitrarily
|
// arbitrarily
|
||||||
if (!this->winner_team &&
|
if (this->preceding_a->winner_team &&
|
||||||
this->preceding_a->winner_team &&
|
|
||||||
this->preceding_b->winner_team &&
|
this->preceding_b->winner_team &&
|
||||||
this->preceding_a->winner_team->player_serial_numbers.empty() &&
|
this->preceding_a->winner_team->player_serial_numbers.empty() &&
|
||||||
this->preceding_b->winner_team->player_serial_numbers.empty()) {
|
this->preceding_b->winner_team->player_serial_numbers.empty()) {
|
||||||
@@ -156,7 +158,7 @@ bool Tournament::Match::resolve_if_no_players() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tournament::Match::resolve_following_matches() {
|
void Tournament::Match::on_winner_team_set() {
|
||||||
auto tournament = this->tournament.lock();
|
auto tournament = this->tournament.lock();
|
||||||
if (!tournament) {
|
if (!tournament) {
|
||||||
return;
|
return;
|
||||||
@@ -164,16 +166,10 @@ void Tournament::Match::resolve_following_matches() {
|
|||||||
|
|
||||||
tournament->pending_matches.erase(this->shared_from_this());
|
tournament->pending_matches.erase(this->shared_from_this());
|
||||||
|
|
||||||
// Resolve all matches up the chain until we can't anymore (this
|
// Resolve the following match if possible (this skips CPU-only matches). If
|
||||||
// automatically skips CPU-only matches)
|
// the following match can't be resolved, mark it pending.
|
||||||
auto following = this->following.lock();
|
auto following = this->following.lock();
|
||||||
while (following && following->resolve_if_no_players()) {
|
if (following && !following->resolve_if_no_players()) {
|
||||||
tournament->pending_matches.erase(following);
|
|
||||||
following = following->following.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's a following match that wasn't resolved, mark it pending
|
|
||||||
if (following) {
|
|
||||||
tournament->pending_matches.emplace(following);
|
tournament->pending_matches.emplace(following);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +197,7 @@ void Tournament::Match::set_winner_team(shared_ptr<Team> team) {
|
|||||||
this->preceding_a->winner_team->is_active = false;
|
this->preceding_a->winner_team->is_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->resolve_following_matches();
|
this->on_winner_team_set();
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Tournament::Team> Tournament::Match::opponent_team_for_team(
|
shared_ptr<Tournament::Team> Tournament::Match::opponent_team_for_team(
|
||||||
@@ -373,7 +369,7 @@ void Tournament::start() {
|
|||||||
|
|
||||||
// Resolve all possible CPU-only matches
|
// Resolve all possible CPU-only matches
|
||||||
for (auto m : this->zero_round_matches) {
|
for (auto m : this->zero_round_matches) {
|
||||||
m->resolve_following_matches();
|
m->on_winner_team_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +380,7 @@ void Tournament::print_bracket(FILE* stream) const {
|
|||||||
fputc(' ', stream);
|
fputc(' ', stream);
|
||||||
}
|
}
|
||||||
string match_str = m->str();
|
string match_str = m->str();
|
||||||
fprintf(stream, "%s\n", match_str.c_str());
|
fprintf(stream, "%s%s\n", match_str.c_str(), this->pending_matches.count(m) ? " (PENDING)" : "");
|
||||||
if (m->preceding_a) {
|
if (m->preceding_a) {
|
||||||
print_match(m->preceding_a, indent_level + 1);
|
print_match(m->preceding_a, indent_level + 1);
|
||||||
}
|
}
|
||||||
@@ -392,7 +388,33 @@ void Tournament::print_bracket(FILE* stream) const {
|
|||||||
print_match(m->preceding_b, indent_level + 1);
|
print_match(m->preceding_b, indent_level + 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
print_match(this->final_match, 0);
|
fprintf(stream, "Tournament %02hhX: %s\n", this->number, this->name.c_str());
|
||||||
|
string map_name = this->map->map.name;
|
||||||
|
fprintf(stream, " Map: %08" PRIX32 " (%s)\n", this->map->map.map_number.load(), map_name.c_str());
|
||||||
|
string rules_str = this->rules.str();
|
||||||
|
fprintf(stream, " Rules: %s\n", rules_str.c_str());
|
||||||
|
fprintf(stream, " Structure: %s, %zu entries\n", this->is_2v2 ? "2v2" : "1v1", this->num_teams);
|
||||||
|
switch (this->current_state) {
|
||||||
|
case State::REGISTRATION:
|
||||||
|
fprintf(stream, " State: REGISTRATION\n");
|
||||||
|
break;
|
||||||
|
case State::IN_PROGRESS:
|
||||||
|
fprintf(stream, " State: IN_PROGRESS\n");
|
||||||
|
break;
|
||||||
|
case State::COMPLETE:
|
||||||
|
fprintf(stream, " State: COMPLETE\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stream, " State: UNKNOWN\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stream, " Standings:\n");
|
||||||
|
print_match(this->final_match, 2);
|
||||||
|
fprintf(stream, " Pending matches:\n");
|
||||||
|
for (const auto& match : this->pending_matches) {
|
||||||
|
string match_str = match->str();
|
||||||
|
fprintf(stream, " %s\n", match_str.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
std::string str() const;
|
std::string str() const;
|
||||||
|
|
||||||
bool resolve_if_no_players();
|
bool resolve_if_no_players();
|
||||||
void resolve_following_matches();
|
void on_winner_team_set();
|
||||||
void set_winner_team(std::shared_ptr<Team> team);
|
void set_winner_team(std::shared_ptr<Team> team);
|
||||||
std::shared_ptr<Team> opponent_team_for_team(std::shared_ptr<Team> team) const;
|
std::shared_ptr<Team> opponent_team_for_team(std::shared_ptr<Team> team) const;
|
||||||
};
|
};
|
||||||
@@ -108,7 +108,6 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
|
|
||||||
void print_bracket(FILE* stream) const;
|
void print_bracket(FILE* stream) const;
|
||||||
void print_bracket_stderr() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrefixedLogger log;
|
PrefixedLogger log;
|
||||||
|
|||||||
@@ -1051,6 +1051,10 @@ static void on_ep3_server_data_request(shared_ptr<ServerState> s, shared_ptr<Cli
|
|||||||
if (winner_team_id == -1) {
|
if (winner_team_id == -1) {
|
||||||
throw runtime_error("match concluded, but winner team not specified");
|
throw runtime_error("match concluded, but winner team not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto tourn = l->tournament_match->tournament.lock();
|
||||||
|
tourn->print_bracket(stderr);
|
||||||
|
|
||||||
if (winner_team_id == 0) {
|
if (winner_team_id == 0) {
|
||||||
l->tournament_match->set_winner_team(l->tournament_match->preceding_a->winner_team);
|
l->tournament_match->set_winner_team(l->tournament_match->preceding_a->winner_team);
|
||||||
} else if (winner_team_id == 1) {
|
} else if (winner_team_id == 1) {
|
||||||
@@ -1060,7 +1064,7 @@ static void on_ep3_server_data_request(shared_ptr<ServerState> s, shared_ptr<Cli
|
|||||||
}
|
}
|
||||||
send_ep3_tournament_match_result(l, l->tournament_match);
|
send_ep3_tournament_match_result(l, l->tournament_match);
|
||||||
|
|
||||||
auto tourn = l->tournament_match->tournament.lock();
|
tourn->print_bracket(stderr);
|
||||||
if (tourn && (tourn->get_state() == Episode3::Tournament::State::COMPLETE)) {
|
if (tourn && (tourn->get_state() == Episode3::Tournament::State::COMPLETE)) {
|
||||||
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
s->ep3_tournament_index->delete_tournament(tourn->get_number());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,8 @@ Server commands:\n\
|
|||||||
dice-boost=ON/OFF: Enable/disable dice boost\n\
|
dice-boost=ON/OFF: Enable/disable dice boost\n\
|
||||||
start-tournament \"Tournament Name\"\n\
|
start-tournament \"Tournament Name\"\n\
|
||||||
End registration for a tournament and allow matches to begin.\n\
|
End registration for a tournament and allow matches to begin.\n\
|
||||||
|
tournament-state \"Tournament Name\"\n\
|
||||||
|
Print the current state of a tournament.\n\
|
||||||
\n\
|
\n\
|
||||||
Proxy commands (these will only work when exactly one client is connected):\n\
|
Proxy commands (these will only work when exactly one client is connected):\n\
|
||||||
sc <data>\n\
|
sc <data>\n\
|
||||||
@@ -415,6 +417,15 @@ Proxy commands (these will only work when exactly one client is connected):\n\
|
|||||||
fprintf(stderr, "no such tournament exists\n");
|
fprintf(stderr, "no such tournament exists\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (command_name == "tournament-status") {
|
||||||
|
string name = get_quoted_string(command_args);
|
||||||
|
auto tourn = this->state->ep3_tournament_index->get_tournament(name);
|
||||||
|
if (tourn) {
|
||||||
|
tourn->print_bracket(stderr);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "no such tournament exists\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// PROXY COMMANDS
|
// PROXY COMMANDS
|
||||||
|
|||||||
Reference in New Issue
Block a user