The main problem here is that I consider using object variables instead of a local variable.
self.move is an object variable, every time you change it - each level of recursion βseesβ the change, which is usually bad for recursive algorithms.
Recursive algorithms should be self-sufficient and minimal if there are any changes in the calling environment - this greatly facilitates the flow of the algorithm.
The two main problems that I see in this code are:
self.move must be a local variable (declare it as move ). When you later do: board.unmakeMove(self.move, player) - I suspect that the board cancels another move that was set deeper in the recursion tree, and not the one you intended. Using a local variable will eliminate this unwanted behavior.- Each level of the recursive call sets
self.max_eval = float('-infinity') - so you are constantly changing it, although this is probably not what you want to do.
The solution should be something like this:
def negaMax(self, board, rules, ply, player): """ Implements a minimax algorithm. """ if ply == 0: return self.positionEvaluation() max_eval = float('-infinity') move_list = board.generateMoves(rules, player) for move in move_list: board.makeMove(move, player) currentEval = -self.negaMax(board, rules, ply - 1, board.getOtherPlayer(player)) board.unmakeMove(move, player) if currentEval > max_eval: max_eval = currentEval return max_eval
I'm not 100% sure that it will really solve everything in the code (but it will solve part of it), but I am 100% sure that I will avoid object variables, which will make your code much easier to understand and debug.
source share