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")
