using System;
using System.Collections.Generic;
namespace Moserware.Skills
{
///
/// Base class for all skill calculator implementations.
///
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;
}
///
/// Calculates new ratings based on the prior ratings and team ranks.
///
/// The underlying type of the player.
/// Parameters for the game.
/// A mapping of team players and their ratings.
/// The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2)
/// All the players and their new ratings.
public abstract IDictionary CalculateNewRatings(GameInfo gameInfo,
IEnumerable
>
teams,
params int[] teamRanks);
///
/// Calculates the match quality as the likelihood of all teams drawing.
///
/// The underlying type of the player.
/// Parameters for the game.
/// A mapping of team players and their ratings.
/// The quality of the match between the teams as a percentage (0% = bad, 100% = well matched).
public abstract double CalculateMatchQuality(GameInfo gameInfo,
IEnumerable> teams);
public bool IsSupported(SupportedOptions option)
{
return (_SupportedOptions & option) == option;
}
///
/// Helper function to square the .
///
/// *
protected static double Square(double value)
{
return value*value;
}
protected void ValidateTeamCountAndPlayersCountPerTeam(IEnumerable> teams)
{
ValidateTeamCountAndPlayersCountPerTeam(teams, _TotalTeamsAllowed, _PlayersPerTeamAllowed);
}
private static void ValidateTeamCountAndPlayersCountPerTeam(
IEnumerable> 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();
}
}
}
}