I have a working 1600 blitz level bot but it works too slow in python using python chess library. I tried to optimize the functions in eval function but the best it can do is depth 4 since it takes a second for average of 6000 nodes, and the functions are not even that complex, doubled pawns, king safety,material,piece tables etc. Even without an evaluation function it takes 1 second for 8000 nodes on average, i looked at other python engines and it seems that it's slow in general, should I switch to C++? On average 6 second is passed for a move but sometimes it takes like 18 seconds for a move with quiescence search with minimax alpha beta pruning. I use MVV-LVA move ordering; therefore, it reduces time by half but still its too much for some moves. Tried delta pruning, don't know if the implementation is correct tho, the execution time is about the same if delta = 880(queen) but when its around 200 it halves in middle game. Don't know if it's the best approach to keep it 200, open to any ideas, i'm new at these topics, and this engine really needs to work faster. It really plays bad when delta is 200.
This is the quiescence search:
def search_captures(self, alpha, beta, maximizing_player, delta=200):
self.number_of_positions += 1
# Static evaluation at the current position
if self.board.is_checkmate():
return -10000 if maximizing_player else 10000
stand_pat = self.eval_func(maximizing_player)
# Delta pruning: Skip this branch if even the best possible gain
# cannot exceed alpha (for maximizing player) or beta (for minimizing player)
if maximizing_player:
if stand_pat + delta <= alpha:
return alpha
else:
if stand_pat -delta >= beta:
return beta
# Alpha-beta bounds adjustment
if maximizing_player:
if stand_pat >= beta:
return beta
alpha = max(alpha, stand_pat)
else:
if stand_pat <= alpha:
return alpha
beta = min(beta, stand_pat)
# Generate capture moves
capture_moves = [
move for move in self.board.legal_moves if self.board.is_capture(move)
]
# Sort capture moves to improve pruning
capture_moves = sorted(
capture_moves,
key=lambda move: self.capture_heuristic(move),
reverse=True
)
# Evaluate each capture move
for move in capture_moves:
self.board.push(move)
# Recursive quiescence search for the new position
eval = self.search_captures(alpha, beta, not maximizing_player, delta)
self.board.pop()
# Alpha-beta pruning
if maximizing_player:
if eval >= beta:
return beta
alpha = max(alpha, eval)
else:
if eval <= alpha:
return alpha
beta = min(beta, eval)
return alpha if maximizing_player else beta
Profiler:
Normally it takes 8 seconds for this move but with profiler it took 27 seconds.


eval_func()(and the functions it calls), which you're not showing here...