I've had fun developing this control and believe it will be useful for many reasons. The first and foremost reason is to get a good peer review. The second is to help share ideas, coding, and of course the code itself. I've been interested in chess for about 7 years now and you can say I'm quite addicted. The positive note is my wife would rather see me out playing chess on a Friday night vs drinking in a bar. I was about 80% done with my code when I noticed that Chris R. Chapman had put out his version of a control, using the famous Bitboards (Good job Chris!). So any one interested should check out his control as well. There are two main differences that you will note: Chris pre generates his attack boards where as I generate mine on the fly, I draw the chess board in an offscreen buffer then splash it to the screen, and finally I trap the mouse clicks and locate the corresponding squares.
In regards to the Bitboards I've always been curious to the differences in speed between the two approaches. There has been some arguments in the online 'chess' groups that the pre-generated versions are no faster than the build as you go, I personally have not tested this but now maybe I can. I've found my code to execute very nicely and do not see any performance problems. I believe if I change anything in performance it would be the mouse click / square location routines. I think simply dividing the board into quarters and associating each quarter with the underlying squares should speed things up some, but to be honest it runs pretty fast now so I may be lazy and skip this part. I have successfully validated quite a few different and weird checks, mates, and stalemates so I believe the move validation is pretty solid. If you find any problems let me know, email me FEN strings. You can find some of the FEN strings in the header for
I draw the chess board in the background and then splashed to the screen and this gives me pretty smooth piece movement. The intentions here were to give the drawing code the ability to be called from a web server for display on an HTML page. That's why it's hooked up to the FEN events, pass the string and generate the graphics. See below discussion on events.
There is also a PGN brute force parser that has example code in the demo program that converts the PGN to XML. It will save the file into the same location as the PGN but with the .XML extension. The intent here was to use the XML for the format in the background for displaying, navigating, and annotating chess games. It can also be used to display an annotated game in HTML with a little XSL processing (if anyone writes one let me know). I have some example pgn files saved in the directory with the control for testing, a couple with multiple variations and comments. The game navigation is the next thing I'm going to work on finishing. Please be aware that I'm unsure how the XML parser will work with a totally junked file and I have not tested it 100% as I'm just starting to working on the game navigation control.
Note the VCR buttons do not move through a game yet. I'm working on that in my spare time utilizing the XML generated above.
There is some cleanup I still need to perform so don't be too critical of the code.
I would recommend that you read articles on Bitboards and their use in chess computer. Crafty source code is an insane place to look if you enjoy reading C code. But the easiest method is to perform a simple search on the topic. But beware, you may get redirected to this very column where you will find yourself in a never ending do/while loop.
Seriously though I hope to show a use of interfaces and events in my first attempt and this article. In regards to interfaces and events, I find that they go very well together. I first think of the events I want a particular object to implement, then I group these event methods into an interface. I then define a bare minimum interface for the object itself in which I declare two methods:
removeEvents(ievents) where the parameter
ievents would be the event methods/interface I previously created. The body of the methods
removeEvents() simply hook/detach up all of the methods defined in the interface to the object producing the events.
To better understand my point look at the code in the file ChessInterfaces.cs. In particular find the
IPositionEvents interfaces. The
IPosition defines the methods that a class must implement to allow the events defined in
IPoisitionEvents to be hooked up and ready for action. Thus in the interface
IPosition we have the two methods named:
IPosition.removeEvents(IPositionEvents ievents) and
IPosition.addEvents(IPositionEvents ievents). Now open up the file FenNotation.cs. Here you will find
public class FenNotation : IPosition which wants other classes to be aware of his ability to parse a FEN string. Now open up the two files ChessBitmap.cs and StandardValidation.cs to reveal the following:
public class ChessBitmap : IPositionEvents and
public class StandardValidation: IPositionEvents, IValidation . Making sense yet? Ok just a little more to go. Once you've studied the aforementioned code, mainly the
removeEvents, open the file: ChessBoard.cs and find the code in the constructor:
coFen = new FenNotation();
Now you should be able to see what we've accomplished here: First with a little bit of extra work I've made it very simple for others to use the events of my object, Second I've made it very easy for me to use the events of my object. To create another object that listens to the events I simply declare an object and have it implement the interface for the events that I am interested in receiving. Remember VS will ask you if you want the interface skeleton code generated, simply say yes and write the body of the code to handle the events. Then it is a simple function call to hook that object up to receive events. For another example look at the PGN parser and the XML conversion that takes place in the sample applications.
Using the code
Couldn't get any easier: Compile the projects and let em rip....
Seriously though it is that easy. Just open the solution in the ChessBoardCtrl directory named: ChessBoardCtrl.sln. This solution has references to the demo applications that hosts the control and implements some of the features. By looking at the demo program you can get a good understanding of how the control works, play with that first then try it your self. I'll update this more at a later time (when I have a little more time). Until then let me know what you guys think!
Points of Interest
If there is any particular area you want me to discuss, just post a message!
- This is the first release.