Design of the project classes
For the Board class, I use two int vectors to store the number of beans in each hole for north and south players. In these two vectors, the #0/the first int represents the pot.
For Game class, I create a Board variable to store the board for the game; two player* representing north and south; and a Side variable to switch turn between two players.
For player class, I introduced three private functions for my SmartPlayer class:
-
AdditionalMove: return a boolean variable and indicate whether the current player need a second move
-
chooseMove: a void function that override the original two-parameter function. It takes the Board and side, int for besthole, int for evaluation value, and an int for depth. It stores the choice of besthole in the int variable. The value is a variable to store the evaluate score for that move. The depth is a variable to keep track of the Game tree and terminate the searching when it reaches depth 6.
-
Evaluate: a function that returns an int which represents the score of that move. The higher the score is, the better the choice is. The score is calculated by comparing the total beans of south and north including their pots.
Design of the smartPlayer algorithm
In my smartPlayer class, I have three private functions that I already introduced previously. The major part for smartPlayer is the override chooseMove function. I called it in the original chooseMove function so that it can return the besthole value. When implementing this function, I first start with the exceptions: if the criterion says we should not search below or no move.
Then, I loop over all the possible holes for the move, if there are no beans inside (not valid move), I search the next one. If it is a valid move, I call recursion to keep searching down the game tree. There are two cases for the recursion, if there is one more round for the same player, we chooseMove for the same player but increase the depth. If the move ends, we chooseMove for the opponent and increase the depth.
Then once we get the value returned from chooseMove for that specific hole, we compare it with the existing value of the current best hole. Because my evaluation function focuses on SOUTH, the larger the value for south’s choice the better for south, the smaller the value for North, the better for north. If the value is better, we update the besthole.