Usually, I do my work and fun in JVM-based languages like Scala or sometimes Clojure; however, I get this nagging feeling that I’m missing something if I don’t look at the world of .NET once in a while, too.
C# is boringly similar to Java, so let’s try out F# for a change.
First, bootup Windows. Next: installation stuff. Ugh.
Alright, now I’m ready to open Visual Studio and create a F# project. Nice.
Next, I have to install Robocode itself and the .NET plugin (both from here): First, call the Robocode JAR setup jar, then install the robocode.dotnet setup jar on top of the created Robocode directory. By the way, I’m loosely following the instructions in the awesome Robocode Wiki for these steps.
In the “New Project” wizard of Visual Studio, I select “F# Library”, as we want to create a class library, not an application. I call my project “SharpyTheFirst” (yeah, well). Up comes the editor. But I don’t have any reference to Robocode yet, so let’s create one.
From the wiki again: “You need to add a reference to the robocode.dll file located under the \libs folder of your home folder for Robocode”. Right, let’s do exactly that.
Also, let’s change the assembly name right now to conform to the Robocode conventions: Right-click the project, then under Properties, Application, set the assembly name (I set it to johofer.SharpyTheFirst_1.0).
We’re finally all set for some hackage.
I’ll create the johofer namespace, as it’s the convention to use one’s nick for Robocode robot namespaces, open the Robocode namespace for my perusal, and create a class inheriting from Robocode.Robot because that’s how simple Robocode robots work:
#light namespace johofer open Robocode type SharpyTheFirst() = inherit Robot()
This still displays an error because Robot seems to depend on System.Drawing, so let’s add System.Drawing to the dependencies, too.
Next, I have to find out how to override a method in F# (stuff you normally don’t need in functional languages). It seems I need the override keyword for this, and a “self identifier”. I’ll call the self identifier this. Then, I basically have to translate the C# robot initialization, main loop and event handling into F# syntax. You can marvel at my first attempt here:
#light namespace johofer open Robocode type SharpyTheFirst() = inherit Robot() override this.Run() = this.Initialize() this.MainLoop() member private this.Initialize() = this.TurnLeft (this.Heading - 90.0) this.TurnGunRight 90.0 member private this.MainLoop() = while true do this.ExecuteSingleStep() member private this.ExecuteSingleStep() = this.Ahead 5000.0 this.TurnRight 90.0 override this.OnScannedRobot e = this.Fire 1.0
Now that we have a robot with extremely basic functionality, let’s find out if it works… at all… – quickly build it in Visual Studio, and then, finally start up Robocode!
Alrighty. The wiki says that I have to add the path to my newly built assembly in the Robocode IDE under Options, Preferences, Development Options.
Now, I can start the battle. Is johofer available under packages? Yes, it is! Woot!
Let’s have a fight: johofer.SharpyTheFirst vs sample.Crazy! – And… SharpyTheFirst wins! Yay!
So, to recapitulate:
- Installed F#: Check.
- Installed Robocode: Check.
- Learnt how to do the ugly OO/inheritance stuff in F#: Check.
- Implemented basic robot: Check.
- Won a fight: Check.
That’s all for now. I hope you’ll try it out!