Skip to content

Commit

Permalink
Generate a 'pre-history' for cups
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tstellar committed Jul 27, 2021
1 parent 313b5bd commit 25d9880
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 43 deletions.
52 changes: 11 additions & 41 deletions src/cup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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) ?
Expand Down Expand Up @@ -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);
}

Expand Down
3 changes: 3 additions & 0 deletions src/cup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 3 additions & 2 deletions src/league.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *
Expand All @@ -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
Expand Down
81 changes: 81 additions & 0 deletions src/start_end.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ start_new_game(void)

start_load_other_countries();

start_generate_cup_history();

start_new_season();
}

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions src/start_end.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
void
start_load_other_countries(void);

void
start_generate_cup_history(void);

void
start_new_game(void);

Expand Down

0 comments on commit 25d9880

Please sign in to comment.