| |
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.
|
|