1
1
mirror of https://github.com/tstellar/bygfoot.git synced 2025-02-03 17:27:31 +01:00
bygfoot/src/game.c
2005-01-10 15:37:30 +00:00

165 lines
5.4 KiB
C

#include "fixture.h"
#include "game.h"
#include "maths.h"
#include "player.h"
#include "team.h"
#include "variables.h"
/** Influence in % of the game style towards more attack.
@see game_get_values() */
#define CONSTANT_GAME_STYLE_FACTOR 0.075
/** How much a defender's worth when the team's defending or attacking.
@see game_get_player_contribution() */
#define CONSTANT_GAME_PLAYER_WEIGHT_DEFENDER_DEFEND 1
#define CONSTANT_GAME_PLAYER_WEIGHT_DEFENDER_ATTACK 0.25
/** How much a forward's worth when the team's defending or attacking.
@see game_get_player_contribution() */
#define CONSTANT_GAME_PLAYER_WEIGHT_FORWARD_DEFEND 0.2
#define CONSTANT_GAME_PLAYER_WEIGHT_FORWARD_ATTACK 1.3
/** How much a midfielder is worth both attacking and defending.
@see game_get_player_contribution() */
#define CONSTANT_GAME_PLAYER_WEIGHT_MIDFIELDER 0.625
/** Calculate attacking, defending and goalie values for the two teams
of a fixture.
@param fix The fixture we calculate.
@param team_value The place to store the values.
@param home_advantage The home advantage factor.
@see #GameTeamValue
*/
void
game_get_values(const Fixture *fix, gfloat team_values[][GAME_TEAM_VALUE_END],
gfloat home_advantage)
{
gint i, j;
Team *tm[2] = {fix->teams[0], fix->teams[1]};
gfloat style_factor;
printf("\nhome %.2f\n", home_advantage);
for(i=0;i<2;i++)
{
for(j=0;j<GAME_TEAM_VALUE_END;j++)
team_values[i][j] = 0;
style_factor = (gfloat)tm[i]->style * CONSTANT_GAME_STYLE_FACTOR;
team_values[i][GAME_TEAM_VALUE_GOALIE] =
game_get_player_contribution(player_of(tm[i], 0), FALSE) *
(1 + home_advantage * (i == 0)) *
(1 + CONSTANT_PLAYER_BOOST_SKILL_EFFECT * (tm[i] == my_team && options[OPT_BOOL_BOOST] == 1));
for(j=1;j<11;j++)
{
team_values[i][GAME_TEAM_VALUE_ATTACK] +=
game_get_player_contribution(player_of(tm[i], j), TRUE);
team_values[i][GAME_TEAM_VALUE_DEFEND] +=
game_get_player_contribution(player_of(tm[i], j), FALSE);
}
team_values[i][GAME_TEAM_VALUE_ATTACK] *=
((1 + style_factor) * (1 + home_advantage * (i == 0)) *
(1 + CONSTANT_PLAYER_BOOST_SKILL_EFFECT * (tm[i] == my_team && options[OPT_BOOL_BOOST] == 1)));
team_values[i][GAME_TEAM_VALUE_DEFEND] *=
((1 - style_factor) * (1 + home_advantage * (i == 0)) *
(1 + CONSTANT_PLAYER_BOOST_SKILL_EFFECT * (tm[i] == my_team && options[OPT_BOOL_BOOST] == 1)));
printf("%s attack %.1f defend %.1f\n", tm[i]->name->str, team_values[i][GAME_TEAM_VALUE_ATTACK],
team_values[i][GAME_TEAM_VALUE_DEFEND]);
}
}
/** Return the contribution of a player to the attack, defend or
goalie value of his team.
@param pl The player.
@param attack Whether we have attack or defend value.
@return The player's contribution depending on position and
fitness. */
gfloat
game_get_player_contribution(const Player *pl, gboolean attack)
{
gfloat weights[4] =
{1,
(attack) ? CONSTANT_GAME_PLAYER_WEIGHT_DEFENDER_ATTACK : CONSTANT_GAME_PLAYER_WEIGHT_DEFENDER_DEFEND,
CONSTANT_GAME_PLAYER_WEIGHT_MIDFIELDER,
(attack) ? CONSTANT_GAME_PLAYER_WEIGHT_FORWARD_ATTACK : CONSTANT_GAME_PLAYER_WEIGHT_FORWARD_DEFEND};
return (gfloat)(pl->cskill * powf((gfloat)pl->fitness / 100, CONSTANT_GAME_PLAYER_FITNESS_EXPONENT) *
weights[pl->pos]);
}
/** Return a random attacking or defending player
or the player that has to shoot the number_of_penalty'th penalty.
@param tm The team we examine.
@param player_type Whether we concentrate on attacking or defending players
or would like to have a penalty shooting player.
@param number_of_penalty Which penalty has to be taken (1st, 2nd etc.)
@param not_this_one A player to exclude.
@return A player index. */
gint
game_get_player(const Team *tm, gint player_type, gint number_of_penalty, gint not_this_one)
{
gint i, player = not_this_one;
gfloat weights[3];
gfloat probs[10];
gfloat rndom;
if(player_type == GAME_PLAYER_TYPE_ATTACKER)
{
weights[0] = 0.25;
weights[1] = 0.5;
weights[2] = 1;
}
else if(player_type == GAME_PLAYER_TYPE_ATTACKING)
{
weights[0] = 0.5;
weights[1] = 1;
weights[2] = 1;
}
else if(player_type == GAME_PLAYER_TYPE_DEFENDER)
{
weights[0] = 1;
weights[1] = 0.5;
weights[2] = 0.25;
}
else if(player_type == GAME_PLAYER_TYPE_INJURY)
weights[0] = -1;
else if(player_type == GAME_PLAYER_TYPE_PENALTY)
return 10;
game_get_player_probs(tm->players, probs, weights);
while(player == not_this_one)
{
rndom = math_rnd(0, probs[9]);
if(rndom < probs[0])
player = player_of(tm, 0)->id;
else
for(i=1;i<10;i++)
if(rndom < probs[i] && rndom > probs[i - 1])
player = player_of(tm, i + 1)->id;
}
return player;
}
void
game_get_player_probs(GArray *players, gfloat *probs, gfloat *weights)
{
gint i;
if(weights[0] == -1)
for(i=0;i<10;i++)
probs[i] = 1;
else
{
probs[0] = (gfloat)g_array_index(players, Player, 1).cskill *
powf((gfloat)g_array_index(players, Player, 1).fitness, CONSTANT_GAME_PLAYER_FITNESS_EXPONENT) *
weights[g_array_index(players, Player, 0).pos - 1];
for(i=1;i<10;i++)
probs[i] = probs[i - 1] + (gfloat)g_array_index(players, Player, i + 1).cskill *
powf((gfloat)g_array_index(players, Player, i + 1).fitness, CONSTANT_GAME_PLAYER_FITNESS_EXPONENT) *
weights[g_array_index(players, Player, i + 1).pos - 1];;
}
}