Step 1: Source Code Control We prefer http://tortoisesvn.tigris.org/http://tortoisesvn.tigris.org/ Can use pay/hosted sites: –http://wush.net/subversion.php --- $20/monthhttp://wush.net/subversion.php –https://secure.cvsdude.org/ --- $10/monthhttps://secure.cvsdude.org/ Can host an SVN server yourself Can use free/hosted sites: –http://forge.novell.com/http://forge.novell.com/ Reasons: –Collaboration –Easily back out changes –Backup
Step 2: Setup Interface and Debug Tab Basically just get it compiling, telling you your color, and you reacting properly. Make sure your DLL is getting copied into the framework’s output directory. Create the Debug Tab custom user control, and be able to add controls easily.
Step 3: Data Structures Decide on data structures to represent the board and pieces. –It is suggested that you use an enum to represent MyChessPiece (MyChessPiece.WhitePawn, MyChessPiece.BlankTile, MyChessPiece.BlackPawn, etc) –Make sure that MyChessPiece.BlankTile is in the middle so that you can say: if (curTile < MyChessPiece.BlankTile) then white else if (curTile > MyChessPiece.BlankTile) then black –It is suggested that you use an 8x8 array of MyChessPiece to represent the chess board. –It is also suggested that you have an array of piece values, for example if you were black: pieceValue[MyChessPiece.WhitePawn] = 1; pieceValue[MyChessPiece.BlackPawn] = -1;
Step 4: Move Generator Create your Move Generator –Pass in the board and a board location (row, col). Have it return all moves for that piece. To get all moves for a board, cycle through all rows and columns, passing each tile into the Move Generator and storing the results in a huge Array (or ArrayList) ONLY return valid moves Create InCheck function Make sure to check for special cases: –In Check (don’t move into and not out of) –Pawn (diagonal killing) –Queening (straight on, and diagonal killing queening on both ends of the board)
Step 5: Move Validator Move Validator just takes in a board and a move and returns a bool of “pass or fail” Move Validator calls Move Generator and if Move Generator returns the move in it’s list of valid moves, then the move is good A move is invalid if it goes over time. Make sure to check. Add in a special case to allow a human player to pick up a piece and put it back in the same place (helps in debugging)
MILESTONE-1: Random AI Create an AI that takes all possible moves, and randomly picks one (and moves). To meet this milestone: –AI must make valid moves –AI must catch the user making invalid moves –AI must handle special cases (in check, diagonal killing, etc) –AI does not use Mini-Max at this point
Step 6: Debug Tab Add code in your tab to see: – what the AI thinks the board looks like –what it thinks the score is –who it thinks is winning –any other info that is relevant
Step 7: Benchmark Info “One test is worth 1,000 expert opinions” – Russ Miller Make it so that you collect benchmarking info like: –Depth (Start, Completed) –Moves Generated –Moves Visited –% Waste –How many Moves were visited per level (not useful until Mini- Max is plugged in, but nice to have) –Average of above
Step 8: Test Play MANY games and make sure that the AI is performing appropriately Make sure that Moves are generated correctly Make sure that the AI flags invalid game when you try to perform illegal moves This is a VERY important step! Before starting Mini-Max, you want to make sure that your core code is VERY solid (debugging Mini-Max is hard enough)
Step 9: Evaluate Board Create the Evaluate Board function Can be as simple as going through the board tile by tile and adding up piece values: total += pieceValue[board[x,y]]; Simply returns board score by adding up the values of all of the pieces Can also have certain “extensions” (see Advanced slide at end of presentation) Make sure this works properly, otherwise your AI will help the other AI win. This is the “smarts” of the AI.
MILESTONE-2: Greedy-1 AI You should at least be here by the first class tournament Create an AI that takes all possible moves, and picks the most valuable one (and moves) To meet this milestone: –AI must select the most valuable move in it’s list. In the case of multiple moves being the same value, choose the first one. –AI must make valid moves –AI must catch the user making invalid moves –AI must handle special cases (in check, diagonal killing, etc) –AI does not use Mini-Max at this point –Greedy-1 AI should beat Random AI every single time.
Step 10: Add Mini-Max Leave about a week to add and test Mini-Max (by far hardest part of the chess program to get right) Test Mini-Max with depth 2 and 3 If your program does Mini-Max depth 3 correctly, you can be pretty confident that Mini-Max depth n will work also Choose how you want to solve the in order problem –Order Bonus –Create all children and Mini-Max from highest value to lowest value
MILESTONE-3: Mini-Max AI Create an AI that selects the best move based on Mini-Max with A/B pruning To meet this milestone: –AI must select the best move based on Min-Max –AI must make valid moves –AI must catch the user making invalid moves –AI must handle special cases (in check, diagonal killing, etc) –Mini-Max AI should beat Greedy-1 AI and Random AI every single time
Final Testing Play MANY games and make sure that the AI is performing appropriately Make sure that Moves are selected correctly Make sure that the AI flags invalid game when you try to perform illegal moves This is a VERY important step!
Things to Know Mini-Max is VERY time consuming to debug. Stay with the Psuedo code as much as possible. Mini-Max is executed HUNDREDS of thousands of times, so even one extra line of code can adversely impact performance (‘#if debug’ is your friend) Avoid creating objects in Mini-Max (serious performance hit) Avoid static functions because if you play your AI against itself, it will share static functions, and static variables. Understand the Horizon Effect
Advanced Evaluate Board Make sure that any additional stuff that you add is worth less than a pawn, otherwise you’ll get pawn sacrifices. Any Advancement to Evaluate Board not only makes your offense better, but also your defense, since you’ll automatically avoid it (because of Mini- Max) You can add different stuff to evaluate board to make your AI “smarter” –Forking –Trapping –Knights in the center –King in the corner –Protected Pieces –Etc Opening Books help you initially to setup good position (there are a bunch of them out there, but you have to pare them down to not have ‘en pesaint’ moves, and also castling moves.
Best Practices Do not move onto the next step until you feel comfortable with the amount of testing that has been done on the current step! (Build on a solid foundation) Use #define’s at each milestone so that you can easily build Random AI and Greedy-1 AI (off of your new code) You can also create Greedy-2 (depth 2), and Greedy-3 by just executing Mini-Max with depth-3 and picking the highest scoring move. Test your AI often as both White and Black (pit AI against AI to test this) NEVER use floats, always use Ints Buy a real chess board to help debug Mini-Max ($7 at k-mart) Read a few of the Chess HowTo’s out on the internet
What will help you to Win (listed in order of priority) Testing to make sure that your AI doesn’t make invalid moves, and doesn’t allow invalid moves Having a really “smart” evaluate board Getting as far down in Mini-Max as possible
Final Thoughts It’s hard, but it’s possible to do (we did ours during summer term and had less time) Well worth the effort Amazing to see your program get more intelligent with time It’s pretty amazing when your program outsmarts you