I recently attended one of the Rock, Paper, Azure! training sessions. Fun times. We learned how to quickly build, test Azure applications locally, and deploy them to the internet. However, I was perplexed by some of the MyBot API features. My naive .Net coding attempts were clearly not working once deployed on Azure. This article explains the problem using a not thread safe .NET Random() implementation. Finally, we show how to create an Azure thread safe full implementation of System.Random().
The basic Rock, Paper, Azure! ideas are for using API features from the reference library RockPaperScissorsPro.RPA. Trainees implement various strategies for playing the game inside a MakeMove() method. The method signature is:
public Move MakeMove(IPlayer you, IPlayer opponent, GameRules rules)
In this blog article we have three examples. (1) The NotRandom class shows the problems with non-thread safe coding of Random() and bad results running on Azure. (2) The MovesRandom class shows a working example with the very simple Rock, Paper, Azure! API random integer method. (3) The final DNetRandom and RandomGenerator classes show a working example with full System.Random() features, and safe for running on Azure.
Here we go….
Example One – NotRandom
This example shows one naive attempt to implement System.Random(). There are lots of ways to do it wrong. In this case we re-seed the Random() function using a sequence (not thread safe) and select the NextDouble() for game play. What we expect is 25% of the time getting Scissors, and 75% of the time choosing Paper.
Source code for the NotRandom.cs class follows:
using RockPaperScissorsPro;
using System;
namespace RockPaperAzure
{
public class NotRandom : IRockPaperScissorsBot
{
private static int mSeed = 0;
// Random sample implementation
public Move MakeMove(IPlayer you, IPlayer opponent, GameRules rules)
{
Move rtn;
// seed, Int32.MaxValue == 2,147,483,647
if (mSeed >= Int32.MaxValue)
mSeed = 0;
Random rand = new Random(mSeed++);
// returns a random number between 0.0 and 1.0
double randDouble = rand.NextDouble();
// THIS IS FAIL
if (randDouble > 0.25)
rtn = Moves.Paper;
else
rtn = Moves.Scissors;
return rtn;
}
}
}
This simply does *not* work. First we load all three libraries in the Bot Lab either locally or in Azure. We click the Start Battle button to generate game results. The load & game results are shown here:

The problem with the naive (non thread safe) random generation is shown in the logs. The NotRandom distribution we get is a repeated pattern of five or six Scissors (~25%) & Paper pairs, followed by twelve Papers (~75%), and it repeats for the entire series. Yuck! An example from the NotRandom log (in second column) is shown in this image:

How do we fix this?
Example Two – MovesRandom
This example shows using the Rock, Paper, Scissors! API with method generating an Int32 random number, e.g. Moves.GetRandomNumber(int max). This simple implementation works, but is very basic providing only integers. What we get is 25% of the time choosing Scissors, and 75% of the time choosing Paper.
Source code for the MovesRandom.cs class follows:
using RockPaperScissorsPro;
using System;
namespace RockPaperAzure
{
public class MovesRandom : IRockPaperScissorsBot
{
// Random sample implementation
public Move MakeMove(IPlayer you, IPlayer opponent, GameRules rules)
{
Move mReturn;
// APPEARS WORKING
int random = Moves.GetRandomNumber(100);
if (random > 25)
mReturn = Moves.Paper;
else
mReturn = Moves.Scissors;
return mReturn;
}
}
}
This works, but is too basic, providing only random integers. An example from the MovesRandom log (in second column) is shown in this image:

Working, but this Int32 random function is too basic for my needs.
Example Three – DNetRandom
The final example shows a working, complete implementation .NET System.Random(). This implementation is thread safe for Azure, and provides all the functionality of System.Random(). We get the same 25% of the time choosing Scissors, and 75% of the time choosing Paper.
Source code for the DNetRandom.cs class follows:
using RockPaperScissorsPro;
using System;
namespace RockPaperAzure
{
public class DNetRandom : IRockPaperScissorsBot
{
// Random sample implementation
public Move MakeMove(IPlayer you, IPlayer opponent, GameRules rules)
{
Move mReturn;
double random = RandomGenerator.NextDouble();
// this is pass
if (random > 0.25)
mReturn = Moves.Paper;
else
mReturn = Moves.Scissors;
return mReturn;
}
}
}
You need the thread safe RandomGenerator.NextDouble() implementation in the RandomGeneration.cs class. The source code follows:
using System;
namespace RockPaperAzure
{
internal static class RandomGenerator
{
// Fields
private static Random _global = new Random();
// indicates that the value of a static field is unique for each thread
[ThreadStatic]
private static Random _local;
// Methods
public static double NextDouble()
{
return getLocal().NextDouble();
}
// Methods
public static int Next()
{
return getLocal().Next();
}
// Methods
public static int Next(int maxValue)
{
return getLocal().Next(maxValue);
}
// Methods
public static int Next(int minValue, int maxValue)
{
return getLocal().Next(minValue, maxValue);
}
// Methods
public static void NextBytes(byte[] buffer)
{
getLocal().NextBytes(buffer);
}
private static Random getLocal()
{
Random random = _local;
if (random == null)
{
int num;
// The lock keyword ensures that one thread does
// not enter a critical section of code while
// another thread is in the critical section.
// If another thread tries to enter a locked code,
// it will wait, block, until the object is released.
lock (_global)
{
num = _global.Next();
}
_local = random = new Random(num);
}
return random;
}
}
}
The getLocal() method and [ThreadStatic] decorator expose the *tricks* (or features) required to write the Random() implementation in a thread safe Azure way. Check MSDN documentation for the Lock Statement. You will need to create your own MyBot projects (libraries) with these classes, make minor name changes in the factory classes, and add project references for the Rock, Paper, Azure! library APIs.
This final example provides a full System.Random() thread safe implementation. An example from the DNetRandom log (in second column) is shown in this image:

This article might help you code thread safe implementations of other .Net methods for your Rock, Paper, Azure! games. You can use the same pattern and techniques. Be careful not to lock threads for too long or Azure will kill your threads – and you may lose the game.
Hope this helps!
m