I’m in the beginnings of creating a chess engine written in python and I was wondering of ways to improve the move generation part. Generating pseudo-legal moves I can do about 30/40 K moves/s on my computer and with the slow move validation I have written that drops down to about 11 K moves/s but I am in the midst of writing a better version.
I use a 1D array of two character strings (though my previous version using 2D arrays was faster) and I have made both a Move and a Board State class. I have already implemented slots and I was looking for a way to speed up the classes even more. I have tried numba but I could not get it to work as I am passing a Board State obj in the Move class constructor and so the code did not compile with numba. Are there any other libraries that can be used in this case. The code can be found here: https://github.com/FedericoSaitta/Chess/tree/master/Files
- I should also mention that I am running the engine script on a GUI in pygame handled by the main.py file.
Here are the constructors for my two classes:
class GameState: slots = ('board', 'white_to_move', 'moveLog', 'w_l_c', 'b_l_c', 'w_r_c', 'b_r_c', 'white_king_loc', 'black_king_loc', 'check_mate', 'stale_mate', 'white_en_passant_sq', 'black_en_passant_sq')
def __init__(self):
self.board = [ # Switching to a 1D board representation # Left right is +/- 1 and up and down is +/- 8
'bR', 'bN', 'bB', 'bQ', 'bK', 'bB', 'bN', 'bR', # 0 to 7
'bP', 'bP', 'bP', 'bP', 'bP', 'bP', 'bP', 'bP', # 8 to 15
'--', '--', '--', '--', '--', '--', '--', '--', # 16 to 23
'--', '--', '--', '--', '--', '--', '--', '--', # 24 to 31
'--', '--', '--', '--', '--', '--', '--', '--', # 32 to 39
'--', '--', '--', '--', '--', '--', '--', '--', # 40 to 47
'wP', 'wP', 'wP', 'wP', 'wP', 'wP', 'wP', 'wP', # 48 to 55
'wR', 'wN', 'wB', 'wQ', 'wK', 'wB', 'wN', 'wR'] # 56 to 63
self.white_to_move = True
self.moveLog = []
self.w_l_c, self.b_l_c = True, True # Castling rights for white and black
self.w_r_c, self.b_r_c = True, True
self.white_king_loc = (60) # Make sure to change these once you change to a new board
self.black_king_loc = (4)
self.check_mate, self.stale_mate = False, False
self.white_en_passant_sq, self.black_en_passant_sq = (None, None), (None, None)
And class Move:
__slots__ = ('start_ind', 'end_ind', 'move_ID',
'piece_moved', 'piece_captured', 'castle_move', 'en_passant')
def __init__(self, start_sq, end_sq, board, castle_move=False, en_passant=False):
self.start_ind = start_sq
self.end_ind = end_sq
self.move_ID = self.start_ind * 100 + self.end_ind
self.piece_moved = board[self.start_ind]
self.piece_captured = board[self.end_ind]
self.castle_move = castle_move
self.en_passant = en_passant