Chess AI
Home OpenBubbles Chess AI Stoichiometry Solver TicTacToe AI Transportation Efficiency The Case for Semi-Free Software Navigation Menu

All of the software on this website is released under the GNU General Public License.

Please download the source that I have so far.

If you would like to help me with this program, please email me at lasindi@gmail.com.

 Chess AI is one of my biggest programming goals. I have written lots of code for it before, but it was so ugly and inefficient that I decided to rewrite it (for the third time). I was inspired by an article in a C++ textbook about artificial intelligence that used Deep Blue vs. Kasparov as an example. I'm writing the program as a like-C-but-actually-C++ program, much like Stoichiometry Solver (the non-GUI part at least). What I mean by this is that I use C++ features for I/O (iostreams), comments (//), boolean code (bool variables) and string handling (I actually did true C string handling in Stoichiometry Solver, i.e. using char arrays).
 The program contains a couple thousand lines of code. Keep in mind that many of these lines, if not the majority, are repetitive and only exist for the purpose of creating the bit-field for the board (see below). These lines, rather than having a negative impact on performance, either actually help make the program run faster or have no effect at all. This sounds strange, but consider an 8 by 8 array. If one actually declares 64 variables instead of taking one line to declare this array, there is no more memory used nor more processing required. At the level of assembly language, there are no such things as arrays, and the 8 by 8 array is really just 64 memory addresses. I would use two 8 by 8 arrays to represent my board if I could put it into a bit-field, but since this was impossible, I used 2 sets of 64 separate variables. I have, however, created an interface (through functions with very repetitive code) that allows a programmer to deal with all of the variables in an array-like manner. If you are thoroughly confused, please take a look at the source (if you are a programmer, that is; if you are not, why are you reading this?).

This is what's being tested now:

  • AI: It has the same structure as the TicTacToe AI. It recursively evaluates positions. The depthlimit macro controls how far this recursive evaluation goes. At the limit, the limit_evaluation() function uses the number of and types of pieces to make a static evaluation. At this point the AI is very poor, which is, of course, why it's up for testing.

These are the capabilities I have so far:

  • Board Structure: This is contained in board.h. The entire board is stored in a 35-byte (277 bits out of 280 in actual use) struct. It is a bit-field; it contains 64 1-bit unsigned char variables, each containing the side that the piece at a specific square is on (this is irrelevant if the square is empty), and 64 3-bit unsigned char variables, each containing the type of piece that is on a specific square. It also contains bool variables that store whether or not En Passant moves are possible, whether or not kings and/or rooks have moved (making castling illegal), and whose turn it is. The getside(), gettype(), assignside(), and assigntype() functions allow the programmer to enter in row and column coordinates as parameters to obtain and assign values for these separate variables like they were organized into arrays. Please look at board.h to understand what on Earth I'm talking about, but don't directly access the members of theboard (this is the actual identifier). The goal of using a bit-field was efficiency, but the goal of the rest of board.h was flexibility, readability, and overall, programmability (if this is indeed a real adjective).
  • Translation of User-Readable Values and Computer-Readable Values: This is in textinterface.h. I tried to keep the code that directly interacts with the user and specific to a command line environment as separated from the rest of the program as possible. I'm doing this in the hope that someday I'll be able to make the program GUI (after all, it's not very convenient to have to drag out a physical Chess board everytime you want to play, nor is it more intuitive to enter coordinates than dragging and dropping pieces). Anyways, this code translates column coordinates for the user (a, b, c, ...) to and from their respective numbers (1, 2, 3, ...), converts numerical char values into actual numerical values (the difference between them is that of '1' and 1), and converts numbers that stand for different types of pieces (0=empty, 1=king, 2=queen, ...; these values are defined in the TYPES enumeration in board.h) into strings (0 goes to "empty", for example).
  • Pattern-Based Move Validation: This is in movevalidation.h, or more specifically, the validPattern() function. This function returns true or false depending on whether or not a given move could be made on a board with no pieces other than the one moving. This means that a rook moving vertically will return true but a king moving more than two spaces will return false. This code will only be used in validating moves entered by the user; the AI will be programmed to avoid considering moves that pose such problems.
  • Obstruction-Based Move Validation: This is in validObstructions() in movevalidation.h. This checks to see if the moving piece is illegally moving through other pieces or trying to take a piece of its own side. This code is used only to test moves of the user; the AI will need to do nearly none of what it does.
  • Check-Based Move Validation: This is accomplished through validCheck() in movevalidation.h. It checks if a move places a player's own king in check. The function then calls inCheck(), which goes through all of the opposing pieces and tests whether or not they can take the player's own king using the validPattern() and validObstructions(). While this will certainly be necessary for the AI, I believe that I will be able to incorporate this move-validation into the position-evaluation function. Realize I'm really paranoid about performance issues with the AI (if you don't believe it, look at board.h; I wrote programs to write the long, tedious, repetitive code in there); one set of code I wrote took about a second just to declare a checkmate. Such slow performance is unacceptable, and this time I'm not going to let it happen.
  • Castling: This is handled through an if statement in main() (obviously in main.cpp) and validCastle() in movevalidation.h. It uses variables in boards to make sure that players who have already moved their kings and/or rooks cannot castle.
  • En Passant: This is handled through code throughout main() and in validEnPassant() in movevalidation.h. It uses variables in boards to make sure that only pawns that just moved forward two spaces are being taken with En Passant.
  • End of Game: This is handled in endofgame.h. The only function in there right now is stalemate(). At the end of each round, the program checks if the game is in stalemate and if the player is in check. If in check and in stalemate, then the checkmate is declared and the game ends. If there is only a stalemate, then this is declared and the game ends.

These are some of things that need to programmed next:

  • Graphical User Interface (GUI): I will be using Qt, and because of this, there will only be a Linux version of the GUI.
Valid HTML 4.01!    Valid CSS!

This website is hosted for free by Freewebs.com - free website. Get your own Free Website now!