Thursday, April 23, 2009

Ok... let's go

The final beta test phase of the online chess playing site I developed just started and, thanx to some incredible work of word spreading, we've 100+ players that registered for this phase.
The site is www.area64.it and it has been implemented in Python (server side and tools) and haXe with flash 8 code generation for the interface.
It supports playing, analysis rooms, voice chat, 2d or 3d board, custom colors, personal infos with picture uploading and more...

So far the response has been quite good, bugs are not that many and who entered got a very good impression. Also all of the ones I've been talking to agree with me that playing with someone with a certified identity is WAY better than playing an anonymous nickname.
My hope is that the certified identity will help people behave more socially and also will allow me to ban for good who for example can't avoid insulting the opponent.

We'll see...

Sunday, March 01, 2009

Ugly hacks, nice hacks

I'm translating a small python module that supports some chess intelligence generation into C++ because the speed is becoming a problem (when interfacing a digital board I need to do some search to guess what is the move that has been played and this includes looking one or two moves ahead and one move behind - that is moves that could have been played instead of the last move played).
The translation went fine so far with an almost 1-1 lines of code ratio between the two languages (not a surprise, given the problem) but I got a couple of surprises...

The bug

To check if a position cannot be win by either player I had to check whether two remaining bishops on the board were covering the same squares or not (that is if they were both light-square bishops or both dark-squares bishops or if they were covering the whole board).
This is needed because if there are two opposite-square-colors bishops on the board then a checkmate is still possible.
The code looked like this

if bc == 2 and nc == 0:
bp = [i for i, x in enumerate(pz) if x == BISHOP]
if (bp[1] - bp[0]) % 2 == 0:
# Just two bishops both dark squares or both light squares
return "material"
nc and bc are the number of knights and bishops on the board (pawns, rooks and queens are already known to be absent at this point). The board is represented using an array of 120 elements (12x10 representation) but it would be the same using an 8x8 approach... the bug is that just using the index "i" to check odd-even property is not correct, and "i//10 + i" should have been used instead. This shined apparent to me just by reading the code... however this code passed the tests because the test cases were all having the bishops on ranks with an even distance.
Now that I'm writing this post I also realize that there's even another bug at an higher logical level... it doesn't matter how many bishops are there: if they're all covering the same squares the checkmate is trivially impossible. It's not a 100% genuine bug because if the function returns a non-empty string then the position is impossible to win, but the converse is not true and it would be quite hard to fulfill such a contract.

Morale ? If it works is just because you didn't look closely enough.

The hack

In the same code I couldn't resist changing the handling of en-passant from

if x1 == self.epsq:
if np == WHITE+PAWN:
# White en-passant capture
self.board[x1+10] = EMPTY
elif np == BLACK+PAWN:
# Black en-passant capture
self.board[x1-10] = EMPTY
if np == WHITE+PAWN and x1 - x0 == -20:
# White double push
self.epsq = x0 - 10
elif np == BLACK+PAWN and x1 - x0 == 20:
# Black double push
self.epsq = x0 + 10
else:
self.epsq = -1
to

if ((np & PIECE) == PAWN)
{
if (x1 == epsq)
// En-passant capture
board[x1 - (((x1-x0)>>4)*20+10)] = EMPTY;
if (abs(x1-x0) == 20)
// Double push
epsq = x0 + (x1-x0)/2;
else
epsq = -1;
}
The C++ version is much more compact, but in the first part relies on a "trick" that for sure would look quite obscure for who reads the code... what the hell is "(((x1-x0)>>4)*20+10)" ?
The trick is that I know that the move was legal, so if a pawn goes to the en-passant square it must have been an en-passant capture and so the delta (x1 - x0) was either -9, -11, +9 or +11 depending on the color of the player. Then "(x1 - x0)>>4" is just the -1 if delta is negative or 0 otherwise; with "*20+10" and "x1 -" gets to the square where the captured double-pushed pawn was sitting.
Why do I think this trick is nice ? That's a good question...

I'll add a comment as a partial excuse to the poor future reader (which will probably be myself) :-)

Sunday, February 22, 2009

Back to running

Thanks to a wonderful sunny day I was able to defeat my laziness to go out for a nice run. It was long I wasn't running outdoor and I've also been skipping quite a few times the treadmill downstairs where I was supposed to run half an hour at least three times a week (ok ... quite a bit more than a few times...).
So I've been a coward and took it easy by not running the usual one-hour path but stopping instead short of that to turn back toward home. Everything was fine except a bit of ankle pain on the left foot near the end of the run.

Surprisingly enough I met only three other runners and a guy on a bicycle... I would have expected to meet much more than that given the nice sunny Sunday (I think my record is meeting about 20 or so people down that path).

Thursday, February 19, 2009

Apparently sometimes nothing is better than something

Phew!

The turney is over and I'm getting back to my normal routine. On 13-14-15 February we organized the first International Chess Tournament of Vigevano, with 120 players from all over the world including 8 GMs.
The turney itself was ok, except for the usual delay at the first round everything went smoothly and as an arbiter I had to tell something just in a few occasions...

From a software point of view instead most worked ok, including a few patches I made in the few minutes I found. Unfortunately the first round - because of the delay - started when I wasn't ready yet so I had to start the DGT boards when the games were already started, so I decided to just show on the big screens the positions and not the moves; for the other rounds instead the play zone screens were showing both the positions, moves and clocks.
We also found one of the DGT clocks to be defective (it wasn't sensing the clock button that players are required to press at every move) so the 5th board was shown without players remaining time.

A the tournament I was also asked if what was visible on the screens could have been published also on the web. I wasn't expecting this and hacking it at the moment has been a bad decision for a few reasons
  • What was shown on the big screens was indeed an HTML page but I tested it only on FireFox and actually I even used a few images for figurine notation that were rescaled exactly so they could look right at the resolution/magnification I was using on the big screens. I didn't try it at all with any other browser or any other resolution.
    Of course it turns out that a self-refreshing HTML page is absolutely terrible on IE because of flashing and because it loses the scroll position (ok... IE - no matter if 5 6 or 7 - is a total crap as a browser for a jillion reasons, but still a lot of internet users for some strange reason stick to it, so anthing published on the internet - unfortunately - should be made to work also with that thing). Also someone using XP was still unable to see the small PNG i used for the figurine notation and was instead seeing just black squares (!).

  • I simply added an "os.system('pscp postion.html ....');" line to put the updated file on a web server, but I was directly replacing the file being served by apache. The file was rather "big" (35k) so the upload was not instantaneous and what happened is that who was observing the game from the internet could get an incomplete HTML file. An even bigger problem was that the if file was not even complete to the "http-equiv refresh" line then the partial - totally blank - file would stuck on the browser of the observer forever.
    I fixed this only the second day by uploading with pscp to another location and then calling a cgi script to move the file to the correct position.

  • The program I wrote was for showing the first 4 games in the playing area, not for publishing it on the internet, so a few "features" like figurines instead of letters were indeed "anti-features" for who was observing from a PC (with letters you could copy-n-paste in a chess program). Also the game shown was not complete for layout reasons and there was no provision for downloading the PGN of the game. Moreover it wasn't possible to go back and forth on the moves or to see just one board instead of all five of them.
All these things were nonsense for showing in the playing zone (in the room there was no reload problem ... the local file was correctly written and moved in place; and there's no mouse for who is looking at the screen so no interactive feature makes any sense at all) but made the experience for who was accessing that from the internet quite less than optimal.
What I realized only later after reading some comments was that it would have been better not showing anything at all on the internet...

So apparently sometimes nothing is better than something...

Now I'm working on a better flash-based interface for publishing the games online and hopefully I should be able to provide a better experience for viewers of the Bergamo tournament next month.

Sunday, February 08, 2009

Learning LISP

I'm halfway reading Practical Common Lisp and I'm now beginning to understand a few points about LISP that were not that clear. First of all what are those famous macros and why they're so powerful. I always had the gut feeling that C++ template machinery was not good, it is a different language with a lot of limitations and even doing things like loops or ifs is not impossible but very very hard; not only template debugging is difficult but even reports about syntax errors are so bad that they look like a joke.
LISP macros can do the same as C++ templates (and more), however the language is LISP itself (if, loops, opening files... you can do whatever you need to do "compile time").
I am experimenting with a macro "defentity" that given for example


(defentity simple-point point
(coords point))

(defentity circle line
(center point)
(radius float))


defines two classes, the classes "simple-point" and "circle". The center of a circle entity is a reference to a point entity and this generates a dipendence. When I change the coordinates of a point I want that all the geometry of dependent entities (for example circles that are referencing that point as center) to be invalidated.

I'm still working on it but I already got something working. The defined classes are regular CLOS classes with added "dirty" fields for invalidated geometry, cached results and accessors that do the required recursive "touching" of dependent entities on write operations. Changing referred entities, destruction and link removal is implemented (so when destroying a point all entities depending on it will be notified and given the possibility to remove the link instead of being also destroyed).

Making the same using templates with C++ would be IMO just impossible. Making the same with python would be easy (we did) but keeping much of the logic at runtime. Moving it at compile time with python would be possible but IMO a lot harder (and without much gain indeed).
With C++ a reasonable solution would be using a code generator (written e.g. in PERL) that generates the C++ code needed.

I'm trying the LISP way and so far looks promising...

Python dropped the clear distinction of compile-time and run-time as class and function definition are indeed executable statements; LISP moved further by dropping also the parse-time separation because thanks to macros even the parsing of the source is more or less an executable statement.