Archive for the ‘Chess’ Category

Final Round of Chess Tourney

Friday, May 27th, 2005

white to moveIs there any glory in winning the B division? That’s what it came down to in my final round game. I needed a win against Kevin to claim the “title” outright and a draw to tie for it. It looked doubtful for a while, but I got the win.

I traded queens early to force his king to recapture and lose its right to castle. At the first diagrammed position, I thought I saw an easy way to win a pawn–just trade away the knight at f6 and then take the now-unguarded pawn at h7. I regretted it immediately when he played g6 to trap my bishop. black to moveHowever, computer analysis says the capture was actually a good move, and it turned out I was able to hang onto the bishop for quite a while, partly due to threats against the king and other Black pieces.

Our moves weren’t always best, but they were usually in the top 5, according to Fritz. Until the position of the second diagram, that is, where Black blundered. Fritz recommends Bh6, threatening my knight, pawn, and king all on the same diagonal, but Black moved Rh8 allowing the knight fork. black to moveA few trades later, we arrived at the final diagrammed position where Black is tied down to watching over the advanced g-pawn and can’t keep the White king out of the center.

Chess Tourney Rounds 4 and 1

Tuesday, May 24th, 2005

White to moveI’ve uploaded PGN players for my round 4 and round 1 games. Both of these games were wins playing black, which gives me 3 wins and a draw with one round to go. The round 4 game got off to a quick start with all 8 minor pieces traded off by the 16th move. That was fine by me since it would reduce the chance of time trouble, and it left my opponent with doubled pawns, but it also cut down on the tactical possibilities. However, the rest of the game was not dull. Douglas put all his hopes on a king attack by lining up all three major pieces on the f-file. I thought I had it covered and took the opportunity to pick up a few neglected pawns. He made the best move in the diagrammed position, but after a sequence of less-than-perfect moves for both sides, I avoided trouble and started pushing my passed a-pawn to win.

Can White trap the queen?The round 1 game against Nancy had a couple of similarities. Both started with a Sicilian defence and with my queen venturing into enemy territory to pick up a pawn, but instead of counter-attacking like Douglas, Nancy made an effort to trap my queen. The net was getting pretty tight until she blundered and left a rook unguarded. Otherwise I think my queen can barely escape by giving back the pawn. The computer shows that my previous move (h7-h5) was a waste, and I should have moved my knight to d7 and then c5 instead with prospects for trading my queen for a rook and a bishop.

“Jnuchess” Plays and Wins

Monday, May 23rd, 2005

The Java port of GNU Chess is now doing well enough to play a game and beat me. To get the main alpha-beta engine to work I had to track down about a half-dozen or so translation errors I had made in going from C to Java. Fortunately, I got the C version to build under Xcode, which gave me a IDE with debugger that I could use to compare my code with the C code as they were both running. Just as fortunately, most of the errors made themselves felt pretty early in the move evaluation process, so it wasn’t too tough to track down what was going wrong by narrowing the window between when things were good and when they were bad.

There are several sets of “find the best move” problems that are used for evaluating chess programs. With 5 seconds per problem for the “BT2630″ set, my Java version of GNU Chess gets 7 out of 30 correct (10 if I increase the hash table size from 1K to 16K entries, and 16 if I give it about 30 seconds per problem), and the C version gets 11 out of 30 correct (12 with the bigger hash table). The C version is still running about twice as fast at processing positions. The hash table management appears to be a place where improvement is possible.

The toughest errors to track down were those that originated in the C source. In one case the Java version would get an IndexOutOfBounds exception evaluating a position, and it turned out the position was invalid as there was a black pawn on its eighth rank (it hadn’t been promoted). It made me feel a little better than the C code had the same problem, except that negative array indices executed silently there. I couldn’t find any problem with the move generation code or the move execution code, but I eventually found that there was a backdoor for stale moves to enter into consideration.

Moves in the hash table that were once good “killer” moves would be considered later even if the board had changed, as long as they were still legal. So at some point a move such as g2-g1 would make it on the list with a rook on g2. Later the move would be considered again when a black pawn was on g2, and the legality-checking code wasn’t watching for such a pawn move (since none would be generated by the move generator without also setting the promotion info). So a fix to IsLegalMove finally got things going.

Everything I test shows new errors, and now I’m seeing problem processing the opening book…

Chess Tourney Round 3

Wednesday, May 18th, 2005

I got very lucky in this game yesterday. I started out well, I thought, with a strong center and plenty of room for my pieces. If only I knew how to turn those advantages into something tangible. Black soon challenged my center with d5, and the center stayed fairly tense throughout the middle game. Computer analysis showed many suboptimal moves which resulted in slight advantages that swung from one player to the other.

Black traded a knight for my two central pawns, which I thought was to my advantage though the computer shows it was a good trade for Black. He probably needed to work on advancing his passed pawns to make the trade worthwhile, though. At left, is a typical position of the middle game. I thought for a while and moved Bf3, but the computer suggests f4 instead. Eventually I figured out I should use my extra piece to try to win trailing pawns and got into a decent position, but was very short on time. Black kindly dropped a rook with my clock under two minutes, and I barely had enough time to mate him–only four seconds to spare. Very lucky.

GNU Chess/Java Starts to Run

Monday, May 16th, 2005

I decided to go ahead and convert the remaining printf() calls (too chicken to try switching to Java 5 at this point) and ignore the signal() calls so I could try running GNU Chess/Java. The signal() calls are only used for handling control-C to allow interupting of the think process. Not sure what the Java equivalent would be.

For a while, I would get early crashes when trying to run. Usually these were NullPointerExceptions due to uninitialized array members. IndexOutOfBounds errors were a little trickier to fix, and for one of them I had to actually run the C version to compare values. Turns out the array index was -1 there, too! I’ve already marked a half dozen or so places where the C code looks suspicious, so I think this effort will unearth a few problems in the original source.

There were a couple of errors to get around when trying to build the C version, which I’m guessing are due to different versions of the developer tools on Mac OS X 10.4. There is also a problem running the C version. It seems to process one command and then get a bus error. Coincidentally, the Java version has a similar problem. After processing one command, it gets lost trying to look for more input — there’s some threading issue going on.

The program has some self-test commands that I was able to use to compare speeds. The Java version appears to be about half the speed of the C version. Some results

Test C Java
movegen 34M moves/sec 16M moves/sec
eval 217K evals/sec 110K evals/sec

Not bad.

Other tests, which actually try to find the best moves, are crashing …. If I can get past that, I may need a catchy name for this project. Jnuchess?

C to Java

Tuesday, May 10th, 2005

I’ve almost finished the mostly-mechanical first pass of converting the C GNU Chess code to Java syntax. I haven’t tried to compile yet, but there’s about six files out of thirty-plus that IDEA (world’s greatest IDE) says contain syntax errors. Most of them are complicated printf() calls that I put off, thinking I might just start using Java 5, which comes with a printf() of its own. Also remaining are some threading issues like the use of the signal() function.

The most common C features in C GNU Chess that needed converting to Java:

primitive typedefs
better readability and type-checking by using BitBoard instead of long. I started using Java classes for these typedefs, but BitBoard operations much be fast, and I’ve have to deal with translating between the different semantics for assignment of primitives and objects.
macros
most were just constants; I made functions for most of the others, except a few like CLEARBIT that seemed easier to inline.
primitive reference parameters
I used the return value if possible; otherwise I passed the params in an array.
printf and scanf
only a few of these we hard to convert; Java 5’s printf will help
enum
something else that’s available in Java 5
implicit bools
I can’t count how many times I converted “if (c)” to “if (c!=0)
goto
Java doesn’t have goto, but it does allow labels on break and continue, which sometimes resulted in creating dummy loops just so I could use a labeled break instead of a goto.

Java Port of GNU Chess

Wednesday, May 4th, 2005

A week or two ago I started porting GNU Chess from C to Java in my spare time. The main motivation is to refresh my Java skills after two years of C++ immersion. It’s amazing how quickly you can lose the subtleties of a tool when you don’t use it.

I’m sure the project will succeed at making we aware of the Java/C differences, but I have to admit it’s unlikely the port will produce a runnable chess-plaing program even if I stick with it. GNU Chess code is pretty hairy, especially since it sacrifices clarity for speed. But if it does by chance run, it will serve as an interesting Java benchmark and will give me something to tinker with.

So far I’ve been translating each file to a Java class composed of static members, and I’m probably about 15% done by volume. The biggest headache so far has been lexpgn, which is a PGN (Portable Game Notation) file parser that is generated from a grammar description, sort of like ANTLR but different. I’ve barely used ANTLR, but if I knew it well, the thing to do would be to translate the lexpgn grammar to ANTLR syntax directly. The main lex() function is 800 lines long with nested switch statements and gotos …