From ee310c6ba01f8bad7313e941c6cd78111b3cb1ce Mon Sep 17 00:00:00 2001 From: Mark Bluemer Date: Wed, 3 May 2017 13:45:57 -0400 Subject: [PATCH] Aded implementation details to readme and updated bitboard picture --- README.md | 20 ++++++++++++++++---- docs/bitboard.png | Bin 13429 -> 24186 bytes 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e822a33..f666234 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,24 @@ This is the repo for a checkers AI project. * `build/runner` - When project is built it's compiled to the `runner` file -## Implementation Details -Here is an example of the bit board setup this project follows: +## (1) Implementation Details + +The project was implemented purely in c++. The decision to use c++ was made because bit manipulation in Java is unnecessarily difficult due to not having any definitive unsigned 32 bit integer primitive. C++ on the other hand contains a plethora of integer data types in the `cstdint` library. Two group members were also taking the networks course concurrently so socket programming in C wasn't an issue. + +### Bitboard Implenetation +Here is the bitboard layout that we utilized where each number corresponds to the bit index: ![bit board](/docs/bitboard.png) -This orientation allows all moves to be done with either a 7 bit or 1 bit rotation. +This orientation allows all moves to be done with either a 7 bit or 1 bit rotation. The entire board is then represented by three 32 bit integers: white pieces, black pieces, and kings. This is much more space-efficient than array implementations. + +Along with space saving there were other advantages. Using bit manipulation means there's no need to constantly index into any sort of data structure like in the array representation of a board, saving time. Another large advantage is that many of the heuristics can be done with bit masks. That, in combination with inlining done by modern c++ compilers, boils many of these calculations down to a few lines of machine code. + +### Search Implementation and Depth + +For search we stuck to a recursive minimax with alpha-beta pruning. This implementation can be seen in the `src/MinimaxSearch.cpp` file. This function, identical to the description in the textbook, allows the elimination of unnecessary search, cutting the ply factor by a quarter on average. + +We used a simple variable depth solution. We have a minimum and maximum search depth such that the minimum is always met and the search will continue to the maximum depth as long as there are jumps available. With this we could achieve a maximum ply of around 11 in a couple of seconds. The minimum depth of 5 ensured that pieces wouldn't hover around corners during endgame as 5 moves is often enough to encounter another piece which was combined with higher evaluation values on encounters rather than avoidance. ## Citations @@ -26,4 +38,4 @@ The vast majority of the project is personal work but there were some inspiratio * [Checkers Bitboard Tutorial](http://www.3dkingdoms.com/checkers/bitboards.htm#movegen) * [Compiler Friendly Bit Rotation in C](http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c) * [Evolutionary-based heuristic generators](http://pdfs.semanticscholar.org/91c9/d140267f3b008d00b330b6b0e9182fa4b62e.pdf) -* [Strategy Game Programming](http://www.fierz.ch/strategy5.htm) \ No newline at end of file +* [Strategy Game Programming](http://www.fierz.ch/strategy5.htm) diff --git a/docs/bitboard.png b/docs/bitboard.png index d0e1aae150021f2096fd3e3ffee4fc7bbdc593d4..79d3a2c5564351ae1d600b27c1f48903c60b864c 100644 GIT binary patch literal 24186 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 s&wZ1USXl^Wslvio|J<)FoaykN8rZ~{Bti> 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 Pygwr=sU%S)W)$>4%z{aY