Multiple tables for leagues feature completed.

This commit is contained in:
gyboth 2008-11-22 16:51:31 +00:00
parent e80656a66e
commit 33e2134d18
15 changed files with 248 additions and 80 deletions

View File

@ -341,6 +341,7 @@ free_league(League *league)
free_g_array(&league->prom_rel.elements);;
free_tables(&league->tables);
free_new_tables(&league->new_tables);
free_g_array(&league->fixtures);
@ -411,6 +412,19 @@ free_tables(GArray **tables)
*tables = NULL;
}
/** Free a new_tables array. */
void
free_new_tables(GArray **new_tables)
{
gint i;
for(i = 0; i < (*new_tables)->len; i++)
free_gchar_ptr(g_array_index(*new_tables, NewTable, i).name);
g_array_free(*new_tables, TRUE);
*new_tables = NULL;
}
/** Free the memory occupied by a teams array.
@param teams The pointer to the array we free. */
void

View File

@ -113,6 +113,9 @@ free_support_dirs(void);
void
free_tables(GArray **tables);
void
free_new_tables(GArray **new_tables);
void
free_league_stats(LeagueStat *stats);

View File

@ -46,7 +46,6 @@ League
league_new(gboolean new_id)
{
League new;
Table new_table;
new.name = NULL;
new.names_file = g_strdup(opt_str("string_opt_player_names_file"));
@ -70,14 +69,8 @@ league_new(gboolean new_id)
new.teams = g_array_new(FALSE, FALSE, sizeof(Team));
new.fixtures = g_array_new(FALSE, FALSE, sizeof(Fixture));
new.joined_leagues = g_array_new(FALSE, FALSE, sizeof(JoinedLeague));
new.new_tables = g_array_new(FALSE, FALSE, sizeof(NewTable));
new.tables = g_array_new(FALSE, FALSE, sizeof(Table));
if(new_id)
{
new_table = table_new();
g_array_append_val(new.tables, new_table);
league_table((&new))->clid = new.id;
}
new.first_week = new.week_gap = 1;
new.two_match_weeks[0] = g_array_new(FALSE, FALSE, sizeof(gint));
@ -417,23 +410,13 @@ league_season_start(League *league)
usr(i).tm->luck =
MIN(usr(i).tm->luck * const_float("float_season_end_user_champ_luck_factor_regen"), 1);
for(i = league->tables->len - 1; i > 0; i--)
/** Reset tables */
for(i = league->tables->len - 1; i >= 0; i--)
{
g_array_free(g_array_index(league->tables, Table, i).elements, TRUE);
g_array_remove_index(league->tables, i);
}
for(i=0;i<league_table(league)->elements->len;i++)
{
g_array_index(league_table(league)->elements, TableElement, i).team =
&g_array_index(league->teams, Team, i);
g_array_index(league_table(league)->elements, TableElement, i).team_id =
g_array_index(league->teams, Team, i).id;
g_array_index(league_table(league)->elements, TableElement, i).old_rank = i;
for(j=0;j<TABLE_END;j++)
g_array_index(league_table(league)->elements, TableElement, i).values[j] = 0;
}
league_add_table(league);
/*d*/
/* if(league == &lig(0)) */
@ -884,3 +867,50 @@ query_league_cup_matchday_in_two_match_week(GArray **two_match_weeks, gint match
return FALSE;
}
/** Add a new table to the league tables if specified
in the new_tables array. */
void
league_check_new_tables(League *league)
{
gint i;
Table new_table;
for(i = 0; i < league->new_tables->len; i++)
if(g_array_index(league->new_tables, NewTable, i).add_week == week)
{
/** Create cumulative table if necessary. */
if(league->tables->len == 1 && week > 1)
{
new_table = table_copy(league_table(league));
g_array_append_val(league->tables, new_table);
}
league_add_table(league);
misc_string_assign(&league_table(league)->name,
g_array_index(league->new_tables, NewTable, i).name);
}
}
/** Add an initialized table to the league. */
void
league_add_table(League *league)
{
gint i;
Table new_table;
TableElement new_table_element;
new_table = table_new();
new_table.clid = league->id;
new_table.name = g_strdup(league->name);
for(i = 0; i < league->teams->len; i++)
{
new_table_element =
table_element_new(
&g_array_index(league->teams, Team, i), i);
g_array_append_val(new_table.elements, new_table_element);
}
g_array_append_val(league->tables, new_table);
}

View File

@ -138,4 +138,10 @@ query_leagues_active_in_country(void);
gboolean
query_league_cup_matchday_in_two_match_week(GArray **two_match_weeks, gint matchday);
void
league_check_new_tables(League *league);
void
league_add_table(League *league);
#endif

View File

@ -90,6 +90,17 @@ typedef struct
gint rr;
} JoinedLeague;
/**
A structure containing a week when a new table
gets created with nullified values for the league;
older tables get stored.
*/
typedef struct
{
gint add_week;
gchar *name;
} NewTable;
/**
Representation of a league.
@see PromRel
@ -136,6 +147,9 @@ typedef struct
/** League tables. Usually only one, sometimes more than one is created.
@see Table */
GArray *tables;
/** Array holding NewTable elements specifying when to add
a new table to the tables array. */
GArray *new_tables;
/** The fixtures of a season for the league. */
GArray *fixtures;
/** The current league statistics. */

View File

@ -698,17 +698,13 @@ player_is_banned(const Player *pl)
streak.
@return A float value representing the player's contribution. */
gfloat
player_get_game_skill(Player *pl, gboolean skill, gboolean count_special)
player_get_game_skill(const Player *pl, gboolean skill, gboolean count_special)
{
gfloat boost = (count_special) ?
1 + const_float("float_player_boost_skill_effect") * pl->team->boost : 1;
gfloat streak = (count_special) ?
1 + (gfloat)pl->streak * const_float("float_player_streak_influence_skill") : 1;
// workaround
if(pl->fitness < 0)
pl->fitness = const_float("float_player_fitness_lower");
return (skill) ? pl->skill * boost * streak *
powf(pl->fitness, const_float("float_player_fitness_exponent")) :
pl->cskill * boost * streak *
@ -749,7 +745,8 @@ player_decrease_fitness(Player *pl)
goalie_factor * boost_factor * streak_factor);
}
pl->fitness = MAX(0, pl->fitness);
if(pl->fitness < 0)
pl->fitness = 0;
}
@ -1103,6 +1100,10 @@ player_update_streak(Player *pl)
void
player_update_weekly(Player *pl)
{
// workaround, possibly unnecessary
if(pl->fitness < 0)
pl->fitness = const_float("float_player_fitness_lower");
if(pl->health > 0)
player_update_injury(pl);
else

View File

@ -103,7 +103,7 @@ gint
player_id_index(const Team *tm, gint player_id);
gfloat
player_get_game_skill(Player *pl, gboolean skill, gboolean special);
player_get_game_skill(const Player *pl, gboolean skill, gboolean special);
void
player_decrease_fitness(Player *pl);

View File

@ -69,7 +69,7 @@ WeekFunc start_week_round_funcs[] =
/** Array of functions called when a week
is started. */
WeekFunc start_week_funcs[] =
{start_week_add_cups, start_week_update_users,
{start_week_update_leagues, start_week_add_cups, start_week_update_users,
start_week_update_teams, start_week_update_user_finances,
youth_academy_update_weekly, transfer_update, job_update,
finance_update_current_interest, NULL};
@ -148,6 +148,12 @@ start_new_season(void)
}
else
{
for(i=0;i<ligs->len;i++)
{
league_add_table(&lig(i));
league_check_new_tables(&lig(i));
}
for(i=0;i<cps->len;i++)
if(cp(i).add_week <= 0)
g_ptr_array_add(acps, &cp(i));
@ -591,6 +597,16 @@ start_week_update_users(void)
}
}
/** Create new tables if necessary etc. */
void
start_week_update_leagues(void)
{
gint i;
for(i = 0; i < ligs->len; i++)
league_check_new_tables(&lig(i));
}
/** Check whether the season has ended. */
gboolean
query_start_end_season_end(void)

View File

@ -91,4 +91,7 @@ end_week_hide_cups(void);
void
start_new_season_reset_ids(void);
void
start_week_update_leagues(void);
#endif

View File

@ -69,41 +69,59 @@ table_element_new(Team *team, gint old_rank)
void
table_update(const Fixture *fix)
{
gint i;
gint i, j;
gint idx = (fix->result[0][0] < fix->result[1][0]);
TableElement *elements[2] = {NULL, NULL};
TableElement *elements[2];
table_update_get_elements(elements, fix);
for(j = 0; j < 2; j++)
{
elements[0] = elements[1] = NULL;
table_update_get_elements(elements, fix, (j == 1));
for(i=0;i<2;i++)
{
elements[i]->values[TABLE_PLAYED]++;
elements[i]->values[TABLE_GF] += fix->result[i][0];
elements[i]->values[TABLE_GA] += fix->result[!i][0];
elements[i]->values[TABLE_GD] =
elements[i]->values[TABLE_GF] - elements[i]->values[TABLE_GA];
}
for(i=0;i<2;i++)
{
if(elements[i] != NULL)
{
elements[i]->values[TABLE_PLAYED]++;
elements[i]->values[TABLE_GF] += fix->result[i][0];
elements[i]->values[TABLE_GA] += fix->result[!i][0];
elements[i]->values[TABLE_GD] =
elements[i]->values[TABLE_GF] - elements[i]->values[TABLE_GA];
}
}
if(fix->result[0][0] == fix->result[1][0])
for(i=0;i<2;i++)
{
elements[i]->values[TABLE_DRAW]++;
elements[i]->values[TABLE_PTS] += 1;
}
else
{
elements[idx]->values[TABLE_WON]++;
elements[idx]->values[TABLE_PTS] += 3;
elements[!idx]->values[TABLE_LOST]++;
if(fix->result[0][0] == fix->result[1][0])
for(i=0;i<2;i++)
{
if(elements[i] != NULL)
{
elements[i]->values[TABLE_DRAW]++;
elements[i]->values[TABLE_PTS] += 1;
}
}
else
{
if(elements[idx] != NULL)
{
elements[idx]->values[TABLE_WON]++;
elements[idx]->values[TABLE_PTS] += 3;
}
if(elements[!idx] != NULL)
{
elements[!idx]->values[TABLE_LOST]++;
}
}
}
}
/** Get the pointers to the table entries
representing the two teams from the fixture.
@param elements The table entries.
@fix The fixture. */
@fix The fixture.
@non_cumulative Whether to return the last non-cumulative table. */
void
table_update_get_elements(TableElement **elements, const Fixture *fix)
table_update_get_elements(TableElement **elements, const Fixture *fix, gboolean non_cumulative)
{
gint i, j;
Table *table;
@ -112,8 +130,17 @@ table_update_get_elements(TableElement **elements, const Fixture *fix)
{
for(j = 0; j < 2; j++)
{
table = league_table(league_from_clid(fix->teams[j]->clid));
if(non_cumulative &&
league_from_clid(fix->teams[j]->clid)->tables->len == 1)
{
elements[j] = NULL;
continue;
}
table = (non_cumulative) ?
league_table(league_from_clid(fix->teams[j]->clid)) :
league_table_cumul(league_from_clid(fix->teams[j]->clid));
for(i=0;i<table->elements->len;i++)
{
if(g_array_index(table->elements, TableElement, i).team == fix->teams[j])
@ -230,3 +257,33 @@ query_tables_in_country(void)
return FALSE;
}
/** Copy a table. */
Table
table_copy(const Table *table)
{
gint i, j;
Table new_table;
TableElement new_table_element;
TableElement *elem;
new_table.name = g_strdup(table->name);
new_table.clid = table->clid;
new_table.round = table->round;
new_table.elements = g_array_new(FALSE, FALSE, sizeof(TableElement));
for(i = 0; i < table->elements->len; i++)
{
elem = &g_array_index(table->elements, TableElement, i);
new_table_element.team = elem->team;
new_table_element.team_id = elem->team_id;
new_table_element.old_rank = elem->old_rank;
for(j=0;j<TABLE_END;j++)
new_table_element.values[j] = elem->values[j];
g_array_append_val(new_table.elements, new_table_element);
}
return new_table;
}

View File

@ -40,7 +40,7 @@ void
table_update(const Fixture *fix);
void
table_update_get_elements(TableElement **elements, const Fixture *fix);
table_update_get_elements(TableElement **elements, const Fixture *fix, gboolean non_cumulative);
gint
table_element_compare_func(gconstpointer a,
@ -50,5 +50,8 @@ table_element_compare_func(gconstpointer a,
gboolean
query_tables_in_country(void);
Table
table_copy(const Table *table);
#endif

View File

@ -64,8 +64,6 @@ team_new(gboolean new_id)
new.average_talent = 0;
new.luck = 1;
new.stadium.ticket_price = const_int("int_team_stadium_ticket_price");
new.players = g_array_new(FALSE, FALSE, sizeof(Player));
return new;
@ -90,6 +88,7 @@ team_generate_players_stadium(Team *tm, gfloat av_talent)
tm->stadium.safety =
math_rnd(const_float("float_team_stadium_safety_lower"),
const_float("float_team_stadium_safety_upper"));
tm->stadium.ticket_price = const_int("int_team_stadium_ticket_price");
if(tm->clid < ID_CUP_START)
{

View File

@ -1110,7 +1110,7 @@ treeview_table_write_header(GtkListStore *ls, const Table *table, gint number)
if(table->clid < ID_CUP_START)
{
symbol = league_from_clid(table->clid)->symbol;
strcpy(buf, league_cup_get_name_string(table->clid));
strcpy(buf, table->name);
}
else
{
@ -1219,7 +1219,7 @@ treeview_create_table(gint clid)
if(clid < ID_CUP_START)
{
tables = league_from_clid(clid)->tables;
for(i = 0; i < tables->len; i++)
for(i = tables->len - 1; i >= 0; i--)
treeview_create_single_table(ls, &g_array_index(tables, Table, i), i + 1);
}
else

View File

@ -53,6 +53,7 @@
#define TAG_ACTIVE "active"
#define TAG_BREAK "break"
#define TAG_JOINED_LEAGUE "joined_league"
#define TAG_NEW_TABLE "new_table"
#define TAG_PROM_REL "prom_rel"
#define TAG_PROM_GAMES "prom_games"
#define TAG_PROM_GAMES_DEST_SID "prom_games_dest_sid"
@ -75,6 +76,7 @@
#define TAG_TWO_MATCH_WEEK_END "two_match_week_end"
#define ATT_NAME_JOINED_LEAGUE_RR "rr"
#define ATT_NAME_NEW_TABLE_NAME "name"
/**
* Enum with the states used in the XML parser functions.
@ -114,6 +116,7 @@ enum XmlLeagueStates
STATE_TEAM_DEF_FILE,
STATE_BREAK,
STATE_JOINED_LEAGUE,
STATE_NEW_TABLE,
STATE_TWO_MATCH_WEEK_START,
STATE_TWO_MATCH_WEEK_END,
STATE_END
@ -144,6 +147,7 @@ xml_league_read_start_element (GMarkupParseContext *context,
PromRelElement new_element;
Team new_team;
JoinedLeague new_joined_league;
NewTable new_table;
if(strcmp(element_name, TAG_LEAGUE) == 0)
{
@ -187,6 +191,16 @@ xml_league_read_start_element (GMarkupParseContext *context,
g_array_append_val(new_league.joined_leagues, new_joined_league);
}
else if(strcmp(element_name, TAG_NEW_TABLE) == 0)
{
state = STATE_NEW_TABLE;
if(attribute_names[0] != NULL && strcmp(attribute_names[0], ATT_NAME_NEW_TABLE_NAME) == 0)
new_table.name = g_strdup(attribute_values[0]);
else
new_table.name = g_strdup(new_league.name);
g_array_append_val(new_league.new_tables, new_table);
}
else if(strcmp(element_name, TAG_TWO_MATCH_WEEK_START) == 0)
state = STATE_TWO_MATCH_WEEK_START;
else if(strcmp(element_name, TAG_TWO_MATCH_WEEK_END) == 0)
@ -269,6 +283,7 @@ xml_league_read_end_element (GMarkupParseContext *context,
strcmp(element_name, TAG_ACTIVE) == 0 ||
strcmp(element_name, TAG_BREAK) == 0 ||
strcmp(element_name, TAG_JOINED_LEAGUE) == 0 ||
strcmp(element_name, TAG_NEW_TABLE) == 0 ||
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 ||
@ -324,10 +339,7 @@ xml_league_read_text (GMarkupParseContext *context,
float_value = (gfloat)g_ascii_strtod(buf, NULL);
if(state == STATE_NAME)
{
misc_string_assign(&new_league.name, buf);
misc_string_assign(&(league_table((&new_league))->name), buf);
}
else if(state == STATE_SHORT_NAME)
misc_string_assign(&new_league.short_name, buf);
else if(state == STATE_SID)
@ -358,6 +370,8 @@ xml_league_read_text (GMarkupParseContext *context,
&g_array_index(new_league.joined_leagues,
JoinedLeague,
new_league.joined_leagues->len - 1).sid, buf);
else if(state == STATE_NEW_TABLE)
g_array_index(new_league.new_tables, NewTable, new_league.new_tables->len - 1).add_week = int_value;
else if(state == STATE_TWO_MATCH_WEEK_START)
g_array_append_val(new_league.two_match_weeks[0], int_value);
else if(state == STATE_TWO_MATCH_WEEK_END)
@ -423,8 +437,6 @@ xml_league_read_text (GMarkupParseContext *context,
void
xml_league_read(const gchar *league_name, GArray *leagues)
{
gint i;
TableElement new_table_element;
gchar *file_name = file_find_support_file(league_name, FALSE);
GMarkupParser parser = {xml_league_read_start_element,
xml_league_read_end_element,
@ -462,15 +474,6 @@ xml_league_read(const gchar *league_name, GArray *leagues)
g_free(file_contents);
g_array_append_val(leagues, new_league);
for(i=0;i<g_array_index(leagues, League, leagues->len - 1).teams->len;i++)
{
new_table_element =
table_element_new(
&g_array_index(
g_array_index(
leagues, League, leagues->len - 1).teams, Team, i), i);
g_array_append_val(league_table((&g_array_index(leagues, League, leagues->len - 1)))->elements, new_table_element);
}
}
else
{

View File

@ -59,6 +59,8 @@ enum
TAG_LEAGUE_BREAK,
TAG_LEAGUE_JOINED_LEAGUE_SID,
TAG_LEAGUE_JOINED_LEAGUE_RR,
TAG_LEAGUE_NEW_TABLE_NAME,
TAG_LEAGUE_NEW_TABLE_ADD_WEEK,
TAG_LEAGUE_TWO_MATCH_WEEK_START,
TAG_LEAGUE_TWO_MATCH_WEEK_END,
TAG_LEAGUE_TABLE_FILE,
@ -82,9 +84,8 @@ xml_loadsave_league_start_element (GMarkupParseContext *context,
gint tag = xml_get_tag_from_name(element_name);
gboolean valid_tag = FALSE;
JoinedLeague new_joined_league;
NewTable new_table;
new_joined_league.sid = NULL;
for(i=TAG_LEAGUE;i<TAG_END;i++)
if(tag == i)
{
@ -108,6 +109,9 @@ xml_loadsave_league_start_element (GMarkupParseContext *context,
if(tag == TAG_LEAGUE_JOINED_LEAGUE_SID)
g_array_append_val(new_league->joined_leagues, new_joined_league);
if(tag == TAG_LEAGUE_NEW_TABLE_NAME)
g_array_append_val(new_league->new_tables, new_table);
if(debug > 100)
g_print("xml_loadsave_league_start_element: state %d\n", state);
@ -130,6 +134,8 @@ xml_loadsave_league_end_element (GMarkupParseContext *context,
tag == TAG_LEAGUE_BREAK ||
tag == TAG_LEAGUE_JOINED_LEAGUE_SID ||
tag == TAG_LEAGUE_JOINED_LEAGUE_RR ||
tag == TAG_LEAGUE_NEW_TABLE_NAME ||
tag == TAG_LEAGUE_NEW_TABLE_ADD_WEEK ||
tag == TAG_LEAGUE_TWO_MATCH_WEEK_START ||
tag == TAG_LEAGUE_TABLE_FILE ||
tag == TAG_LEAGUE_AVERAGE_TALENT ||
@ -214,15 +220,22 @@ xml_loadsave_league_text (GMarkupParseContext *context,
new_league->active = int_value;
else if(state == TAG_LEAGUE_BREAK)
new_league->rr_break = int_value;
else if(state == TAG_LEAGUE_JOINED_LEAGUE_SID)
misc_string_assign(
&g_array_index(new_league->joined_leagues,
JoinedLeague,
new_league->joined_leagues->len - 1).sid, buf);
else if(state == TAG_LEAGUE_JOINED_LEAGUE_SID)
g_array_index(new_league->joined_leagues,
JoinedLeague,
new_league->joined_leagues->len - 1).sid = g_strdup(buf);
else if(state == TAG_LEAGUE_JOINED_LEAGUE_RR)
g_array_index(new_league->joined_leagues,
JoinedLeague,
new_league->joined_leagues->len - 1).rr = int_value;
else if(state == TAG_LEAGUE_NEW_TABLE_NAME)
g_array_index(new_league->new_tables,
NewTable,
new_league->new_tables->len - 1).name = g_strdup(buf);
else if(state == TAG_LEAGUE_NEW_TABLE_ADD_WEEK)
g_array_index(new_league->new_tables,
NewTable,
new_league->new_tables->len - 1).add_week = int_value;
else if(state == TAG_LEAGUE_TWO_MATCH_WEEK_START)
g_array_append_val(new_league->two_match_weeks[0], int_value);
else if(state == TAG_LEAGUE_TWO_MATCH_WEEK_END)
@ -345,6 +358,12 @@ xml_loadsave_league_write(const gchar *prefix, const League *league)
xml_write_int(fil, g_array_index(league->joined_leagues, JoinedLeague, i).rr, TAG_LEAGUE_JOINED_LEAGUE_RR, I0);
}
for(i = 0; i < league->new_tables->len; i++)
{
xml_write_string(fil, g_array_index(league->new_tables, NewTable, i).name, TAG_LEAGUE_NEW_TABLE_NAME, I0);
xml_write_int(fil, g_array_index(league->new_tables, NewTable, i).add_week, TAG_LEAGUE_NEW_TABLE_ADD_WEEK, I0);
}
xml_write_float(fil, league->average_talent, TAG_LEAGUE_AVERAGE_TALENT, I0);
for(i=0;i<league->two_match_weeks[0]->len;i++)