We’re just beginning the third week of the RockPaperAzure Challenge, and Brian, Peter, and I are continually thinking of new features and capabilities to add. Just last week Brian opened up the game engine to support multiple different rounds, so people who are unfortunately not eligible to enter the competition (due to residency and age requirements or by having won prizes in previous weeks’ competitions) can still play along for bragging rights.
The newest drop of the Bot Lab code now includes projects for building your bot in VB.NET and F# (in addition to C#), along with sample code for the ‘house bots’: Random, Cycle, and BigBang. While it certainly wasn’t rocket surgery to get these new implementations working, there were a couple of things I discovered in the process that I thought would be worth mentioning.
Customizing the My Namespace in Visual Basic
While this list is subject to change, we do not allow any classes/methods from System.IO, System.Net, System.Reflection, System.Threading, System.Diagnostics, or System.GC. If you receive an error upon uploading and need more information, drop us a note at firstname.lastname@example.org.
Of course I was aware of that, but I was a little surprised to see my Random implementation:
' Random sample implementation Public Function MakeMove(you As IPlayer, opponent As IPlayer, rules As GameRules) As Move _ Implements IRockPaperScissorsBot.MakeMove Return Moves.GetRandomMove() End Function
rejected in the submission page:
Since I have admin access to the game site, I was able to look at the Gendarme output and noticed the following:
MyBotVB ------------------------------------------------------------ 1. NoReflection Problem: Reflection not allowed. * Severity: High, Confidence: High * Target: T RockPaperAzure.My.MyProject/MyWebServices::Create__Instance__(T) * Source: debugging symbols unavailable, IL offset 0x000e * Details: You are calling to !!0 System.Activator::CreateInstance
(), which is a potentially problematic method Solution: Remove reflection.
Well the solution is pretty clear, but WHAT REFLECTION?!
The clue is in
MyWebServices is nothing I'm using explicitly, it’s a freebie in Visual Basic that’s part of the My namespace and obviously does some reflection under the hood. The good news is that you can turn this off by setting a compilation variable. In the MyBotVB project of the MyBot solution, I’ve set the custom constant _MYTYPE to the value Empty via the Advance Compile Options… dialog of the project properties page. Doing so eliminates the My namespace and all associated objects from the compiler output, but there is a bit more granularity available as you can read in the MSDN reference page.
We had a couple of folks ask about F# support over the last week or two, and while F# is supported in Windows Azure (there’s an option for creating F# Worker Roles right in the File->New dialogs) there was a catch – our old friend Copy Local. When you create an F# project, the core assembly reference you’ll end up adding is, well, FSharp.Core, and since it’s not in the GAC in Windows Azure, you’ll get an unresolved reference at runtime. In terms of bot projects, I was finding all of my moves to be Exception moves!
Since your bot code is being loaded by either the Bot Lab or the main RockPaperAzure site, there wasn’t a lot you could do since it was up to either Bot Lab or RockPaperAzure.com to set up the appropriate environment. If you’re F# savvy, you might have known that you can embed the runtime statically with your appplication or assembly via the standalone compiler command-line option, and that indeed works from a technical perspective; however, there is a restriction on bot size that you can upload (< 100K), and statically linking the F# libraries bloats your bot assembly to well over 800K, making it not a viable option for RockPaperAzure.
So the upshot is that once you download the new Bot Lab distribution, you don’t have to do anything special… other than write your own killer F# code. Just for grins, I’m including the implementation of the ‘house bot’ named Cycle here. I’m sure some of you could tweak this to be even more F#-y!
namespace RockPaperAzure open RockPaperScissorsPro type MyBot() = class interface IRockPaperScissorsBot with member this.MakeMove(y, o, r) = this.MakeMove(y, o, r) end // Cycle sample implementation member this.MakeMove(you: IPlayer, opponent: IPlayer, rules: GameRules) = match (match you.LastMove with | null -> "" | _ -> you.LastMove.ToString().ToLower()) with | "rock" -> Moves.Paper | "paper" -> Moves.Scissors | "scissors" -> if you.HasDynamite then Moves.Dynamite else Moves.WaterBalloon | "dynamite" -> Moves.WaterBalloon | _ -> Moves.Rock end