Generate a 'pre-history' for cups

We know generate cup results for each cup before starting the game.
This allows cups to select last year's winner without having to
special case cup selection for the first season.
This commit is contained in:
Tom Stellard 2021-07-18 19:11:06 -07:00 committed by Tom Stellard
parent 313b5bd07b
commit 25d9880da4
5 changed files with 101 additions and 43 deletions

View File

@ -154,9 +154,13 @@ cup_reset(Cup *cup)
if(cup->teams->len > 0) if(cup->teams->len > 0)
{ {
/* Save this season's results. */ /* Save this season's results. If there are no fixtures then
GPtrArray *sorted_teams = cup_get_teams_sorted(cup); * it means we have generated this cups results, so we have
g_ptr_array_add(cup->history, sorted_teams); * already saved the history. */
if (cup->fixtures->len > 0) {
GPtrArray *sorted_teams = cup_get_teams_sorted(cup);
g_ptr_array_add(cup->history, sorted_teams);
}
g_ptr_array_free(cup->teams, TRUE); g_ptr_array_free(cup->teams, TRUE);
cup->teams = g_ptr_array_new(); cup->teams = g_ptr_array_new();
} }
@ -201,7 +205,7 @@ query_cup_choose_team_is_league(const gchar *sid)
/** @return TRUE if the team(s) referenced by \p sid need to be /** @return TRUE if the team(s) referenced by \p sid need to be
* generated. * generated.
*/ */
static gboolean gboolean
cup_choose_team_should_generate(const CupChooseTeam *ct) cup_choose_team_should_generate(const CupChooseTeam *ct)
{ {
if (g_str_has_prefix(ct->sid, "LEAGUE") || g_str_has_prefix(ct->sid, "CUP")) if (g_str_has_prefix(ct->sid, "LEAGUE") || g_str_has_prefix(ct->sid, "CUP"))
@ -396,43 +400,6 @@ cup_load_choose_team_from_cup(Cup *cup, const Cup *cup_temp, GPtrArray *teams, c
number_of_teams = 0; number_of_teams = 0;
cup_teams_sorted = NULL; cup_teams_sorted = NULL;
if(season == 1 && week == 1 && cup->add_week == 0)
{
if(lig(0).teams->len < ct->number_of_teams)
main_exit_program(EXIT_CHOOSE_TEAM_ERROR,
"cup_load_choose_team_from_cup: not enough teams in league 0 for chooseteam %s (%d; required: %d) in cup %s\n",
ct->sid, lig(0).teams->len,
ct->number_of_teams, cup->name);
gint permutation[lig(0).teams->len];
math_generate_permutation(permutation, 0, lig(0).teams->len - 1);
for(i = ct->start_idx - 1; i <= ct->end_idx - 1; i++)
{
gint team_idx = permutation[i - ct->start_idx + 1];
Team *team = g_ptr_array_index(lig(0).teams, team_idx);
if(ct->skip_group_check ||
!query_team_is_in_cups(team, cup->group))
{
g_ptr_array_add(teams, team);
number_of_teams++;
}
if(number_of_teams == ct->number_of_teams)
break;
}
if(number_of_teams != ct->number_of_teams) {
if (ct->next)
return cup_load_choose_team(cup, teams, ct->next);
main_exit_program(EXIT_CHOOSE_TEAM_ERROR,
"cup_load_choose_team_from_cup (2): not enough teams found in league 0 for chooseteam %s (%d; required: %d) in cup %s (group %d)\n",
ct->sid, number_of_teams,
ct->number_of_teams, cup->name, cup->group);
}
}
else
{ {
/* Self-referential cup or no? */ /* Self-referential cup or no? */
cup_teams_sorted = (cup == cup_temp) ? cup_teams_sorted = (cup == cup_temp) ?
@ -1431,6 +1398,9 @@ query_cup_hidden(const Cup *cup)
GPtrArray * GPtrArray *
cup_get_last_season_results(const Cup *cup) cup_get_last_season_results(const Cup *cup)
{ {
gint i, j, k;
GPtrArray *history;
return g_ptr_array_index(cup->history, cup->history->len - 1); return g_ptr_array_index(cup->history, cup->history->len - 1);
} }

View File

@ -105,6 +105,9 @@ cup_get_round_reached(const Team *tm, const GArray *fixtures);
gboolean gboolean
query_cup_begins(const Cup *cup); query_cup_begins(const Cup *cup);
gboolean
cup_choose_team_should_generate(const CupChooseTeam *ct);
gint gint
cup_choose_team_compute_start_idx(const CupChooseTeam *ct); cup_choose_team_compute_start_idx(const CupChooseTeam *ct);

View File

@ -474,7 +474,8 @@ country_get_league_sid(Country *country, const gchar *sid)
return NULL; return NULL;
} }
/** Get the leauge with \p sid from the list of all countries. /** Get the leauge with \p sid from the list of all countries (including the
* users' country).
* @returns A pointer to a League object or NULL if the cup is not found. * @returns A pointer to a League object or NULL if the cup is not found.
*/ */
League * League *
@ -487,7 +488,7 @@ bygfoot_get_league_sid(const gchar *sid)
if (league) if (league)
return league; return league;
} }
return NULL; return country_get_league_sid(&country, sid);
} }
/** Remove the team with the specified id from the teams /** Remove the team with the specified id from the teams

View File

@ -92,6 +92,8 @@ start_new_game(void)
start_load_other_countries(); start_load_other_countries();
start_generate_cup_history();
start_new_season(); start_new_season();
} }
@ -132,6 +134,85 @@ start_load_other_countries()
g_ptr_array_foreach(country_files, load_country, country_list); g_ptr_array_foreach(country_files, load_country, country_list);
} }
/** Generate cup results so that in the first season we can select the cup
* winners using the same method we do for the later seasons.
*
*/
void
start_generate_cup_history()
{
gint i, j, k, m, t;
gint number_of_teams;
/* First pass: Collect all the teams that qualify for a cup from a league. */
for (i = country.cups->len - 1; i >=0; i--) {
Cup *cup = &g_array_index(country.cups, Cup, i);
for(j = cup->rounds->len - 1; j >= 0; j--) {
CupRound *round = &g_array_index(cup->rounds, CupRound, j);
for (k = 0; k < round->choose_teams->len; k++) {
gint start_idx, end_idx;
GPtrArray *teams = g_ptr_array_new();
CupChooseTeam *ct = &g_array_index(round->choose_teams, CupChooseTeam, k);
League *league = bygfoot_get_league_sid(ct->sid);
Cup *ct_cup;
gboolean update_clid = cup_choose_team_should_generate(ct);
if (!league)
continue;
for (t = 0; t < league->teams->len; t++) {
g_ptr_array_add(teams, g_ptr_array_index(league->teams, t));
}
number_of_teams = ct->number_of_teams == -1 ? teams->len : ct->number_of_teams;
t = 0;
start_idx = cup_choose_team_compute_start_idx(ct);
end_idx = cup_choose_team_compute_end_idx(ct, teams->len);
for (m = start_idx; m <= end_idx && m < teams->len && t < number_of_teams; m++) {
Team *team = g_ptr_array_index(teams, m);
if(!ct->skip_group_check && query_team_is_in_cups(team, cup->group))
continue;
g_ptr_array_add(cup->teams, team);
if (update_clid)
team->clid = cup->id;
t++;
}
g_ptr_array_free(teams, TRUE);
}
}
}
/* Second pass: Collect all the teams that qualify for a cup from another cup. */
for (i = country.cups->len - 1; i >=0; i--) {
Cup *cup = &g_array_index(country.cups, Cup, i);
for(j = cup->rounds->len - 1; j >= 0; j--) {
CupRound *round = &g_array_index(cup->rounds, CupRound, j);
for (k = 0; k < round->choose_teams->len; k++) {
gint start_idx, end_idx;
GPtrArray *teams = g_ptr_array_new();
CupChooseTeam *ct = &g_array_index(round->choose_teams, CupChooseTeam, k);
Cup *ct_cup = country_get_cup_sid(&country, ct->sid);
if (!ct_cup)
continue;
for (t = 0; t < ct_cup->teams->len; t++) {
g_ptr_array_add(teams, g_ptr_array_index(ct_cup->teams, t));
}
number_of_teams = ct->number_of_teams == -1 ? teams->len : ct->number_of_teams;
t = 0;
start_idx = cup_choose_team_compute_start_idx(ct);
end_idx = cup_choose_team_compute_end_idx(ct, teams->len);
for (m = start_idx; m <= end_idx && m < teams->len && t < number_of_teams; m++) {
Team *team = g_ptr_array_index(teams, m);
if(!ct->skip_group_check && query_team_is_in_cups(team, cup->group))
continue;
g_ptr_array_add(cup->teams, team);
t++;
}
g_ptr_array_free(teams, TRUE);
}
}
cup->teams = misc_randomise_g_pointer_array(cup->teams);
g_ptr_array_add(cup->history, misc_copy_ptr_array(cup->teams));
}
}
/** Make new fixtures, nullify things etc. */ /** Make new fixtures, nullify things etc. */
void void
start_new_season(void) start_new_season(void)

View File

@ -31,6 +31,9 @@
void void
start_load_other_countries(void); start_load_other_countries(void);
void
start_generate_cup_history(void);
void void
start_new_game(void); start_new_game(void);