I have a rather simple chess endgame Python code implementinng `negamax strategy` given below but it behaves strange.Negamax means that when both players play fully rationally the best move leading to the quickest mate or the longest defense by both sides.It prints correctly this position, but the best move `Kb2c2` is not even considered when I have printed all legal moves.I'm even unable to force the code `consider` at any stage of searching the best move by white king `K`.I would like if some can dig into the code and tell me what's wrong **huh**
The output:
. . . . . . . .. . . k . . . .. . . . . . . .. . . . . . . .. . . . . . . .. . . . . . . .. K . p . . . .. . . . . . . .
Na tahu je: bílý (white to move in Czech language)b2c3<LegalMoveGenerator at 0x1d473d26b50 (Ke8, Kd8, Kc8, Ke7, Kc7, Ke6, Kd6, Kc6, d1=Q, d1=R, d1=B, d1=N+)><LegalMoveGenerator at 0x1d473d26250 (Kd4, Kc4, Kb4, Kd3, Kb3, Kxd2, Kc2, Kb2)><LegalMoveGenerator at 0x1d473d24050 (Kf8, Kd8, Kf7, Ke7, Kd7, d1=Q+, d1=R+, d1=B, d1=N)><LegalMoveGenerator at 0x1d473d25e10 (Ke5, Kd5, Kc5, Ke4, Kc4, Ke3, Kd3, Kc3)><LegalMoveGenerator at 0x1d473d25110 (Kg8, Ke8, Kg7, Kf7, Ke7, d1=Q, d1=R, d1=B, d1=N)><LegalMoveGenerator at 0x1d473d27110 (Kf6, Ke6, Kd6, Kf5, Kd5, Kf4, Ke4, Kd4)>
The code:[python]import chessimport timeimport threading
# Globální proměnná pro sledování počtu prohledaných pozicpositions_count = 0
def update_positions_count(last_time_printed): global positions_count while not board.is_game_over(): if time.time() - last_time_printed > 1: print(f"\rProhledaných pozic: {positions_count}", end='') last_time_printed = time.time()
def evaluate_board(board, depth): global positions_count positions_count += 1
if board.is_checkmate(): return 10000 - depth if board.is_stalemate() or board.can_claim_draw(): return 0 return None
# ... negamax, find_best_move ...# Negamax algoritmusdef negamax(board, depth, alpha, beta, color): evaluated = evaluate_board(board, depth) if evaluated is not None: return color * evaluated
if depth == 0 or board.is_game_over(): return 0
max_eval = float('-inf') print(board.legal_moves) for move in board.legal_moves: board.push(move) eval = -negamax(board, depth - 1, -beta, -alpha, -color) board.pop() max_eval = max(max_eval, eval) alpha = max(alpha, eval) if alpha >= beta: break
return max_eval
def find_best_move(board, depth): best_move = None best_value = float('-inf') alpha = float('-inf') beta = float('inf') color = 1 if board.turn else -1
print(f"Na tahu je: {'bílý' if board.turn else 'černý'}")
for move in board.legal_moves: print(move.uci()) # Vypíše tahy ve formátu UCI if move.uci() == "c1c2": # Příklad pro tah bílého krále print("HERE") board.push(move) board_value = -negamax(board, depth - 1, -beta, -alpha, -color) board.pop()
if board_value > best_value: best_value = board_value best_move = move
return best_move
# Hlavní část kódu#start_position = "8/8/8/8/8/7Q/k7/2K5 w - - 0 1"#start_position = "8/3k4/8/8/8/8/1K6/8 w - - 0 1"start_position = "8/3k4/8/8/8/8/1K1p4/8 w - - 0 1"board = chess.Board(start_position)depth = 11 # Můžete zvážit snížení hloubky pro rychlejší výsledkylast_time_printed = time.time()
positions_count_thread = threading.Thread(target=update_positions_count, args=(last_time_printed,), daemon=True)positions_count_thread.start()
print(board)print()
while not board.is_game_over(): best_move = find_best_move(board, depth) if best_move is not None: board.push(best_move) print("\n", board) # Vytiskne šachovnici po provedení nejlepšího tahu else: print("Žádný další legální tah není možný.") break
print("\nKonec hry")[/python]