I implemented the following minimax algorithm for the reversi GamePigeon game in python:
def minimaxabp(depth, max_player, game, move, alpha, beta):
if depth == 0 or game.gameOver:
return game.calcScore()
if (max_player):
moves = game.getValidMoves()
bestMove = [-1, -1]
bestScore = -99999
for m in moves:
ga = deepcopy(game)
ga.doTurn(m[0], m[1])
score = minimaxabp(depth - 1, not max_player, ga, move, alpha, beta)
if score > bestScore:
bestMove[0] = m[0]
bestMove[1] = m[1]
bestScore = score
alpha[0] = max(alpha[0], bestScore)
if beta[0] <= alpha[0]:
break
move[0] = bestMove[0]
move[1] = bestMove[1]
return bestScore
else:
moves = game.getValidMoves()
bestMove = [-1, -1]
bestScore = 99999
for m in moves:
ga = deepcopy(game)
ga.doTurn(m[0], m[1])
score = minimaxabp(depth - 1, not max_player, ga, move, alpha, beta)
if score < bestScore:
bestMove[0] = m[0]
bestMove[1] = m[1]
bestScore = score
beta[0] = min(beta[0], bestScore)
if beta[0] <= alpha[0]:
break
move[0] = bestMove[0]
move[1] = bestMove[1]
return bestScore
The algorithm works fine if I comment out the two parts that say:
if beta[0] <= alpha[0]:
break
which basically just turns it into a normal minimax algorithm. Because Python doesn't let you pass integers as references instead of values, I used an integer of length one instead. The alpha-beta pruning implementation looks exactly like every example I can find, so I assume it has to be a problem with the parameters getting passed around. For what it's worth, alpha and beta get declared in the following manner:
alpha = []
alpha.append(-999999)
beta = []
beta.append(999999)