Monday, May 7, 2012

Chess in C (Part 1)

I recently finished writing a chess application in C. I've been trying to get back into programming: with all the cool social websites and iPhone apps out there, I've felt a little left out in these past years working in the infrastructure space. Sure, cloud is the coolest thing to happen to infrastructure in awhile, but I've always envied the people who write the awesome applications on top of the cloud. zCloud is an amazing piece of infrastructure, but the Zynga games programmed on top of it are much more fun!


The chicken in this picture is more happier than your average infrastructure architect.

The best way to write a chess application (or any application) is to split it into several smaller discrete parts. In this blog post, I'll describe how to setup a chess board, put some pieces on the board and print the board. My next blog post will deal with the algorithms used to calculate possible moves.

Setting up the board


I may not be a chess grandmaster, but if I recall correctly, boards have 8 rows and 8 columns. Each square on the board can have a piece. The obvious data structure to represent this would be a two-dimensional array of integers which we can declare as follows.




That was easy. One line of code and we have a chess board! Done! Here's a diagram of what we've created.

A visual representation of int array [8][8]. It ain't pretty, and neither is C.

The first square on the board is 0,0. The last square on the last row is 7,7. Remember, in C, array elements start counting at 0 and not 1, even though the statement we used to create the board was [8][8]. Confusing, I know. Remember this lesson when it comes to writing for loops.

This chess board is neat, but it's not much use without any pieces on it This chess board is an array of integers, which means each array element can hold a number between 0 and 65536. This is more than enough: there are only six types of pieces in chess (assuming a single player for now). Let's define these pieces upfront.




By defining (or should I say, #define'ing) these pieces, we can refer to them freely through our program as BISHOP or KING, instead of having to remember obscure numbers. This will come as a relief to the dyslexics reading this blog post, and the dyslexic writing it.
Now, we'll need a function to print the chess board.



This code might look long, but it's fairly simple. Let's go through it line by line.



We have two for loops that iterate through each element of the board[][] array. Notice how the for loops begin at 0 and stop at 7? This is because in C, we begin counting from 0. Remember this: if you tried to view the contents of array[0][8] (column 9 when the array only 8 columns), you'll get an array out of bounds error. If you're lucky, you'll get garbage, your program will crash, and you'll only have to bang your head against a wall once or twice. If you're unlucky, it'll introduce subtle bad behaviour to your program and you'll die never understanding why your code behaved that way.



If any given element matches a piece, we print the piece. Unfortunately, you can't do a switch() on an array value, which is why I've made a new variable called boardValue and performed a switch() on that. Ignore the BREADCRUMB: I'll explain that later. Let's run the code so far and see what we get.

This is not the chess board I grew up with.

That doesn't look too good. It looks more like a chess board designed by an alcoholic. Where's our chess board?! What happened to our 8x8 one-line wonder?! When an array is instantiated in C, all array elements are filled with garbage. You'll need to write code to "zero out" the board.



This code will iterate through each square in the array and set the value to 0. Let's try that again.
Now THAT'S a chess board!

Fantastic! If you ever get strange array results, make sure you've zeroed out your array. Now let's place two bishops on the board in their starting positions and see what happens.



Two lonely bishops.

Amazing! Two bishops have arrived! Let's go one step further and make an ARMY



Let's look at the chess board now.
An army looking for a fight.

We can even put one hapless opposing pawn on the board with board[6][4] = PAWN;
Advice for pawn in (6,4): RUN

Here's the code if you want to compile it for yourself.



Other posts in this series

Chess in C (Part 1)
Chess in C (Part 2) - Insert Pawn Pun Here
Chess in C (Part 3) - Rook, Rooks, Rookies, Wookies, same thing
Chess in C (Part 4) - I'm asking for input
Chess in C (Part 5) - Potential moves of a bishop: up-left, cardinal, pope

2 comments:

  1. Hi Paul
    I like this post-thanks.
    On compile of your code with gcc I get x2 warnings: unused variable row & column.
    I added some black pieces eg kqrbnp (lowercase for black pieces/pawns.
    I look forward to your next post on move entry
    (I was actually trying myself to do a 1d chessboard array in C eg cboard[64]; etc).
    Thanks :-)

    ReplyDelete
    Replies
    1. Thanks for your comment! Yep, there are 2 unused variables: row and column. I'll update the post to remove them. They are used in one of the next blog posts about valid move algorithms :)

      Delete