Saturday, August 23, 2008

Adventures in F# - A port of the simplest Herbivore

Following the past of my previous post, this time I present a barebones stripped-down version of the Herbivore that ships with the Terrarium SDK. The code is will equip you with a compilable herbivore, which however does nothing but sit in your terrarium. Just like in the previous post, I did not strip out some of the inline comments, which may be helpful to some of us.

So here comes the code ...
namespace CBHerbivore

#light
#r "E:\\Development\\my fsharp\\Terrarium\\Terrarium\\OrganismBase.dll"

open System;;
open System.Drawing;;
open System.Collections;;
open System.IO;;
open OrganismBase;;



//Sample Herbivore
//The following Assembly attributes must be applied to each
//Organism Assembly


[<assembly: OrganismClass("CBHerbivore.CBHerbivore")>]
//The class that derives from Animal
[<assembly: AuthorInformation("Christian Bitter", "x@y.z")>]
//It's an herbivore
[<CarnivoreAttribute(false)>]

//This value must be between 24 and 48, 24 means faster
//reproduction
//while 48 would give more defense and attack power
//Make it smaller for reproduction

[<MatureSize(26)>]

//AnimalSkin = AnimalSkinFamilyEnum.Beetle, you can be a Beetle
//an Ant, a Scorpion, an Inchworm, or a Spider
//MarkingColor = KnownColor.Red, you can choose to mark your
//creature with a color.
//This does not affect appearance in the game.

[<AnimalSkin(AnimalSkinFamily.Beetle)>]
[<MarkingColor(KnownColor.Red)>]

//You get 100 points to distribute among these attributes to define
//what your organism can do.
//Choose them based on the strategy your organism will use.
//This organism hides and has good eyesight to find plants.

[<MaximumEnergyPoints(0)>]

//Don't need to increase this as it just sits next to plants

[<EatingSpeedPoints(0)>] //Ditto
[<AttackDamagePoints(0)>] //Doesn't ever attack
[<DefendDamagePoints(0)>]
//This attribute changes the skin of our herbivore,
//which is now going to be a beetle.
//Point Based Attributes
//Doesn't even defend

[<MaximumSpeedPoints(0)>] //Doesn't need to move quickly
[<CamouflagePoints(50)>] //Try to remain hidden
[<EyesightPoints(50)>] //Need this to find plants better


type CBHerbivore () =  
  inherit Animal() 
  override sh.Initialize() = () 
  override sh.SerializeAnimal (m:MemoryStream) = () 
  override sh.DeserializeAnimal (m:MemoryStream) = ()

As you may see, the main difference between this herbivore and the previous plant, is the base type our herbivore type needs to implement, and some attributes declared on our animal. In this case the abstract Animal class, declares 3 abstract members (Initialize, SerializeAnimal, DesirializeAnimal), which need to be implemented by our herbivor. Attributes control some of the properties of our herbivore, such as its moving speed, etc. 

Again, if you compile this type and introduce it to your terrarium, do not be surprised, to see, that the animal is stiff and not moving like an animal during hibernation. This is due to not implemented event handlers. These event handlers are responsible for your animal's interaction with its environment.

Adventures in F# - A Plant for Terrarium 2

Recently, my beloved Terrarium-game has reappeared from the neatherworlds of software. As some of you may know, Terrarium's intend was to showcase the back then rather new and exciting .NET platform version 1.x (not that it is not still exciting). Although from a gamer's perspective, the graphics weren't all to great, from a technology standpoint, it featured great things, such as Webservices, Reflection, etc.

At some point Terrarium ceased to exist, which was a shame, since the community was quite active developing plants, herbivores and carnivores for the virtual ecosystem that Terrarium simulates. I for myself, developed some simple creatures too (a simple decision-based/state-based agent), as part of a project I did during university for my AI course. More advanced (in comparison to my creature) could be imported showcasing great AI stuff such as A*, neural networks, planning, etc.

However, in an community effort, Terrarium was relaunched lately on codeplex and will hopefully see great new additions, such as a port to a more current version of the .NET platform and DirectX.

In a small attempt I tried to put my superficial F#  skills to work, and decided to port a plant organism to F#. My attempt can be seen in the following lines of code. For a C# version, see the codeplex discussion here. I decided to leave the comments from the discussion as is.

namespace CBPlant

We open a namespace for the plant organism


#light
#r "E:\\Path to OrganismBase.dll\\OrganismBase.dll"

We set the environment to lightweight and reference the OrganismBase.dll, which contains all the Terrarium2 stuff.


open System;;
open System.Drawing;;
open System.Collections;;
open System.IO;;
open OrganismBase;;


We open some namespaces, which we are going to use later and dive right into the code.

// Sample Herbivore

//Strategy

//This animal moves until it finds a food source and

//then stays there

// The following Assembly attributes must be applied to each

//Organism Assembly
[<assembly: OrganismClass("CBPlant.CBPlant")>] // The class that derives from Animal
[<assembly: AuthorInformation("XYZ", "x@y.z")>] // Provide Author Information
do()

Assembly-level attributes have to be declared via a global do() statement. See the discussion here.

//3.2 Plants 
//The definition of a plant is relatively easy since plants do not have to have any sort of movement defined to allow them to locate sources of food. 
//Each plant has three basic functions: 
//1. Grow 
//2. Reproduce by spreading seeds 
//3. Be eaten by herbivores 
//A plant organism does not need to contain any methods, it just has three properties that define how a plant functions. 
//4 
//1. The “MaximumEnergyPoints” property allows the developer to state how many energy points a herbivore will gain by consuming this plant. The maximum allowed is 10. 
//2. The “MatureSize” property which must be a number between 24 and 48 states the maximum size a plant can grow to when it has survived for some amount of time without being consumed. The smaller a plant is, the faster it will be able to reproduce. As a plant gets larger it will become easier for herbivores to see and will more likely be consumed. 
//3. The “SeedSpreadDistanceAttribute” states the maximum distance a plant can spread seeds from its current location. The maximum allowed is 100. These three properties alone are enough to define a functioning plant for the Terrarium game. 
// This value must be between 26 and 48, 26 means faster reproduction 
// while 48 would give more defense and attack power 
// Make it smaller for reproduction*) 
[<MatureSize(26)&gt;] 
[<SeedSpreadDistance(100)>

// Point Based Attributes 
// You get 100 points to distribute among these attributes to define 
// what your organism can do.Choose them based on the strategy your organism 
// will use. This organism hides and has good eyesight to find plants
[<MaximumEnergyPoints(10)>] 

type CBPlant () = 
  inherit Plant ()
  override cb.SerializePlant (m:MemoryStream) = ()
  override cb.DeserializePlant (m:MemoryStream) = ()
;;

We define a new plant type, called CBPlant (full CBPlant.CBPlant). This type is a subclass of the abstract class Plant. We have to implement Plant's two abstract members, which according to the example is just an empty method body. If we compile this by invoking

fsc OrganismBase.dll CBPlant.fs -a

A new library will be created, containing just this simple type.

Hopefully, I will get to play some more with F# and Terrarium doing some other stuff, like porting the Herbivore, Carnivore and start to add some real behaviour. 

Adventures in F# - F# and ADO.NET

Today's post is rather simplistic in what it does, but it illustrates some key language elements of F#, such as exception handling. 

The task to accomplish is quite it easy, nameley, to connect to a SQL Server 2005 database called "TestDB" on my local machine, using ADO.NET to pull out some rows of the "Person" table having the following schema:

Person (

  PersonID: int;

  FirstName nvarchar(50);

  LastName nvarchar (50);

  Street nvarchar(50);

  City nvarchar(50);

  ZIP int

)

The code we use in F# is a rather straightforward conversion of some typical C# code, and as such is probably not the best way to do things, but it gets the task done, and may illustate the point.

#light

We use the lightweight syntax option.

open System.Data;
open System;
open System.Data.SqlClient;

As a next step, we have to open the correct namespaces.

let ADONetTest = 
  let conStringBuilder = new SqlConnectionStringBuilder()
  conStringBuilder.IntegratedSecurity <- true
  conStringBuilder.["Data Source"] <- "localhost"
  conStringBuilder.InitialCatalog <- "TestDB"
  let con = new SqlConnection(conStringBuilder.ConnectionString)

These lines create the connection to the SQL Server 2005 database "TestDB" on my local machine. As you may see I use a mixture of passing values to properties (IntegratedSecurity, InitialCatalog) and the indexer (["Data Source"]) that is defined on the SqlConnectionStringBuilder type.


  try
    con.Open()
    let cmdString = "SELECT * FROM [dbo].[Person]"
    let cmd = new SqlCommand(cmdString, con)
    cmd.CommandType <- CommandType.Text
    using (cmd.ExecuteReader()) (fun reader ->
      if (reader.HasRows) then
        (
          printfn "Queried: %s" cmdString
          while (reader.Read()) do
            (
              let id = reader.GetInt32(0)
              let firstName = reader.GetString(1)
              let lastName = reader.GetString(2)
              let street = reader.GetString(3)
              let city = reader.GetString(4)
              let zip = reader.GetInt32(5) 
              printfn "%d %s %s %s %s %d" id firstName lastName street city zip
            )
          done
        )
      else (printfn "Empty result")
    )
    con.Close()
  with
    | :? System.Data.SqlClient.SqlException as sqlEx -> printfn "%A" sqlEx.Message
    | _ -> printfn "Unknown Exception"
 

  (con :> IDisposable).Dispose ()
;;

This part is responsible for the main functionality. We open the previously specified connection. We do this in a try-with block, to be prepared in case of exceptions. We actually try to handle one exceptio, the SqlExceptio. In the with block, we use type/pattern matching rule (|:? SqlException) to catch this particular exception. Since we do not have a handling strategy in place, a printf command is issued.The next with rule gets executed on whatever type not matching SqlException. We indicate that we do not even care about what it is (| _) using an anonymous rule.

Inside our try block, we declare a SqlCommand and pass in the Sql query stored in the cmdString. variable. This command encapsulates a Select-From-Where SQL-query. We execute the query, using one of F#'s equivalent's of the C# using statement - the using statement (the other one would be use).

The using keeps track for us, that in the case of an exception the "Dispose" method of the object used in the using statement is called - in this case it would be the Dispose declared by the result of  SqlCommand.ExecuteReader() - a DataReader object.

Inside the using block, it is asked whether the result of the query (DataReader) actually has rows that were returned by our particular query. This is done by if (reader.HasRows) then () else ().In case rows were returned by that query,they are enumerated by the while do () done loop. This loop does nothing but print each row present in the DataReader.

The last statement to mention is the  (con :> IDisposable).Dispose (). This statement casts the connection object into the IDisposable and calls the Dispose method on it. This has to be done, since it is not automatically called by a try-with block, and we have to ensure that all used objects are properly disposed of - espacially those that abstract native resources, such as database or file connections.

Wednesday, August 20, 2008

Small one - SourceSafe via command line

Yes, I haven't been blogging for quite a bit and this small post is not going to change that but at least it is a little somethin'. I've been digging into F# and have had some great learning experience but this is nothing to really present now.

Today I show a little snippet that let's you load some project ("XYZ") from SourceSafe into a specific folder (<Target Directory>). This may come in handy in some sort of automatic build invironment.

At first you need to define, i.e. set as environment variables:
1. SourceSafe User Account, supplied with sufficient privileges to actually access the project you want to retrieve
2. The account's password
3. The path to the SourceSafe DB's SourceSafe configuration file (srcsafe.ini)

Next you ask SourceSafe to change the working directory for the project, you are going to load. You do this via "ss Workfold".
The last step is to load/get the actual project into the working directory.


SET SSUSER=<your SourceSafe Account>
SET SSPWD=<your SourceSafe Account's Password>
SET SSDIR=<the path to your SourceSafe DB>

"SOURCESAFEDIR\ss.exe" Workfold $/<Path to XYZ>/XYZ "<Target Directory>"
"SOURCESAFEDIR\ss.exe" get $/<Path to XYZ>/XYZ -R


The only problem with this solution is, that SourceSafe is going to ask you, whether the intended working folder is the correct one. To fix this we include a change of the current directory into the <Target Directory> and everything will be fine.


SET SSUSER=<your SourceSafe Account>
SET SSPWD=<your SourceSafe Account's Password>
SET SSDIR=<the path to your SourceSafe DB>

cd "<Target Directory>"

"SOURCESAFEDIR\ss.exe" Workfold $/<Path to XYZ>/XYZ "<Target Directory>"
"SOURCESAFEDIR\ss.exe" get $/<Path to XYZ>/XYZ -R


Another way to accomplish this sort of automatic build environment is by the use of SourceSafe initialization variables. These let one configure the SourceSafe environment. By specifying a custom SourceSafe initialization file, one may configure all aspects to one's needs.