Minimax 返回非法 uci 移动 - 移动生成不更新?
Minimax returning illegal uci move - move generation doesn't update?
当我用位置 r1bqkbr1/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R w KQq - 3 6
测试我的代码时,下面的代码在 运行 时输出 ValueError: illegal uci: 'd8d7' in r1bqkbr1/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R w KQq - 3 6
。问题似乎是在我推动新动作后棋盘没有更新(它仍然产生合法的动作,认为它是黑色的移动,而实际上是白色的移动)。我该如何解决这个问题?
import random
import chess
import chess.polyglot as book
from evaluate import *
searched_position_evals = {}
def choose_move(board, depth, is_max):
# TODO: endgame database
best_move = ""
best_eval = float('inf')
if not is_max: best_eval *= -1
if check_opening_book(board)[0]: return check_opening_book(board)[1].uci()
for move in list(board.legal_moves):
print(f"evaluating {move}")
board.push_uci(move.uci())
eval = minimax(board, depth, board.turn == chess.WHITE)
if is_max: best_eval = max(best_eval, eval)
else: best_eval = min(best_eval, eval)
if best_eval == eval: best_move = move
board.pop()
return best_move
def check_opening_book(board):
with book.open_reader("assets/openings.bin") as reader:
if len(list(reader.find_all(board))) == 0:
return (False, "")
else:
return (True, list(reader.find_all(board))[random.choice(range(0, len(list(reader.find_all(board)))))].move)
def minimax(board, depth, is_max):
if depth == 0:
return evaluate(board)
elif board.fen in searched_position_evals:
board.pop()
return searched_position_evals[board.fen]
else:
if is_max:
max_eval = -float('inf')
for move in list(board.legal_moves):
board.push_uci(move.uci())
searched_eval = minimax(board, depth - 1, False)
searched_position_evals[board.fen] = searched_eval
max_eval = max(max_eval, searched_eval)
board.pop()
return max_eval
else:
min_eval = float('inf')
for move in list(board.legal_moves):
board.push_uci(move.uci())
searched_eval = minimax(board, depth - 1, True)
searched_position_evals[board.fen] = searched_eval
min_eval = min(min_eval, searched_eval)
board.pop()
return min_eval
print(choose_move(chess.Board("r1bqkb1r/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R b KQkq - 2 5"), 3, False))
注释掉下面的board.pop()
。
def minimax(board, depth, is_max):
if depth == 0:
return evaluate(board)
elif board.fen in searched_position_evals:
# board.pop()
return searched_position_evals[board.fen]
...
当我用位置 r1bqkbr1/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R w KQq - 3 6
测试我的代码时,下面的代码在 运行 时输出 ValueError: illegal uci: 'd8d7' in r1bqkbr1/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R w KQq - 3 6
。问题似乎是在我推动新动作后棋盘没有更新(它仍然产生合法的动作,认为它是黑色的移动,而实际上是白色的移动)。我该如何解决这个问题?
import random
import chess
import chess.polyglot as book
from evaluate import *
searched_position_evals = {}
def choose_move(board, depth, is_max):
# TODO: endgame database
best_move = ""
best_eval = float('inf')
if not is_max: best_eval *= -1
if check_opening_book(board)[0]: return check_opening_book(board)[1].uci()
for move in list(board.legal_moves):
print(f"evaluating {move}")
board.push_uci(move.uci())
eval = minimax(board, depth, board.turn == chess.WHITE)
if is_max: best_eval = max(best_eval, eval)
else: best_eval = min(best_eval, eval)
if best_eval == eval: best_move = move
board.pop()
return best_move
def check_opening_book(board):
with book.open_reader("assets/openings.bin") as reader:
if len(list(reader.find_all(board))) == 0:
return (False, "")
else:
return (True, list(reader.find_all(board))[random.choice(range(0, len(list(reader.find_all(board)))))].move)
def minimax(board, depth, is_max):
if depth == 0:
return evaluate(board)
elif board.fen in searched_position_evals:
board.pop()
return searched_position_evals[board.fen]
else:
if is_max:
max_eval = -float('inf')
for move in list(board.legal_moves):
board.push_uci(move.uci())
searched_eval = minimax(board, depth - 1, False)
searched_position_evals[board.fen] = searched_eval
max_eval = max(max_eval, searched_eval)
board.pop()
return max_eval
else:
min_eval = float('inf')
for move in list(board.legal_moves):
board.push_uci(move.uci())
searched_eval = minimax(board, depth - 1, True)
searched_position_evals[board.fen] = searched_eval
min_eval = min(min_eval, searched_eval)
board.pop()
return min_eval
print(choose_move(chess.Board("r1bqkb1r/pp2pppp/2n1p2n/2p5/3P4/7N/PPP2PPP/RNBQKB1R b KQkq - 2 5"), 3, False))
注释掉下面的board.pop()
。
def minimax(board, depth, is_max):
if depth == 0:
return evaluate(board)
elif board.fen in searched_position_evals:
# board.pop()
return searched_position_evals[board.fen]
...