mirror of
https://github.com/furyfire/trueskill.git
synced 2025-01-16 01:47:39 +00:00
93 lines
4.0 KiB
C#
93 lines
4.0 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
namespace Moserware.Skills
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Base class for all skill calculator implementations.
|
|||
|
/// </summary>
|
|||
|
public abstract class SkillCalculator
|
|||
|
{
|
|||
|
[Flags]
|
|||
|
public enum SupportedOptions
|
|||
|
{
|
|||
|
None = 0x00,
|
|||
|
PartialPlay = 0x01,
|
|||
|
PartialUpdate = 0x02,
|
|||
|
}
|
|||
|
|
|||
|
private readonly SupportedOptions _SupportedOptions;
|
|||
|
private readonly PlayersRange _PlayersPerTeamAllowed;
|
|||
|
private readonly TeamsRange _TotalTeamsAllowed;
|
|||
|
|
|||
|
protected SkillCalculator(SupportedOptions supportedOptions, TeamsRange totalTeamsAllowed, PlayersRange playerPerTeamAllowed)
|
|||
|
{
|
|||
|
_SupportedOptions = supportedOptions;
|
|||
|
_TotalTeamsAllowed = totalTeamsAllowed;
|
|||
|
_PlayersPerTeamAllowed = playerPerTeamAllowed;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Calculates new ratings based on the prior ratings and team ranks.
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="TPlayer">The underlying type of the player.</typeparam>
|
|||
|
/// <param name="gameInfo">Parameters for the game.</param>
|
|||
|
/// <param name="teams">A mapping of team players and their ratings.</param>
|
|||
|
/// <param name="teamRanks">The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2)</param>
|
|||
|
/// <returns>All the players and their new ratings.</returns>
|
|||
|
public abstract IDictionary<TPlayer, Rating> CalculateNewRatings<TPlayer>(GameInfo gameInfo,
|
|||
|
IEnumerable
|
|||
|
<IDictionary<TPlayer, Rating>>
|
|||
|
teams,
|
|||
|
params int[] teamRanks);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Calculates the match quality as the likelihood of all teams drawing.
|
|||
|
/// </summary>
|
|||
|
/// <typeparam name="TPlayer">The underlying type of the player.</typeparam>
|
|||
|
/// <param name="gameInfo">Parameters for the game.</param>
|
|||
|
/// <param name="teams">A mapping of team players and their ratings.</param>
|
|||
|
/// <returns>The quality of the match between the teams as a percentage (0% = bad, 100% = well matched).</returns>
|
|||
|
public abstract double CalculateMatchQuality<TPlayer>(GameInfo gameInfo,
|
|||
|
IEnumerable<IDictionary<TPlayer, Rating>> teams);
|
|||
|
|
|||
|
public bool IsSupported(SupportedOptions option)
|
|||
|
{
|
|||
|
return (_SupportedOptions & option) == option;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Helper function to square the <paramref name="value"/>.
|
|||
|
/// </summary>
|
|||
|
/// <returns><param name="value"/> * <param name="value"/></returns>
|
|||
|
protected static double Square(double value)
|
|||
|
{
|
|||
|
return value*value;
|
|||
|
}
|
|||
|
|
|||
|
protected void ValidateTeamCountAndPlayersCountPerTeam<TPlayer>(IEnumerable<IDictionary<TPlayer, Rating>> teams)
|
|||
|
{
|
|||
|
ValidateTeamCountAndPlayersCountPerTeam(teams, _TotalTeamsAllowed, _PlayersPerTeamAllowed);
|
|||
|
}
|
|||
|
|
|||
|
private static void ValidateTeamCountAndPlayersCountPerTeam<TPlayer>(
|
|||
|
IEnumerable<IDictionary<TPlayer, Rating>> teams, TeamsRange totalTeams, PlayersRange playersPerTeam)
|
|||
|
{
|
|||
|
Guard.ArgumentNotNull(teams, "teams");
|
|||
|
int countOfTeams = 0;
|
|||
|
foreach (var currentTeam in teams)
|
|||
|
{
|
|||
|
if (!playersPerTeam.IsInRange(currentTeam.Count))
|
|||
|
{
|
|||
|
throw new ArgumentException();
|
|||
|
}
|
|||
|
countOfTeams++;
|
|||
|
}
|
|||
|
|
|||
|
if (!totalTeams.IsInRange(countOfTeams))
|
|||
|
{
|
|||
|
throw new ArgumentException();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|