Friday, March 14, 2014

Implementing ELO Ratings

I've been planning for quite some time to implement an ELO Rating system in my World Cup project to predict the strength of foot ball teams. ELO is a method of calculating the relative strength of players. Therefore, you'd expect Brazil and Spain to have high ELO ratings. While I need some tweaking to the formula to make some events more important (For example, a friendly international isn't as important to win as a World Cup Final). You can see these early ratings on the World Cup detail pages, for example, World Cup 2010.

The actual code to calculate the ELO Rating is below. It runs quick, processing all 800 games I have in my database in less than a second. 

  /// <summary>
        ///  Updates the scores in the matchup object. 
        /// </summary>
        /// <param name="matchup">The Matchup to update</param>
        /// <param name="user1WonMatch">Whether User 1 was the winner (if both user 1 and user 2 are false, it's a draw)</param>
        /// <param name="user2WonMatch">Whether User 2 was the winner</param>
        /// <param name="diff">The desired Diff, currently a constant of 400</param>
        /// <param name="kFactor">The K factor. My K factor currently takes into account the type of game & the goals difference</param>
        /// <returns></returns>
        public static Matchup UpdateEloRatingScores(Matchup matchup, bool user1WonMatch, bool user2WonMatch, double diff, double kFactor)
        {
            // player A rating
            double User1ScoreDouble = Convert.ToDouble(matchup.User1Score);
            // player B rating
            double User2ScoreDouble = Convert.ToDouble(matchup.User2Score);

            //expected score for player A = 1 / (1 + 10 ^ ((player A rating - player B rating) / 400 ))
            double player1ExpectedScore = 1d / Convert.ToDouble(1d + Math.Pow(10d, ((User2ScoreDouble - User1ScoreDouble) / diff)));
            //expected score for player B = 1 / (1 + 10 ^ ((player B rating - player A rating) / 400 ))
            double player2ExpectedScore = 1d / Convert.ToDouble(1d + Math.Pow(10d, ((User1ScoreDouble - User2ScoreDouble) / diff)));

            double user1Result = 0;
            double user2Result = 0;
            if (user1WonMatch == true)
            {
                user1Result = 1;
            }
            else if (user2WonMatch == true)
            {
                user2Result = 1;
            }
            else //split the result evenly for a draw
            {
                user1Result = 0.5;
                user2Result = 0.5;
            }

            //player new rating = [player A current rating] + [K Factor] ( userResult - playerExpectedScore )
            matchup.User1Score = Convert.ToInt32(Math.Round(Convert.ToDouble(matchup.User1Score) + kFactor * (user1Result - player1ExpectedScore)));
            matchup.User2Score = Convert.ToInt32(Math.Round(Convert.ToDouble(matchup.User2Score) + kFactor * (user2Result - player2ExpectedScore)));

            return matchup;
        }

Friday, March 7, 2014

XML Serialization: Making the call generic.

I've been experimenting with XML serialization quite a bit lately. It's working really well, consuming my xml calls. In the code example below.


public PlayerStatistic LoadPlayerStats(string xmlString)
{
    PlayerStatistic xmlToLoad = new PlayerStatistic();
    if (string.IsNullOrEmpty(xmlString) == false)
    {
        // convert string to stream
        byte[] byteArray = Encoding.UTF8.GetBytes(xmlString);
        MemoryStream stream = new MemoryStream(byteArray);

        // load into a streamreader and then deserialize
        StreamReader streamReader = new StreamReader(stream);
        XmlSerializer reader = new XmlSerializer(typeof(PlayerStatistic));
        return (PlayerStatistic)reader.Deserialize(streamReader);
    }
    else
    {
        return null;
    }
}


This is great, but as I needed to deserialize other documents, I found myself writing the same code, over and over. Enter Generics. I can write a generic version that I can pass the datatype into.

public T LoadXML<T>(string xmlString)
{
    if (string.IsNullOrEmpty(xmlString) == false)
    {
        // convert string to stream
        byte[] byteArray = Encoding.UTF8.GetBytes(xmlString);
        MemoryStream stream = new MemoryStream(byteArray);

        // load into a streamreader and then deserialize
        StreamReader streamReader = new StreamReader(stream);
        XmlSerializer reader = new XmlSerializer(typeof(T));
        return (T)reader.Deserialize(streamReader);
    }
    else
    {
        return default(T);
    }
}


To call this, using the example above, it's as simple as:

PlayerStatistic LoadXML<RawPlayerAchievementsForApp.PlayerStatistic>(rawXMLString);

Friday, February 28, 2014

Introduction

I'm a software developer. I've been one since I started my first job at a small firm in Christchurch, New Zealand, in 2000. In 2003 I moved to Boston, USA, and I've been here ever since. 

I'm hoping to use this blog to write about what I'm doing here, interesting problems, interesting solutions and anything else development related.

I mostly use C# and MSSQL, but I also write a little HTML, CSS, JavaScript, and occasionally, VB.NET.