I'm writing a chess AI by using a convolutional neural network to evaluate a specific board state, and then I'm using that evaluation to apply a min_max algorithm to get the AI's move. When I go passed a depth of 2 on my algorithm I get an error about comparing tuples to scalars.
def NN_evaluate(board):
board3d = split_dims(board)
board3d = np.expand_dims(board3d, 0)
return model.predict(board3d)[0][0]
def minimax(board, depth, alpha, beta, maximizing_player):
if depth == 0 or board.is_game_over():
return NN_evaluate(board)
moves = board.legal_moves
if maximizing_player:
max_eval = -np.Inf
for move in moves:
board.push(move)
current_eval = minimax(board, depth-1, alpha, beta, False)
board.pop()
max_eval = max(max_eval, current_eval)
best_move = move
alpha = max(alpha, current_eval)
if beta <= alpha:
break
return max_eval
else:
min_eval = np.Inf
for move in moves:
board.push(move)
current_eval = minimax(board, depth-1, alpha, beta, True)
board.pop()
min_eval = min(min_eval, current_eval)
best_move = move
beta = min(beta, current_eval)
if beta <= alpha:
break
return min_eval
def get_ai_move(board, depth, maximizing_player):
max_move = None
max_eval = -np.inf
for move in board.legal_moves:
board.push(move)
current_eval = minimax(board, depth-1, -np.inf, np.inf, False)
board.pop()
if current_eval > max_eval:
max_eval = current_eval
max_move = move
return max_move
board = chess.Board()
with chess.engine.SimpleEngine.popen_uci('C:\\Users\\coope\\Downloads\\Python\\Machine Learning\\Chess AI\\stockfish_15_win_x64_avx2\\stockfish_15_x64_avx2.exe') as engine:
while True:
move = get_ai_move(board, 3, True)
board.push(move)
print(f'\n{board}')
if board.is_game_over():
break
move = engine.analyse(board, chess.engine.Limit(time=1), info=chess.engine.INFO_PV)['pv'][0]
board.push(move)
print(f'\n{board}')
if board.is_game_over():
break
The error goes as
TypeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_1108/561116885.py in <module>
3 with chess.engine.SimpleEngine.popen_uci('C:\\Users\\coope\\Downloads\\Python\\Machine Learning\\Chess AI\\stockfish_15_win_x64_avx2\\stockfish_15_x64_avx2.exe') as engine:
4 while True:
----> 5 move = get_ai_move(board, 3, True)
6 board.push(move)
7 print(f'\n{board}')
~\AppData\Local\Temp/ipykernel_1108/3382320008.py in get_ai_move(board, depth, maximizing_player)
40 for move in board.legal_moves:
41 board.push(move)
---> 42 current_eval = minimax(board, depth-1, -np.inf, np.inf, False)
43 board.pop()
44 if current_eval > max_eval:
~\AppData\Local\Temp/ipykernel_1108/3382320008.py in minimax(board, depth, alpha, beta, maximizing_player)
28 current_eval = minimax(board, depth-1, alpha, beta, True)
29 board.pop()
---> 30 min_eval = min(min_eval, current_eval)
31 best_move = move
32 beta = min(beta, current_eval)
TypeError: '>' not supported between instances of 'float' and 'NoneType'
This seems to be an issue with my min(min_eval, current_eval)
but I'm unsure how to fix it ifget_ai_move(board, 2, True)
doesn't crash.
CodePudding user response:
Your
return max_eval
is inside the for loop, and should be outside. Written like this there is a situation in which it does not execute, and thus the whole function returns None
(default return value in python if you do not return anything in a function)