Code
(NB: Much of the following has been superseded. See What's New for details.)
Code is now included, for the benefit of those who think it might help them.
I have included sample projects, for use when recompiling.
Please note that you will need the included resource files for sounds and pictures.
If you don't like my commenting habits, too bad. ;->
Basic Comments:
Much of the code is written more clumsily than I like. But then, I didn't have a clear idea how I was going to adapt it to a multi-threaded system.
In particular, if I were to do it again, I would make the brain a separate BLooper, and have it trade messages with the main view for moves.
Basically, there are four areas where multi-threading becomes important:
- Display: In addition to the regular BLooper handling the events in the window, there is a second thread that handles spacing out the frames of the explosions. This is handled separately from the events in the window, to permit faster responses to the user. A set of semaphores and associated flags is used to control when the display thread shows the next set of moves. No more than one display thread ever exists.
- Thinking: Once a move has been decided upon, and the display thread started, a new thread is started to think of the computer's next move. Again, a set of semaphores controls when it starts and finishes, along with the Pulse() function. This is one of the major reasons that all changes to the game options are delayed until the next turn.
- Multi-threaded thinking: Bill Kocay thinks by starting up one thread for each row to do the lookahead, then waiting for all the threads to complete. If the game is interrupted partway through this, the threads may leak memory. There are, of course, better ways of doing this.
- Sounds are played on separate threads, to permit the rest of the game to continue.
Coming from a MacOS background, I wanted to put all the sounds and pictures in a resource file. Due to the lack of a ResEdit equivalent, I had to hack them in myself. The code for this is not included, as it involves some quick-and-dirty routines that you really don't want to see.
The board is drawn from a set of bitmaps. To make life easier for me, the bitmaps are of uniform size (64x64, if I remember correctly), and include the borders for the cells. Thus, the empty cell is drawn as a bitmap. This means that I never have to worry about previous contents of cells.