I have a rather simple chess endgame Python code implementinng
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
I'm even unable to force the code
I would like if some can dig into the code and tell me what's wrong
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:
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

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:
import chess import time import threading # Globální proměnná pro sledování počtu prohledaných pozic positions_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 algoritmus def 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ýsledky last_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")