mirror of
https://github.com/tstellar/bygfoot.git
synced 2024-12-13 08:56:32 +01:00
Add support for regional leagues
This allows promotion / relegation of teams into region based leagues. In some countries lower level leagues are region based, and teams that are relegated to this level must play in a specific regional league. To create a regional league, use the <regions> tag in the league definiton to specify a space separated list of region names that this league covers. To specify which region a team belongs to, use the <region> tag in the team definition.
This commit is contained in:
parent
34db509a84
commit
2345d797f0
@ -404,6 +404,8 @@ free_league(League *league)
|
||||
free_g_array(&league->two_match_weeks[1]);
|
||||
|
||||
free_league_stats(&league->stats);
|
||||
|
||||
free_gchar_ptr(league->regions);
|
||||
}
|
||||
|
||||
/** Free the promotion/relegation struct of a league. */
|
||||
@ -562,6 +564,7 @@ free_team(Team *tm)
|
||||
free_gchar_ptr(tm->def_file);
|
||||
|
||||
free_player_array(&tm->players);
|
||||
g_free(tm->region);
|
||||
}
|
||||
|
||||
/** Free an array containing players. */
|
||||
|
55
src/league.c
55
src/league.c
@ -82,6 +82,7 @@ league_new(gboolean new_id)
|
||||
new.yellow_red = 1000;
|
||||
|
||||
new.stats = stat_league_new("", "");
|
||||
new.regions = NULL;
|
||||
|
||||
return new;
|
||||
}
|
||||
@ -1318,6 +1319,40 @@ league_team_movements_compare_dest_idcs(gconstpointer a, gconstpointer b,
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
league_has_region(const League *league)
|
||||
{
|
||||
return league->regions != NULL;
|
||||
}
|
||||
|
||||
/** Return TRUE if \p team is eligible for \p league baed on the regions
|
||||
* of both. Note: This function will return TRUE for if either \p league or
|
||||
* \p team have no regions defined.
|
||||
*/
|
||||
gboolean
|
||||
league_team_is_in_region(const League *league, const Team *team)
|
||||
{
|
||||
GPtrArray *regions;
|
||||
gboolean result = FALSE;
|
||||
gint i;
|
||||
|
||||
if (!league_has_region(league) || !team->region)
|
||||
return TRUE;
|
||||
|
||||
regions = misc_separate_strings(league->regions);
|
||||
for (i = 0; i < regions->len; i++) {
|
||||
const gchar *region = g_ptr_array_index(regions, i);
|
||||
if (!g_strcmp0(team->region, region)) {
|
||||
result = TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
free_gchar_array(®ions);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** Assign a random destination for the team move with given index
|
||||
and remove the destination from all other unassigned moves if
|
||||
the dest league is full. */
|
||||
@ -1335,6 +1370,19 @@ league_team_movements_assign_dest(GArray *team_movements, gint idx,
|
||||
if(debug > 60)
|
||||
g_print("league_team_movements_assign_dest %s\n", tmove->tm.name);
|
||||
|
||||
/* Filter out destination leagues that are in a different region */
|
||||
if (tmove->tm.region) {
|
||||
GArray* new_dest_idcs = g_array_new(FALSE, FALSE, sizeof(gint));
|
||||
for (i = 0; i < tmove->dest_idcs->len; i++) {
|
||||
gint dest_idx = g_array_index(tmove->dest_idcs, gint, i);
|
||||
const League *league = &lig(dest_idx);
|
||||
if (league_team_is_in_region(league, &tmove->tm))
|
||||
g_array_append_val(new_dest_idcs, dest_idx);
|
||||
}
|
||||
g_array_unref(tmove->dest_idcs);
|
||||
tmove->dest_idcs = new_dest_idcs;
|
||||
}
|
||||
|
||||
if(tmove->dest_idcs->len == 1)
|
||||
dest_idx = g_array_index(tmove->dest_idcs, gint, 0);
|
||||
else
|
||||
@ -1347,7 +1395,12 @@ league_team_movements_assign_dest(GArray *team_movements, gint idx,
|
||||
|
||||
league_cur_size[dest_idx]++;
|
||||
|
||||
if(league_cur_size[dest_idx] > league_size[dest_idx])
|
||||
/* The size of region based leagues can fluxute depending on when teams
|
||||
* are relegated in a given year, so we skip the size check for those
|
||||
* types of leagues.
|
||||
*/
|
||||
if(league_cur_size[dest_idx] > league_size[dest_idx] &&
|
||||
!league_has_region(&lig(dest_idx)))
|
||||
main_exit_program(EXIT_PROM_REL,
|
||||
"league_team_movements_assign_dest: no room in league %s for team %s.",
|
||||
lig(dest_idx).name, tmove->tm.name);
|
||||
|
@ -148,6 +148,12 @@ void
|
||||
league_team_movements_prune(GArray *team_movements, const gint *league_size,
|
||||
gint *league_cur_size);
|
||||
|
||||
gboolean
|
||||
league_has_region(const League *league);
|
||||
|
||||
gboolean
|
||||
league_team_is_in_region(const League *league, const Team *team);
|
||||
|
||||
void
|
||||
league_team_movements_assign_dest(GArray *team_movements, gint idx,
|
||||
const gint *league_size, gint *league_cur_size);
|
||||
|
@ -193,6 +193,9 @@ typedef struct
|
||||
the fixtures of which should be avoided when scheduling
|
||||
the league fixtures. */
|
||||
GPtrArray *skip_weeks_with;
|
||||
/** Space delminted list of region names for this league. Only Teams that
|
||||
* belong to one of these regions may play in this league. */
|
||||
gchar *regions;
|
||||
} League;
|
||||
|
||||
#endif
|
||||
|
@ -72,6 +72,7 @@ team_new(gboolean new_id)
|
||||
new.first_team_sid = NULL;
|
||||
new.first_team_id = 0;
|
||||
new.reserve_level = 0;
|
||||
new.region = NULL;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -117,6 +117,10 @@ typedef struct
|
||||
* to have Green II be level 2 and not 1 is because it makes the xml
|
||||
* definitions less confusing.*/
|
||||
gint reserve_level;
|
||||
|
||||
/** The region this team belongs to. This can be used to determine
|
||||
* which leagues a team can play in. */
|
||||
gchar *region;
|
||||
} Team;
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define TAG_AVERAGE_TALENT "average_talent"
|
||||
#define TAG_NAMES_FILE "names_file"
|
||||
#define TAG_BREAK "break"
|
||||
#define TAG_REGIONS "regions"
|
||||
#define TAG_JOINED_LEAGUE "joined_league"
|
||||
#define TAG_NEW_TABLE "new_table"
|
||||
#define TAG_PROM_REL "prom_rel"
|
||||
@ -70,6 +71,7 @@
|
||||
#define TAG_TEAM_FIRST_TEAM "first_team"
|
||||
#define TAG_TEAM_RESERVE_LEVEL "reserve_level"
|
||||
#define TAG_TEAM_DEF_FILE "def_file"
|
||||
#define TAG_TEAM_REGION "region"
|
||||
#define TAG_TWO_MATCH_WEEK_START "two_match_week_start"
|
||||
#define TAG_TWO_MATCH_WEEK_END "two_match_week_end"
|
||||
|
||||
@ -119,12 +121,14 @@ enum XmlLeagueStates
|
||||
STATE_TEAM_FIRST_TEAM,
|
||||
STATE_TEAM_RESERVE_LEVEL,
|
||||
STATE_TEAM_DEF_FILE,
|
||||
STATE_TEAM_REGION,
|
||||
STATE_BREAK,
|
||||
STATE_JOINED_LEAGUE,
|
||||
STATE_PROPERTY,
|
||||
STATE_NEW_TABLE,
|
||||
STATE_TWO_MATCH_WEEK_START,
|
||||
STATE_TWO_MATCH_WEEK_END,
|
||||
STATE_REGIONS,
|
||||
STATE_END
|
||||
};
|
||||
|
||||
@ -202,6 +206,8 @@ xml_league_read_start_element (GMarkupParseContext *context,
|
||||
state = STATE_NAMES_FILE;
|
||||
else if(strcmp(element_name, TAG_BREAK) == 0)
|
||||
state = STATE_BREAK;
|
||||
else if(strcmp(element_name, TAG_REGIONS) == 0)
|
||||
state = STATE_REGIONS;
|
||||
else if(strcmp(element_name, TAG_DEF_PROPERTY) == 0)
|
||||
state = STATE_PROPERTY;
|
||||
else if(strcmp(element_name, TAG_JOINED_LEAGUE) == 0)
|
||||
@ -294,6 +300,8 @@ xml_league_read_start_element (GMarkupParseContext *context,
|
||||
state = STATE_TEAM_FIRST_TEAM;
|
||||
else if(strcmp(element_name, TAG_TEAM_RESERVE_LEVEL) == 0)
|
||||
state = STATE_TEAM_RESERVE_LEVEL;
|
||||
else if(strcmp(element_name, TAG_TEAM_REGION) == 0)
|
||||
state = STATE_TEAM_REGION;
|
||||
else
|
||||
debug_print_message("xml_league_read_start_element: unknown tag: %s; I'm in state %d\n",
|
||||
element_name, state);
|
||||
@ -335,6 +343,7 @@ xml_league_read_end_element (GMarkupParseContext *context,
|
||||
strcmp(element_name, TAG_TWO_MATCH_WEEK_START) == 0 ||
|
||||
strcmp(element_name, TAG_TWO_MATCH_WEEK_END) == 0 ||
|
||||
strcmp(element_name, TAG_PROM_REL) == 0 ||
|
||||
strcmp(element_name, TAG_REGIONS) == 0 ||
|
||||
strcmp(element_name, TAG_TEAMS) == 0)
|
||||
state = STATE_LEAGUE;
|
||||
else if(strcmp(element_name, TAG_PROM_GAMES) == 0 ||
|
||||
@ -362,6 +371,7 @@ xml_league_read_end_element (GMarkupParseContext *context,
|
||||
strcmp(element_name, TAG_TEAM_DEF_FILE) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_FIRST_TEAM) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_RESERVE_LEVEL) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_REGION) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_AVERAGE_TALENT) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_SYMBOL) == 0 ||
|
||||
strcmp(element_name, TAG_TEAM_NAMES_FILE) == 0)
|
||||
@ -428,6 +438,8 @@ xml_league_read_text (GMarkupParseContext *context,
|
||||
misc_string_assign(&new_league.names_file, buf);
|
||||
else if(state == STATE_BREAK)
|
||||
league_cup_fill_rr_breaks(new_league.rr_breaks, buf);
|
||||
else if (state == STATE_REGIONS)
|
||||
misc_string_assign(&new_league.regions, buf);
|
||||
else if(state == STATE_PROPERTY)
|
||||
g_ptr_array_add(new_league.properties, g_strdup(buf));
|
||||
else if(state == STATE_JOINED_LEAGUE)
|
||||
@ -509,6 +521,8 @@ xml_league_read_text (GMarkupParseContext *context,
|
||||
misc_string_assign(&g_array_index(new_league.teams, Team, new_league.teams->len - 1).first_team_sid, buf);
|
||||
else if(state == STATE_TEAM_RESERVE_LEVEL)
|
||||
g_array_index(new_league.teams, Team, new_league.teams->len - 1).reserve_level = int_value;
|
||||
else if(state == STATE_TEAM_REGION)
|
||||
misc_string_assign(&g_array_index(new_league.teams, Team, new_league.teams->len - 1).region, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,6 +66,7 @@ enum
|
||||
TAG_LEAGUE_TWO_MATCH_WEEK_START,
|
||||
TAG_LEAGUE_TWO_MATCH_WEEK_END,
|
||||
TAG_LEAGUE_TABLE_FILE,
|
||||
TAG_LEAGUE_REGIONS,
|
||||
TAG_END
|
||||
};
|
||||
|
||||
@ -155,6 +156,7 @@ xml_loadsave_league_end_element (GMarkupParseContext *context,
|
||||
tag == TAG_LEAGUE_TWO_MATCH_WEEK_START ||
|
||||
tag == TAG_LEAGUE_TWO_MATCH_WEEK_END ||
|
||||
tag == TAG_LEAGUE_TABLE_FILE ||
|
||||
tag == TAG_LEAGUE_REGIONS ||
|
||||
tag == TAG_LEAGUE_AVERAGE_TALENT ||
|
||||
tag == TAG_LEAGUE_AVERAGE_TALENT ||
|
||||
tag == TAG_LEAGUE_ROUND_ROBINS ||
|
||||
@ -292,6 +294,8 @@ xml_loadsave_league_text (GMarkupParseContext *context,
|
||||
xml_loadsave_table_read(buf2, &new_table);
|
||||
g_array_append_val(new_league->tables, new_table);
|
||||
}
|
||||
else if(state == TAG_LEAGUE_REGIONS)
|
||||
misc_string_assign(&new_league->regions, buf);
|
||||
else if(state == TAG_LEAGUE_AVERAGE_TALENT)
|
||||
new_league->average_talent = float_value;
|
||||
else if(state == TAG_LEAGUE_PROM_REL_PROM_GAMES_DEST_SID)
|
||||
@ -391,6 +395,7 @@ xml_loadsave_league_write(const gchar *prefix, const League *league)
|
||||
xml_write_string(fil, league->names_file, TAG_NAMES_FILE, I0);
|
||||
xml_write_string(fil, league->sid, TAG_SID, I0);
|
||||
xml_write_string(fil, league->symbol, TAG_SYMBOL, I0);
|
||||
xml_write_string(fil, league->regions, TAG_LEAGUE_REGIONS, I0);
|
||||
|
||||
for(i=0;i<league->properties->len;i++)
|
||||
xml_write_string(fil, (gchar*)g_ptr_array_index(league->properties, i),
|
||||
|
@ -53,6 +53,7 @@ enum
|
||||
TAG_TEAM_FIRST_TEAM_SID,
|
||||
TAG_TEAM_FIRST_TEAM_ID,
|
||||
TAG_TEAM_RESERVE_LEVEL,
|
||||
TAG_TEAM_REGION,
|
||||
TAG_END
|
||||
};
|
||||
|
||||
@ -137,6 +138,7 @@ xml_loadsave_teams_end_element (GMarkupParseContext *context,
|
||||
tag == TAG_TEAM_FIRST_TEAM_SID ||
|
||||
tag == TAG_TEAM_FIRST_TEAM_ID ||
|
||||
tag == TAG_TEAM_RESERVE_LEVEL ||
|
||||
tag == TAG_TEAM_REGION ||
|
||||
tag == TAG_TEAM_LUCK)
|
||||
state = TAG_TEAM;
|
||||
else if(tag == TAG_TEAM_STADIUM_NAME ||
|
||||
@ -219,6 +221,8 @@ xml_loadsave_teams_text (GMarkupParseContext *context,
|
||||
new_team.first_team_id = int_value;
|
||||
else if(state == TAG_TEAM_RESERVE_LEVEL)
|
||||
new_team.reserve_level = int_value;
|
||||
else if(state == TAG_TEAM_REGION)
|
||||
misc_string_assign(&new_team.region, buf);
|
||||
else if(state >= TAG_START_PLAYERS && state <= TAG_END_PLAYERS)
|
||||
xml_loadsave_players_text(buf);
|
||||
}
|
||||
@ -303,6 +307,7 @@ xml_loadsave_teams_write_team(FILE *fil, const Team* team)
|
||||
xml_write_string(fil, team->names_file, TAG_TEAM_NAMES_FILE, I1);
|
||||
xml_write_string(fil, team->strategy_sid, TAG_TEAM_STRATEGY_SID, I1);
|
||||
xml_write_string(fil, team->first_team_sid, TAG_TEAM_FIRST_TEAM_SID, I1);
|
||||
xml_write_string(fil, team->region, TAG_TEAM_REGION, I1);
|
||||
|
||||
xml_write_int(fil, team->clid, TAG_TEAM_CLID, I1);
|
||||
xml_write_int(fil, team->id, TAG_TEAM_ID, I1);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define TAG_NAMES_FILE "names_file"
|
||||
#define TAG_FIRST_TEAM "first_team"
|
||||
#define TAG_RESERVE_LEVEL "reserve_level"
|
||||
#define TAG_REGION "region"
|
||||
#define TAG_PLAYER "player"
|
||||
#define TAG_PLAYER_NAME "player_name"
|
||||
#define TAG_PLAYER_BIRTH_YEAR "birth_year"
|
||||
@ -64,6 +65,7 @@ enum XmlTeamStates
|
||||
STATE_NAMES_FILE,
|
||||
STATE_FIRST_TEAM,
|
||||
STATE_RESERVE_LEVEL,
|
||||
STATE_REGION,
|
||||
STATE_PLAYER,
|
||||
STATE_PLAYER_NAME,
|
||||
STATE_PLAYER_BIRTH_YEAR,
|
||||
@ -109,6 +111,8 @@ xml_team_read_start_element (GMarkupParseContext *context,
|
||||
state = STATE_FIRST_TEAM;
|
||||
else if(strcmp(element_name, TAG_RESERVE_LEVEL) == 0)
|
||||
state = STATE_RESERVE_LEVEL;
|
||||
else if(strcmp(element_name, TAG_REGION) == 0)
|
||||
state = STATE_REGION;
|
||||
else if(strcmp(element_name, TAG_PLAYER) == 0)
|
||||
{
|
||||
state = STATE_PLAYER;
|
||||
@ -155,6 +159,7 @@ xml_team_read_end_element (GMarkupParseContext *context,
|
||||
strcmp(element_name, TAG_NAMES_FILE) == 0 ||
|
||||
strcmp(element_name, TAG_FIRST_TEAM) == 0 ||
|
||||
strcmp(element_name, TAG_RESERVE_LEVEL) == 0 ||
|
||||
strcmp(element_name, TAG_REGION) == 0 ||
|
||||
strcmp(element_name, TAG_PLAYER) == 0)
|
||||
{
|
||||
state = STATE_TEAM;
|
||||
@ -230,6 +235,8 @@ xml_team_read_text (GMarkupParseContext *context,
|
||||
misc_string_assign(&team->first_team_sid, buf);
|
||||
else if(state == STATE_RESERVE_LEVEL)
|
||||
team->reserve_level = int_value;
|
||||
else if(state == STATE_REGION)
|
||||
misc_string_assign(&team->region, buf);
|
||||
else if(state == STATE_PLAYER_NAME)
|
||||
misc_string_assign(&new_player.name, buf);
|
||||
else if(state == STATE_PLAYER_BIRTH_YEAR && opt_int("int_opt_load_defs") == 1)
|
||||
|
Loading…
Reference in New Issue
Block a user