From 25d9880da4f6ff278957e60440af6ace421f6a0d Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Sun, 18 Jul 2021 19:11:06 -0700 Subject: [PATCH] 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. --- src/cup.c | 52 +++++++------------------------ src/cup.h | 3 ++ src/league.c | 5 +-- src/start_end.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ src/start_end.h | 3 ++ 5 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/cup.c b/src/cup.c index 01c729b4..66492d78 100644 --- a/src/cup.c +++ b/src/cup.c @@ -154,9 +154,13 @@ cup_reset(Cup *cup) if(cup->teams->len > 0) { - /* Save this season's results. */ - GPtrArray *sorted_teams = cup_get_teams_sorted(cup); - g_ptr_array_add(cup->history, sorted_teams); + /* Save this season's results. If there are no fixtures then + * it means we have generated this cups results, so we have + * 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); 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 * generated. */ -static gboolean +gboolean cup_choose_team_should_generate(const CupChooseTeam *ct) { 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; 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? */ cup_teams_sorted = (cup == cup_temp) ? @@ -1431,6 +1398,9 @@ query_cup_hidden(const Cup *cup) GPtrArray * 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); } diff --git a/src/cup.h b/src/cup.h index ecfc0608..96048457 100644 --- a/src/cup.h +++ b/src/cup.h @@ -105,6 +105,9 @@ cup_get_round_reached(const Team *tm, const GArray *fixtures); gboolean query_cup_begins(const Cup *cup); +gboolean +cup_choose_team_should_generate(const CupChooseTeam *ct); + gint cup_choose_team_compute_start_idx(const CupChooseTeam *ct); diff --git a/src/league.c b/src/league.c index 53aae66d..0a513cad 100644 --- a/src/league.c +++ b/src/league.c @@ -474,7 +474,8 @@ country_get_league_sid(Country *country, const gchar *sid) 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. */ League * @@ -487,7 +488,7 @@ bygfoot_get_league_sid(const gchar *sid) if (league) return league; } - return NULL; + return country_get_league_sid(&country, sid); } /** Remove the team with the specified id from the teams diff --git a/src/start_end.c b/src/start_end.c index 0823f132..7ca9873a 100644 --- a/src/start_end.c +++ b/src/start_end.c @@ -92,6 +92,8 @@ start_new_game(void) start_load_other_countries(); + start_generate_cup_history(); + start_new_season(); } @@ -132,6 +134,85 @@ start_load_other_countries() 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. */ void start_new_season(void) diff --git a/src/start_end.h b/src/start_end.h index efe0f31b..5e53d59a 100644 --- a/src/start_end.h +++ b/src/start_end.h @@ -31,6 +31,9 @@ void start_load_other_countries(void); +void +start_generate_cup_history(void); + void start_new_game(void);