Tuesday, July 28, 2009

A Checkers Rules Engine in C#

One of the things I've always wanted to program is a game using a Genetic Algorithm to generate the AI. Well at work I was talking about AI coding and my aforementioned desire came up and as we talked about it, the idea of using game of Checkers as the game I could use with a GA surfaced.

When I got home that evening and was relaxing after diner, I booted up the laptop and started cruising around the web. I was started looking around for a rules engine for checkers - hopefully in C#. You see my thought was, if I could find a rules engine that, from a given game board configuration and who's move it was, it would output all valid moves.

Well, no matter how I arranged the words in Google, I could not find a rules engine for checkers. I found a few complete C# checkers games but the rules were too integrated into the rest of the game for me to filter out.

So, I decided to write one.

I started with an enum to define the two players:
public enum PlayerColors { Black, Red }

Then I wrote a class to hold each checker piece:

CheckerPiece has a single constructor:
CheckerPiece(PlayerColors MyPlayerColor, int MyPieceLocation, bool MyIsKing)

Four properties:
public int PieceLocation { get; set; }
public bool IsKing { get; set; }
public PlayerColors PlayerColor { get; set; }
public List PossibleMoveLocations { get; set; }

and Three methods:
public char GetPlayCharacter()
public void FindAllMoves(char[] GameboardArray)
public void FindAllJumps(char[] GameboardArray)

The constructor sets the PlayerColor, PieceLocation, and IsKing.

PlayerColor defines which side the piece belongs to.
PieceLocation is an int from 0 to 63 defining each square of the game board.
IsKing is a bool that determines if the piece is a king or not.

GetPlayCharacter returns a lowercase r for a red piece, a lowercase b for a black piece, an uppercase R for a red king piece and an uppercase B for a black king piece.

a game board array is a char[64] array that can hold on of these chars 'r', 'R', 'b', 'B' or ' ' (a space).

FindAllMoves and FindAlJumps take in a GameboardArray and sets the PossibleMoveLocations list with all the possible Moves or Jumps.

Now with that built, I created the CheckersRulesEngine class.

CheckersRulesEngine has a single constructor:
public CheckersRulesEngine(char[] gameboardarray)

A static char array that holds a starting game board configuration for convenience:
static public readonly char[] StartingGameboardArray =
" b b b bb b b b b b b b r r r r r r r rr r r r ".ToCharArray();

Three properties:
public List MovablePieces { get; set; }
public List Pieces { get; set; }
public char[] GameboardArray { get; set; }

And Three Methods:
public void GetPiecesWithMoves(PlayerColors CurrentPlayer)
public void GetPiecesWithJumps(PlayerColors CurrentPlayer)
public string OutputAsciiBoard()

The constructor the GameboardArray and creates a CheckerPiece entry into Pieces for each piece defined in the GameboardArray.

GetPiecesWithMoves and GetPiecesWithJumps works its way through the Pieces collection and loads MovablePieces with the pieces that qualify.

OutputAsciiBoard is a helper function that outputs an ascii board showing the location of all the pieces.

You can get the c# code for the CheckersRulesEngine here! Or, you can download a Visual Studio 2008 solution that also includes a console program that plays a game of checkers against itself using random moves! The solution can be downloaded Here!

Tuesday, July 21, 2009

Widgets: Drag, drop and reorder. Simply done with JQUERY.

The heart of the Dropthings project, IGoogle or Pageflakes is the client side moving of the widgets. Be it dragging and dropping the widgets in other columns or reordering the widgets in a single column, this client side behaviour it the flashy part of the widget system.

In the Dropthings project the Author originally used the microsoft AJAX client side library along with quite a bit of his own code. No critisim here, he coded a complex cross-browser system that WORKED! I would not even have tried.

But, in the latest addition it says that the code was converted over to JQUERY. Well I looked at that code and while he may have converted to use JQUERY, he is not really USING JQUERY. Most of his system is still in place. No problem with that, unless you are not the Author and want to modify or enhance it.

I went another route: pure JQUERY. With just a few lines of code and a bit of AJAX to update the server I got all that functionality without all the complexity. Here it is:

        $(document).ready(function() {
$(".DropZone").sortable({
opacity: 0.5,
smooth: true,
helper: "clone",
handle: ".WidgetHeader",
connectWith: ".DropZone",
placeholder: "WidgetSortPlaceholderHighlight",
forcePlaceholderSize: true,
stop: function(event, ui) {
callMyService();
}
});
});


Thats it. You now have multi column drag and drop support. Just have your div's associated with the DropZone class and the Header of the WidgetContainer associated with the WidgetHeader class. My OnStop call to callMyService() walks through all the .DropZone controls and gets the ID of the Widget, the ID of the DropZone and the index (the order of the widgets) and calls the Webservice to update the database.

Here is a link to a working minimum example.

Thursday, July 16, 2009

A c# class to convert between bases

Ever needed to work with numbers in base 17, or base 3? I have always wanted to write a Genetic algorithm that used base 3 numbers to represent the board - 0 empty, 1 my piece, 2 opponent piece. Recently at work, we needed to work with base 36 numbers. While doing some searching I also learned that some people needed numbers that were alpha-int (Where the letters preceded the numbers) instead of the standard int-alpha.

Here is a class that I think Microsoft left out. We work different systems and different numbers every day, so why didn't Microsoft include a base converter class? It probably was just too low on their list of priorities.

Well, here is my interpretation. It is a static class that exposes three overloaded functions:
Encode(long Value, sbyte Base)
Encode(long Value, sbyte Base, bool NumeralsFirst)
Decode(string Input, sbyte Base)
Decode(string Input, sbyte Base, bool NumeralsFirst)
BetweenBases(string Value, sbyte FromBase, sbyte ToBase)
BetweenBases(string Value, sbyte FromBase, sbyte ToBase, bool NumeralsFirst)

By using the BetweenBases function, you can convert directly from one base to another without decoding to a long in between.

The complete code for the class can be downloaded here.