Question:
My engine takes 30 secs to generate a move. When i decrease the time, the engine starts making mistakes. How can I make this time faster while still letting the engine generate a good move?
Repl link:
https://replit.com/@jcsan/Tortoi#main.py
import chess
import time
import chess.polyglot
board = chess.Board()
book = chess.polyglot.open_reader("baron30.bin")
material = {
chess.PAWN:10.0,
chess.KNIGHT:32.0,
chess.BISHOP:33.3,
chess.ROOK:56.5,
chess.QUEEN:95.5,
chess.KING:200.0
}
scoring = {
'Pawn': [
0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 2, 3, 3, 2, 1, 1, 0, 0,
0, 2, 2, 0, 0, 0, 0, 0, 0, -2, -2, 0, 0, 0, 1, -1, -2, 0, 0, -2, -1, 1, 1, 2,
2, -2, -2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0
],
'Knight': [
-5, -4, -3, -3, -3, -3, -4, -5, -4, -2, 0, 0, 0, 0, -2, -4, -3, 0, 1, 1.5,
1.5, 1, 0, -3, -3, 0.5, 1.5, 2, 2, 1.5, 0.5, -3, -3, 0.5, 1.5, 2, 2, 1.5,
0.5, -3, -3, 0, 1, 1.5, 1.5, 1, 0, -3, -4, -2, 0, 0.5, 0.5, 0, -2, -4, -5,
-4, -3, -3, -3, -3, -4, -5
],
'Bishop': [
-2,
-1,
-1,
-1,
-1,
-1,
-1,
-2,
-1,
0.25,
0,
0,
0,
0,
0.25,
-1,
-1,
0,
1,
1,
1,
1,
0,
-1,
-1,
0,
1,
1.5,
1.5,
1,
0,
-1,
-1,
0,
1,
1.5,
1.5,
1,
0,
-1,
-1,
0,
1,
1,
1,
1,
0,
-1,
-1,
0.25,
0,
0,
0,
0,
0.25,
-1,
-2,
-1,
-1,
-1,
-1,
-1,
-1,
-2,
],
'Rook': [
0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 1, 1, 1, 1, 1, 0.5, -0.5, 0, 0, 0, 0, 0, 0,
-0.5, -0.5, 0, 0, 0, 0, 0, 0, -0.5, -0.5, 0, 0, 0, 0, 0, 0, -0.5, -0.5, 0, 0,
0, 0, 0, 0, -0.5, -0.5, 1, 1, 1, 1, 1, 1, -0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0
],
'Queen': [
-2, -1, -1, -0.5, -0.5, -1, -1, -2, -1, 0, 0.5, 0, 0, 0.5, 0, -1, -1, 0.5,
0.5, 0.5, 0.5, 0.5, 0.5, -1, -0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5, 0, 0, 0.5,
0.5, 0.5, 0, 0, 0, -0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5, -1, 0.5, 0.5, 0.5,
0.5, 0.5, 0.5, -1, -2, -1, -1, -0.5, -0.5, -1, -1, -2
],
'King': [
-3, -4, -4, -5, -5, -4, -4, -3, -3, -4, -4, -5, -5, -4, -4, -3, -3, -4, -4,
-5, -5, -4, -4, -3, -3, -4, -4, -5, -5, -4, -4, -3, -2, -3, -3, -4, -4, -3,
-3, -2, -1, -2, -2, -2, -2, -2, -2, -1, 2, 2, 0, 0, 0, 0, 2, 2, 2, 3, 1, 0,
0, 1, 3, 2
],
}
pawn_table = scoring['Pawn']
knight_table = scoring['Knight']
bishop_table = scoring['Bishop']
rook_table = scoring['Rook']
queen_table = scoring['Queen']
king_table = scoring['King']
def evaluate(board):
score = 0.00
pst_score = 0.00
pieces = board.piece_map()
for square, piece in pieces.items():
if piece.color:
score += material[piece.piece_type]
if piece.piece_type == chess.PAWN:
pst_score += pawn_table[square]
elif piece.piece_type == chess.KNIGHT:
pst_score += knight_table[square]
elif piece.piece_type == chess.BISHOP:
pst_score += bishop_table[square]
elif piece.piece_type == chess.ROOK:
pst_score += rook_table[square]
elif piece.piece_type == chess.QUEEN:
pst_score += queen_table[square]
elif piece.piece_type == chess.KING:
pst_score += king_table[square]
else:
score -= material[piece.piece_type]
if piece.piece_type == chess.PAWN:
pst_score -= pawn_table[chess.square_mirror(square)]
elif piece.piece_type == chess.KNIGHT:
pst_score -= knight_table[chess.square_mirror(square)]
elif piece.piece_type == chess.BISHOP:
pst_score -= bishop_table[chess.square_mirror(square)]
elif piece.piece_type == chess.ROOK:
pst_score -= rook_table[chess.square_mirror(square)]
elif piece.piece_type == chess.QUEEN:
pst_score -= queen_table[chess.square_mirror(square)]
elif piece.piece_type == chess.KING:
pst_score -= king_table[chess.square_mirror(square)]
if board.turn == chess.WHITE:
score += 0.4
else:
score -= 0.4
return score + pst_score
def highest_value(BOARD, depth=20, max_time=30):
start_time = time.time()
best_move = None
if BOARD.turn == chess.WHITE:
best_value = -float("inf")
else:
best_value = float("inf")
for d in range(1, depth + 1):
if time.time() - start_time > max_time:
break
for move in BOARD.legal_moves:
BOARD.push(move)
value = alpha_beta_search(BOARD, d)
BOARD.pop()
if BOARD.turn == chess.WHITE:
if value > best_value:
best_value = value
best_move = move
else:
if value < best_value:
best_value = value
best_move = move
return best_move
def alpha_beta_search(board,
depth,
alpha=-float("inf"),
beta=float("inf"),
maximizing_player=True):
if depth == 0 or board.is_game_over():
return evaluate(board)
if maximizing_player:
value = -float("inf")
for move in board.legal_moves:
board.push(move)
value = max(value, alpha_beta_search(board, depth - 1, alpha, beta, False))
board.pop()
alpha = max(alpha, value)
if alpha >= beta:
break
return value
else:
value = float("inf")
for move in board.legal_moves:
board.push(move)
value = min(value, alpha_beta_search(board, depth - 1, alpha, beta, True))
board.pop()
beta = min(beta, value)
if alpha >= beta:
break
return value
while True:
if (len(list(book.find_all(board))) != 0):
board.push(book.weighted_choice(board).move)
time.sleep(1)
print(board)
print(" ")
else:
best_move = highest_value(board)
board.push(best_move)
print(board)
print(" ")
if board.can_claim_draw() == True:
print("draw")
break
`