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(); } } } }