From 79faa697e411aec54fa2764f82c1bf57c37f5a11 Mon Sep 17 00:00:00 2001 From: gyboth Date: Sun, 14 Dec 2008 10:37:10 +0000 Subject: [PATCH] Added custom round robin breaks to leagues and cups. --- src/cup.c | 1 + src/cup_struct.h | 2 + src/fixture.c | 21 ++++---- src/fixture.h | 6 ++- src/free.c | 47 ++++++++++------- src/free.h | 3 ++ src/league.c | 50 ++++++++++++++++++- src/league.h | 6 +++ src/league_struct.h | 2 +- src/treeview_helper.c | 9 ++-- src/xml_cup.c | 9 ++++ src/xml_league.c | 3 +- src/xml_loadsave_cup.c | 9 ++++ src/xml_loadsave_league.c | 6 ++- .../europe/cup_europe_champ_league.xml | 1 + 15 files changed, 136 insertions(+), 39 deletions(-) diff --git a/src/cup.c b/src/cup.c index c11d7e49..272bfac1 100644 --- a/src/cup.c +++ b/src/cup.c @@ -124,6 +124,7 @@ cup_round_new(void) new.round_robin_number_of_advance = 0; new.round_robin_number_of_best_advance = 0; new.round_robins = 2; + new.rr_breaks = g_array_new(FALSE, FALSE, sizeof(gint)); new.two_match_weeks[0] = g_array_new(FALSE, FALSE, sizeof(gint)); new.two_match_weeks[1] = g_array_new(FALSE, FALSE, sizeof(gint)); new.two_match_week = FALSE; diff --git a/src/cup_struct.h b/src/cup_struct.h index 79499b87..5a430f60 100644 --- a/src/cup_struct.h +++ b/src/cup_struct.h @@ -59,6 +59,8 @@ typedef struct gint round_robin_number_of_best_advance; /** How many matchdays there are in the round robin phase. */ gint round_robins; + /** Number of weeks between the parts of a round robin. */ + GArray *rr_breaks; /** Number of new teams participating in the cup round (ie. teams that get loaded and are not advancing from a previous round). */ diff --git a/src/fixture.c b/src/fixture.c index 16e2432f..b324a526 100644 --- a/src/fixture.c +++ b/src/fixture.c @@ -70,7 +70,8 @@ fixture_write_league_fixtures(League *league) /** Write fixtures for as many round robins as required by the maximum number of rrs given. */ for(i = 0; i < max_rr;) { - fixture_write_round_robin((gpointer)league, -1, misc_copy_ptr_array(teams), (i == max_rr - 1), -1); + fixture_write_round_robin((gpointer)league, -1, misc_copy_ptr_array(teams), + (i == max_rr - 1), -1, league->rr_breaks, i - 1); i += (i < max_rr - 1) ? 2 : 1; } @@ -442,7 +443,9 @@ fixture_write_cup_round_robin(Cup *cup, gint cup_round, GPtrArray *teams) fixture_write_round_robin((gpointer)cup, cup_round, misc_copy_ptr_array(teams_group[i]), (j == cupround->round_robins - 1), - (j == 0) ? -1 : g_array_index(cup->fixtures, Fixture, cup->fixtures->len - 1).week_number + cup->week_gap); + (j == 0) ? -1 : g_array_index(cup->fixtures, Fixture, cup->fixtures->len - 1).week_number + + g_array_index(cupround->rr_breaks, gint, j - 1), + cupround->rr_breaks, j - 1); j += (j < cupround->round_robins - 1) ? 2 : 1; } g_ptr_array_free(teams_group[i], TRUE); @@ -471,7 +474,9 @@ fixture_write_cup_round_robin(Cup *cup, gint cup_round, GPtrArray *teams) @param one_round Whether a team plays each other team twice or only once. */ void fixture_write_round_robin(gpointer league_cup, gint cup_round, - GPtrArray *teams, gboolean one_round, gint first_week) + GPtrArray *teams, gboolean one_round, + gint first_week, GArray *rr_breaks, + gint rr_break_idx) { #ifdef DEBUG printf("fixture_write_round_robin\n"); @@ -479,8 +484,7 @@ fixture_write_round_robin(gpointer league_cup, gint cup_round, gint i, j; gint week_gap, week_number, - week_round_number, clid, first_fixture, - rr_break; + week_round_number, clid, first_fixture; gboolean home_advantage; League *league = NULL; Cup *cup = NULL; @@ -500,10 +504,9 @@ fixture_write_round_robin(gpointer league_cup, gint cup_round, clid = league->id; first_week = (fixtures->len == 0) ? league->first_week : g_array_index(fixtures, Fixture, fixtures->len - 1).week_number + - league->rr_break; + g_array_index(rr_breaks, gint, rr_break_idx); week_gap = league->week_gap; home_advantage = TRUE; - rr_break = league->rr_break; } else { @@ -515,7 +518,6 @@ fixture_write_round_robin(gpointer league_cup, gint cup_round, two_match_weeks = g_array_index(cup->rounds, CupRound, cup_round).two_match_weeks; clid = cup->id; home_advantage = (!g_array_index(cup->rounds, CupRound, cup_round).neutral); - rr_break = week_gap; } first_fixture = fixtures->len; @@ -548,7 +550,8 @@ fixture_write_round_robin(gpointer league_cup, gint cup_round, if(!one_round) { /* second half of fixtures */ - week_number += rr_break; + week_number += g_array_index(rr_breaks, gint, rr_break_idx + 1); + for(i = 0; i < len - 1; i++) { if(i > 0 && !query_league_cup_matchday_in_two_match_week(two_match_weeks, diff --git a/src/fixture.h b/src/fixture.h index 678d4771..28cf85cb 100644 --- a/src/fixture.h +++ b/src/fixture.h @@ -50,8 +50,10 @@ void fixture_write_cup_round_robin(Cup *cup, gint cup_round, GPtrArray *teams); void -fixture_write_round_robin(gpointer league_cup, gint cup_round, GPtrArray *teams, - gboolean one_round, gint first_week); +fixture_write_round_robin(gpointer league_cup, gint cup_round, + GPtrArray *teams, gboolean one_round, + gint first_week, GArray *rr_breaks, + gint rr_break_idx); void fixture_write_round_robin_matchday(GArray *fixtures, gint cup_round, GPtrArray *teams, diff --git a/src/free.c b/src/free.c index 6e15d433..d5e9ffbe 100644 --- a/src/free.c +++ b/src/free.c @@ -396,6 +396,7 @@ free_league(League *league) free_new_tables(&league->new_tables); free_g_array(&league->fixtures); + free_g_array(&league->rr_breaks); free_g_array(&league->two_match_weeks[0]); free_g_array(&league->two_match_weeks[1]); @@ -614,7 +615,7 @@ free_cup(Cup *cup) printf("free_cup\n"); #endif - gint i, j; + gint i; free_gchar_ptr(cup->name); free_gchar_ptr(cup->short_name); @@ -622,23 +623,7 @@ free_cup(Cup *cup) free_gchar_ptr(cup->sid); for(i=0;irounds->len;i++) - { - free_g_array(&g_array_index(cup->rounds, CupRound, i).two_match_weeks[0]); - free_g_array(&g_array_index(cup->rounds, CupRound, i).two_match_weeks[1]); - - if(g_array_index(cup->rounds, CupRound, i).round_robin_number_of_groups > 0) - { - free_tables(&g_array_index(cup->rounds, CupRound, i).tables); - - for(j=0;jrounds, CupRound, i).choose_teams->len;j++) - free_cup_choose_team( - &g_array_index(g_array_index(cup->rounds, CupRound, i).choose_teams, CupChooseTeam, j)); - - free_g_array(&g_array_index(cup->rounds, CupRound, i).choose_teams); - free_teams_array(&g_array_index(cup->rounds, CupRound, i).teams, FALSE); - g_ptr_array_free(g_array_index(cup->rounds, CupRound, i).team_ptrs, TRUE); - } - } + free_cup_round(&g_array_index(cup->rounds, CupRound, i)); free_g_array(&cup->rounds); free_g_array(&cup->fixtures); @@ -649,6 +634,32 @@ free_cup(Cup *cup) free_gchar_array(&cup->properties); } +void +free_cup_round(CupRound *cup_round) +{ +#ifdef DEBUG + printf("free_cup_round\n"); +#endif + + gint j; + + free_g_array(&cup_round->two_match_weeks[0]); + free_g_array(&cup_round->two_match_weeks[1]); + + if(cup_round->round_robin_number_of_groups > 0) + { + free_tables(&cup_round->tables); + + for(j=0;jchoose_teams->len;j++) + free_cup_choose_team( + &g_array_index(cup_round->choose_teams, CupChooseTeam, j)); + + free_g_array(&cup_round->choose_teams); + free_teams_array(&cup_round->teams, FALSE); + g_ptr_array_free(cup_round->team_ptrs, TRUE); + } +} + /** Free the memory occupied by a CupChooseTeam. @param cup_choose_team The pointer to the team we free. diff --git a/src/free.h b/src/free.h index 647cd749..62138d46 100644 --- a/src/free.h +++ b/src/free.h @@ -152,4 +152,7 @@ free_news(gboolean reset); void free_newspaper(gboolean reset); +void +free_cup_round(CupRound *cup_round); + #endif diff --git a/src/league.c b/src/league.c index cfc9cb6b..833c6cfb 100644 --- a/src/league.c +++ b/src/league.c @@ -59,7 +59,6 @@ league_new(gboolean new_id) new.id = (new_id) ? league_id_new : -1; new.layer = -1; - new.rr_break = 1; new.average_talent = 0; @@ -76,6 +75,7 @@ league_new(gboolean new_id) new.new_tables = g_array_new(FALSE, FALSE, sizeof(NewTable)); new.tables = g_array_new(FALSE, FALSE, sizeof(Table)); new.properties = g_ptr_array_new(); + new.rr_breaks = g_array_new(FALSE, FALSE, sizeof(gint)); new.first_week = new.week_gap = 1; new.two_match_weeks[0] = g_array_new(FALSE, FALSE, sizeof(gint)); @@ -1051,3 +1051,51 @@ league_cup_get_properties(gint clid) league_from_clid(clid)->properties : cup_from_clid(clid)->properties; } + +/** Synchronise the number of league breaks with the number of + round robins in the league. */ +void +league_cup_adjust_rr_breaks(GArray *rr_breaks, gint round_robins, gint week_gap) +{ +#ifdef DEBUG + printf("league_cup_adjust_rr_breaks\n"); +#endif + + gint i; + gint default_break; + + /* Remove superfluous breaks. */ + for(i = rr_breaks->len - 1; i >= round_robins - 1; i--) + g_array_remove_index(rr_breaks, i); + + /* Add more breaks if necessary. */ + if(rr_breaks->len == 0) + default_break = week_gap; + else + default_break = g_array_index(rr_breaks, gint, rr_breaks->len - 1); + + for(i = rr_breaks->len; i < round_robins - 1; i++) + g_array_append_val(rr_breaks, default_break); +} + +/** Fill the breaks array from a comma separated string of integers. */ +void +league_cup_fill_rr_breaks(GArray *rr_breaks, const gchar *breaks) +{ +#ifdef DEBUG + printf("league_cup_fill_rr_breaks\n"); +#endif + + gint i = 0; + gchar **breaks_arr = g_strsplit(breaks, ",", 0); + gint new_break; + + while(breaks_arr[i] != NULL) + { + new_break = (gint)g_ascii_strtod(breaks_arr[i], NULL); + g_array_append_val(rr_breaks, new_break); + i++; + } + + g_strfreev(breaks_arr); +} diff --git a/src/league.h b/src/league.h index d626afc0..00b18aa8 100644 --- a/src/league.h +++ b/src/league.h @@ -154,4 +154,10 @@ league_cup_get_teams(gint clid); GPtrArray* league_cup_get_properties(gint clid); +void +league_cup_adjust_rr_breaks(GArray *rr_breaks, gint round_robins, gint week_gap); + +void +league_cup_fill_rr_breaks(GArray *rr_breaks, const gchar *breaks); + #endif diff --git a/src/league_struct.h b/src/league_struct.h index 5cae3b3e..29dc9c63 100644 --- a/src/league_struct.h +++ b/src/league_struct.h @@ -133,7 +133,7 @@ typedef struct small leagues with 10 teams or so. Default: 2. */ gint round_robins; /** Number of weeks between the parts of a round robin. */ - gint rr_break; + GArray *rr_breaks; /** Number of yellow cards until a player gets banned. Default 1000 (which means 'off', basically). */ gint yellow_red; diff --git a/src/treeview_helper.c b/src/treeview_helper.c index bd98e66e..16569fb3 100644 --- a/src/treeview_helper.c +++ b/src/treeview_helper.c @@ -388,11 +388,10 @@ treeview_helper_insert_icon(GtkTreeModel *ls, GtkTreeIter *iter, gint column_nr, #endif GdkPixbuf *symbol = treeview_helper_pixbuf_from_filename(icon_name); - if (GTK_IS_LIST_STORE (ls)){ - gtk_list_store_set(ls, iter, column_nr, symbol, -1); - } else if (GTK_IS_TREE_STORE(ls)){ - gtk_tree_store_set(ls, iter, column_nr, symbol, -1); - } + if (GTK_IS_LIST_STORE (ls)) + gtk_list_store_set(GTK_LIST_STORE (ls), iter, column_nr, symbol, -1); + else if (GTK_IS_TREE_STORE(ls)) + gtk_tree_store_set(GTK_TREE_STORE (ls), iter, column_nr, symbol, -1); treeview_helper_unref(G_OBJECT(symbol)); } diff --git a/src/xml_cup.c b/src/xml_cup.c index 3c450f1f..597c7055 100644 --- a/src/xml_cup.c +++ b/src/xml_cup.c @@ -25,6 +25,7 @@ #include "cup.h" #include "file.h" +#include "league.h" #include "main.h" #include "misc.h" #include "option.h" @@ -59,6 +60,7 @@ #define TAG_CUP_ROUND_NUMBER_OF_ADVANCE "number_of_advance" #define TAG_CUP_ROUND_NUMBER_OF_BEST_ADVANCE "number_of_best_advance" #define TAG_CUP_ROUND_ROUND_ROBINS "round_robins" +#define TAG_CUP_ROUND_BREAK "break" #define TAG_CUP_ROUND_TWO_MATCH_WEEK_START "two_match_week_start" #define TAG_CUP_ROUND_TWO_MATCH_WEEK_END "two_match_week_end" #define TAG_CUP_ROUND_TWO_MATCH_WEEK "two_match_week" @@ -103,6 +105,7 @@ enum XmlCupStates STATE_CUP_ROUND_NUMBER_OF_ADVANCE, STATE_CUP_ROUND_NUMBER_OF_BEST_ADVANCE, STATE_CUP_ROUND_ROUND_ROBINS, + STATE_CUP_ROUND_BREAK, STATE_CUP_ROUND_TWO_MATCH_WEEK_START, STATE_CUP_ROUND_TWO_MATCH_WEEK_END, STATE_CUP_ROUND_TWO_MATCH_WEEK, @@ -203,6 +206,8 @@ xml_cup_read_start_element (GMarkupParseContext *context, state = STATE_CUP_ROUND_NUMBER_OF_BEST_ADVANCE; else if(strcmp(element_name, TAG_CUP_ROUND_ROUND_ROBINS) == 0) state = STATE_CUP_ROUND_ROUND_ROBINS; + else if(strcmp(element_name, TAG_CUP_ROUND_BREAK) == 0) + state = STATE_CUP_ROUND_BREAK; else if(strcmp(element_name, TAG_CUP_ROUND_TWO_MATCH_WEEK_START) == 0) state = STATE_CUP_ROUND_TWO_MATCH_WEEK_START; else if(strcmp(element_name, TAG_CUP_ROUND_TWO_MATCH_WEEK_END) == 0) @@ -272,6 +277,7 @@ xml_cup_read_end_element (GMarkupParseContext *context, if(new_round.home_away == 0) new_round.round_robins = 1; + league_cup_adjust_rr_breaks(new_round.rr_breaks, new_round.round_robins, new_cup.week_gap); g_array_append_val(new_cup.rounds, new_round); } else if(strcmp(element_name, TAG_CUP_ROUND_HOME_AWAY) == 0 || @@ -283,6 +289,7 @@ xml_cup_read_end_element (GMarkupParseContext *context, strcmp(element_name, TAG_CUP_ROUND_NUMBER_OF_ADVANCE) == 0 || strcmp(element_name, TAG_CUP_ROUND_NUMBER_OF_BEST_ADVANCE) == 0 || strcmp(element_name, TAG_CUP_ROUND_ROUND_ROBINS) == 0 || + strcmp(element_name, TAG_CUP_ROUND_BREAK) == 0 || strcmp(element_name, TAG_CUP_ROUND_TWO_MATCH_WEEK_START) == 0 || strcmp(element_name, TAG_CUP_ROUND_TWO_MATCH_WEEK_END) == 0 || strcmp(element_name, TAG_CUP_ROUND_TWO_MATCH_WEEK) == 0 || @@ -381,6 +388,8 @@ xml_cup_read_text (GMarkupParseContext *context, new_round.round_robin_number_of_best_advance = int_value; else if(state == STATE_CUP_ROUND_ROUND_ROBINS) new_round.round_robins = int_value; + else if(state == STATE_CUP_ROUND_BREAK) + league_cup_fill_rr_breaks(new_round.rr_breaks, buf); else if(state == STATE_CUP_ROUND_TWO_MATCH_WEEK_START) g_array_append_val(new_round.two_match_weeks[0], int_value); else if(state == STATE_CUP_ROUND_TWO_MATCH_WEEK_END) diff --git a/src/xml_league.c b/src/xml_league.c index b98cd905..dc623794 100644 --- a/src/xml_league.c +++ b/src/xml_league.c @@ -379,7 +379,7 @@ xml_league_read_text (GMarkupParseContext *context, else if(state == STATE_NAMES_FILE) misc_string_assign(&new_league.names_file, buf); else if(state == STATE_BREAK) - new_league.rr_break = int_value; + league_cup_fill_rr_breaks(new_league.rr_breaks, buf); else if(state == STATE_PROPERTY) g_ptr_array_add(new_league.properties, g_strdup(buf)); else if(state == STATE_JOINED_LEAGUE) @@ -498,6 +498,7 @@ xml_league_read(const gchar *league_name, GArray *leagues) g_markup_parse_context_free(context); g_free(file_contents); + league_cup_adjust_rr_breaks(new_league.rr_breaks, new_league.round_robins, new_league.week_gap); g_array_append_val(leagues, new_league); } else diff --git a/src/xml_loadsave_cup.c b/src/xml_loadsave_cup.c index e92fd730..459e935b 100644 --- a/src/xml_loadsave_cup.c +++ b/src/xml_loadsave_cup.c @@ -64,6 +64,7 @@ enum TAG_CUP_ROUND_ROUND_ROBIN_NUMBER_OF_ADVANCE, TAG_CUP_ROUND_ROUND_ROBIN_NUMBER_OF_BEST_ADVANCE, TAG_CUP_ROUND_ROUND_ROBINS, + TAG_CUP_ROUND_BREAK, TAG_CUP_ROUND_TWO_MATCH_WEEK_START, TAG_CUP_ROUND_TWO_MATCH_WEEK_END, TAG_CUP_ROUND_TWO_MATCH_WEEK, @@ -183,6 +184,7 @@ xml_loadsave_cup_end_element (GMarkupParseContext *context, tag == TAG_CUP_ROUND_ROUND_ROBIN_NUMBER_OF_ADVANCE || tag == TAG_CUP_ROUND_ROUND_ROBIN_NUMBER_OF_BEST_ADVANCE || tag == TAG_CUP_ROUND_ROUND_ROBINS || + tag == TAG_CUP_ROUND_BREAK || tag == TAG_CUP_ROUND_TWO_MATCH_WEEK_START || tag == TAG_CUP_ROUND_TWO_MATCH_WEEK_END || tag == TAG_CUP_ROUND_TWO_MATCH_WEEK) @@ -305,6 +307,8 @@ xml_loadsave_cup_text (GMarkupParseContext *context, new_round.round_robin_number_of_best_advance = int_value; else if(state == TAG_CUP_ROUND_ROUND_ROBINS) new_round.round_robins = int_value; + else if(state == TAG_CUP_ROUND_BREAK) + g_array_append_val(new_round.rr_breaks, int_value); else if(state == TAG_CUP_ROUND_TWO_MATCH_WEEK_START) g_array_append_val(new_round.two_match_weeks[0], int_value); else if(state == TAG_CUP_ROUND_TWO_MATCH_WEEK_END) @@ -459,6 +463,11 @@ xml_loadsave_cup_write_round(FILE *fil, const gchar *prefix, const Cup *cup, gin TAG_CUP_ROUND_ROUND_ROBIN_NUMBER_OF_BEST_ADVANCE, I1); xml_write_int(fil, cup_round->round_robins, TAG_CUP_ROUND_ROUND_ROBINS, I1); + + for(i = 0; i < cup_round->rr_breaks->len; i++) + xml_write_int(fil, g_array_index(cup_round->rr_breaks, gint, i), + TAG_CUP_ROUND_BREAK, I1); + xml_write_int(fil, cup_round->two_match_week, TAG_CUP_ROUND_TWO_MATCH_WEEK, I1); diff --git a/src/xml_loadsave_league.c b/src/xml_loadsave_league.c index 6c743ee4..877a8f8d 100644 --- a/src/xml_loadsave_league.c +++ b/src/xml_loadsave_league.c @@ -233,7 +233,7 @@ xml_loadsave_league_text (GMarkupParseContext *context, else if(state == TAG_YELLOW_RED) new_league->yellow_red = int_value; else if(state == TAG_LEAGUE_BREAK) - new_league->rr_break = int_value; + g_array_append_val(new_league->rr_breaks, int_value); else if(state == TAG_LEAGUE_JOINED_LEAGUE_SID) g_array_index(new_league->joined_leagues, JoinedLeague, @@ -368,7 +368,9 @@ xml_loadsave_league_write(const gchar *prefix, const League *league) xml_write_int(fil, league->round_robins, TAG_LEAGUE_ROUND_ROBINS, I0); xml_write_int(fil, league->week_gap, TAG_WEEK_GAP, I0); xml_write_int(fil, league->yellow_red, TAG_YELLOW_RED, I0); - xml_write_int(fil, league->rr_break, TAG_LEAGUE_BREAK, I0); + + for(i = 0; i < league->rr_breaks->len; i++) + xml_write_int(fil, g_array_index(league->rr_breaks, gint, i), TAG_LEAGUE_BREAK, I0); for(i=0;itables->len;i++) { diff --git a/support_files/definitions/miscellaneous/europe/cup_europe_champ_league.xml b/support_files/definitions/miscellaneous/europe/cup_europe_champ_league.xml index f9e8bf6f..89babba2 100644 --- a/support_files/definitions/miscellaneous/europe/cup_europe_champ_league.xml +++ b/support_files/definitions/miscellaneous/europe/cup_europe_champ_league.xml @@ -20,6 +20,7 @@ 2 16 + LEAGUE1