Yeah I know it seems I've done this backwards by not actually designing the application first and every one of my professors are shaking thier heads at me, but it's being done second because since I've started, the number of features and complexity of this application has grown dramatically. So now that the game portion is roughly complete, Jared and I will refine a list of features we want to add and nail down a layout. Once the features are chosen and the layout designed then we will implement them.





Back to Main Page Current Page
 

Current State Screenshot:


 



 

Jan. 1 2004 - Resampling Image for Scaling Board
Now I'm back to the graphic work. I've adapted the board to be scaled (resized) to the window size. This will give those with high and low monitor resolutions a better experience. I will not sacrifice the quality of the images in order to do this though. CxImage has a resample function which resizes the images to display them at a different size. Resizing the images is fast, but renders a low quality image. Resampling is a higher quality resize, in that it takes the original image at its original size and resizes it using bilinear method, nearest pixel method, or bicubic spline interpolation method. This produces a high quality image in the new size. How high quality? Well CxImage does not produce high enough quality resamples for me. I'm looking for the kind of resampling algorithm that will produce a resampled image of Photoshop quality. Am I going to write one, no. There are graduate students who develop new resampling algorithms for thier degree, so to think that I can come up with one of the quality I'm looking for is a little far-fetched. I will find a way to get high quality image resampling, one way or another.

This is a blown up comparison. On the CxImage resampling to the right I also used the Repair() and Median() functions to clean up the artifacts. Now if the resample was done on a busier, single layered image it would have performed much better, but here it is run on each piece individually and though the interiors of the pieces look good, the alpha channel around the edges get mangled. This may be my fault in that the Resample() function didn't resample the alpha channel the same way it resampled the the color channel. So I will look into resampling the layers individually. If I can't find a better resampling algorithm then I will restrict the scaling of the board to 2 or 3 sizes that will give much better resampling results, but I don't want to limit myself to a simple "stepping zoom" resizing of the board just yet.

Note: The difference in position of the pieces is not a resampling problem, but an escalating "off-by-one" problem caused because the calculation used to position the pieces on the board is integer based, and while each piece is only off-center by a single pixel, when we get down to the bottom right corner, the pieces are off-center by 8 pixels. I've since solved this by only resizing the board when the boardSize is divisible by 8, so that none of the pieces are off-center and therefore the offset doesn't increase with the distance from the top left corner. Using doubles to perform the calculations is not the best way to correct this, because the pieces are placed by multiplying their board[8][8] position by the size of each square. But having to cast the squareSize as an integer on all of the 30+ non-piece-placement uses would out way the solution (because I'm just that lazy), and because limiting the resampling of the images to every 8 pixels rather than every single pixel during the window resizing will speed the scaling of the board. Actually I've tried changing squareSize to a double, but what happens is that as the window resizes the pieces don't maintain uniform spacing. The truncation of squareSize from double to integer in the final placement causes the piece spacing to differ by one pixel to the left or right. The resizing looks much better with the pieces being spaced uniformly.

 



 

Jan. 6-9 2004 - Alpha Channel
Looks like Alpha channel support was added as an after thought in CxImage lib, because while the color channels go through the filters for resampling, the alpha channel gets a simple scale-down. This is why the interiors of the pieces look fine while the outsides were mangled, because the alpha channel does a column/row skipping scale down, so therefore my piece shapes also do a column/row skipping scale down. Col/Row Skipping is like this: if you want to shrink the image by a third, then you leave out out every third column and every third row which results in jagged edges. Now I've got to write a Bicubic resampling routine to resample the Alpha Channel like the others are. I will try to use the one provided for the color channels, or I may write one of the Mitchell & Netravali specification, depends on how the adaptation of the current resampling code works out.

OR, (above) I could extract the alpha channel as a regular black and white image, send it to the resampler (which treats it as a black and white "color" image, rather than the alpha channel of an image) then insert it back into the image as the alpha channel. The CxImage resamples are more blurry because the rule is when you resample you also sharpen the image to bring out the detail lost, but the processing time far outweighs the difference in the above images. They might be blurry because the alpha channels are getting washed out... but it's all trivial at this point. Board scaling is high quality and complete. Now that the alpha channel is fixed, I've noticed that Bilinear is faster than Bicubic resampling... and produce practically the same quality (when resampling the image to a lower resolution than the original) since Bicubic is mostly used for resampling an image to a higher resolution than the original. So I think I will use Bilinear resampling since it's so fast. So board scaling is now high quality, transparently fast, and complete.

 



 

Jan. 13 2004 - Feature Platform Test
All of the features we are considering will be handled in windows external to the main board window. So before the feature selection is complete I tested to see if/how to display the other dialogs that the features will be contained in. Along with that is something Jared pointed out, that the chess class must be Observable (java buzzword) by the other windows... which means they must be Global (C/C++ four-letter-word), funny huh. Observability is obtained by declaring the chess object in the main application and using extern in the other dialogs to gain access to it.

The chess board window (ChessDlg) is displayed using chessDlg.DoModal(); but I can't use that to display the other windows because it restricts the focus to only the last window opened. So I had to figure out how to create a modeless dialog. There are a lot of routines that do this, but I used the simple one that uses a resource defined dialog window. Problem was that when I created it directly it would flash and then close. I tried creating it using pointers and it works (if you know why please tell me). There is a minor yet lingering problem that I've got, the modeless dialog window will release focus but it always remains at the top of the Z-Order. Meaning if the dialog is open and you click on the chess board in the background the chess board becomes the active window but the dialog doesn't move behind the chess board. So I'm looking into changing the Z-Order manually.

To test the observability of the chess object by the dialog windows I painted the chess board image from the chess object onto the dialog window. To make sure that the dialog is not accessing a copy of the chess object I resized the board down and the image in the dialog window showed the scale change on its next paint. By the way, the screen shot showing the boards translucent is a test of XP's transparency feature which I have plans for later...

 



 

Jan. 15 2004 - Feature: Game Notation
"If a ruler does not understand chess, how can he rule over a kingdom". Sassanian King of Kings, Khusros II, c.600 A.D.

Chess is a game of great minds, a game of kings, of generals, of scholars. For centuries, games of chess between people have been of great interest to others. So a way of recording the chess game was needed for those who where not there to observe it.

"In Shakespeare's day, for example, the standard English chess book gave [a move] as follows: 'Then the black king for his second draught brings forth his queene, and placest her in the third house, in front of his bishop's pawne.' . . . In 1737, however, a Syrian-born player / author named Philip Stamma introduced the shorthand notation that we now call 'algebraic' in his book of composed problems, published in France." [quote source]

"It is called this because of the unique way it identifies each square of an 8 by 8 matrix chess board. Each column or file is labeled with a letter. Each row or rank is labeled with a number. "
[quote source]

In the 1970's the World Chess Federation made a concerted effort to make Algebraic Notation the standard method of recording chess games. It's a very short notation and devoid of any ambiguity, so Shakespeare's move above would simply be 2. Qf3. Algebraic notation is now the standard in chess game recording, and in computer chess programs Portable Game Notation (PGN) is the standard method of communicating the algebraic notation from program to program. This PGN has an airtight specification found at: http://www.very-best.de/pgn-spec.htm. Good news is I don't have to create a method of notation import / export and it will allow people to continue playing a game on Chess++ that was started on another program. Bad news is I have to read the BOOK that is the PGN specification... it's going to take days!

My PGN class will have to import a PGN ascii text file, export it back and pass it to the notation class that will be able to recreate and record games using the algebraic notation. This is what a typical (though short) PGN file looks like:
[Event "IBM Kasparov vs. Deep Blue Rematch"]
[Site "New York, NY USA"]
[Date "1997.05.11"]
[Round "6"]
[White "Deep Blue"]
[Black "Kasparov, Garry"]
[Opening "Caro-Kann: 4...Nd7"]
[ECO "B17"]
[Result "1-0"]

1.e4 c6 2.d4 d5 3.Nc3 dxe4 4.Nxe4 Nd7 5.Ng5 Ngf6 6.Bd3 e6 7.N1f3 h6
8.Nxe6 Qe7 9.O-O fxe6 10.Bg6+ Kd8 11.Bf4 b5 12.a4 Bb7 13.Re1 Nd5
14.Bg3 Kc8 15.axb5 cxb5 16.Qd3 Bc6 17.Bf5 exf5 18.Rxe7 Bxe7 19.c4 1-0

I think I will use a link list with the element having two parts, char wMove[256] and char bMove[256] since in notation the first "move" is white's first move and black's first move. The string size is 256 because PGN specification says that a move symbol can have 255 characters in it, then plus one for the string terminator. Unfortunately the average symbol is something like 5-7 characters so there will be a lot of wasted space, but abiding by the specification is more important. Inthe PGN specification it says "Because illegal moves are not real chess moves, they are not permitted in PGN movetext." This I think it's a way to get around the PGN reading programs being required to check the validity of each move recorded in a PGN. I wish that was enough to do it, but that's like saying the written law is all that's needed to stop crime. Now that I think about it because of the nature of the notation, some measure of checking the validity of moves is required because in order to move Kg5, you have to find a Knight that can make that move, and if you can't then it's not a valid move. But to truely check the validity of a move you must not only find the piece to move, but also if that piece can move based on whether it's protecting its King etc.

 



 

Jan. 19 2004 - PGN Notation List Structure
This is the list structure I've come up with. I'm using an link list class I wrote a while back.

The nodes (cyan) have 2 parts, both character strings. In the Heading List they store the tag name then the tag description, while in the Move List they store the White move then the Black move.