module elo.rating; import std.math; /// struct RatingSystem { /// public enum Result { Win, Draw, Loss, } // Score constants private enum double[3] SCORE = [1.0,0.5,0.0]; /// public static int GetNewRating (int rating, int opponentRating, Result _result, double _kFactor = 30.0) { return GetNewRating (rating, opponentRating, SCORE[cast(int)_result], _kFactor); } private static int GetNewRating(int rating, int opponentRating, double score, double _kFactor) { double expectedScore = GetExpectedScore(rating, opponentRating); int newRating = CalculateNewRating(rating, score, expectedScore, _kFactor); return newRating; } private static double GetExpectedScore (int rating, int opponentRating) { return 1.0 / (1.0 + pow(10.0, (cast(double) (opponentRating - rating) / 400.0))); } private static int CalculateNewRating(int oldRating, double score, double expectedScore, double _kFactor) { return oldRating + cast(int) (_kFactor * (score - expectedScore)); } } unittest { assert(RatingSystem.GetNewRating(1500,1500,RatingSystem.Result.Win) == 1515); assert(RatingSystem.GetNewRating(1500,1500,RatingSystem.Result.Loss) == 1485); assert(RatingSystem.GetNewRating(1500,1500,RatingSystem.Result.Draw) == 1500); }