Skip to content

Commit

Permalink
Made search 4x faster
Browse files Browse the repository at this point in the history
  • Loading branch information
hrushikeshrv committed Jan 30, 2023
1 parent 78c9ccf commit 9774588
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 44 deletions.
2 changes: 1 addition & 1 deletion chessengine/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.3.1"
__version__ = "0.3.2"

from chessengine.bitboard import Board
from chessengine import moves
Expand Down
20 changes: 14 additions & 6 deletions chessengine/bitboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,13 @@ def copy(self):
Create and return a copy of the board.
"""
return copy(self)

def evaluate_score(self) -> int:
"""
Evaluate the current score/evaluation of the board state. Use this method to
reset the board score to the correct value if the game starts from an intermediate
stage.
:return: The score/evaluation of the current board state.
"""
s = 0
Expand All @@ -296,7 +296,7 @@ def evaluate_score(self) -> int:
"kings": 20000,
}
for i in range(64):
pos = 2 ** i
pos = 2**i
side, piece, _ = self.identify_piece_at(pos)
if side is None:
continue
Expand Down Expand Up @@ -490,7 +490,15 @@ def move(self, start: int, end: int, score: int = None, track: bool = True) -> N

# Track moves made so we can undo
if track:
start_state = (start, end, end_side, end_piece, end_board, castle_type, self.score)
start_state = (
start,
end,
end_side,
end_piece,
end_board,
castle_type,
self.score,
)
self.moves.append(start_state)

# Check en passant moves
Expand Down Expand Up @@ -567,7 +575,7 @@ def move(self, start: int, end: int, score: int = None, track: bool = True) -> N
self.move(2**56, 2**59, False) # Don't track this move
self.black_king_side_castle = False
self.black_queen_side_castle = False

# Update the board evaluation
if track:
if score is None:
Expand Down Expand Up @@ -718,7 +726,7 @@ def undo_move(self) -> None:
raise RuntimeError("No moves have been made yet to undo.")
end, start, side, piece, board, castle_type, prev_score = self.moves.pop()
self.score = prev_score

if castle_type is not None:
# TODO - if user castles when both self.white_kingside and self.white_queenside are
# True, undoing this move only lets the user castle to the same side they castled
Expand Down
98 changes: 63 additions & 35 deletions chessengine/moves.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,19 @@ def get_rook_moves(board, side: str, position: int) -> list[tuple[int, int, int]
while True:
# Move rank up
_ = _ << 8
valid, should_break = check_valid_position(board, side, 'rooks', position, _, moves)
valid, should_break = check_valid_position(
board, side, "rooks", position, _, moves
)
if should_break:
break

_ = position
while True:
# Move rank down
_ = _ >> 8
valid, should_break = check_valid_position(board, side, 'rooks', position, _, moves)
valid, should_break = check_valid_position(
board, side, "rooks", position, _, moves
)
if should_break:
break

Expand All @@ -86,7 +90,9 @@ def get_rook_moves(board, side: str, position: int) -> list[tuple[int, int, int]
for i in range(max_right):
# Move right
_ = _ << 1
valid, should_break = check_valid_position(board, side, 'rooks', position, _, moves)
valid, should_break = check_valid_position(
board, side, "rooks", position, _, moves
)
if should_break:
break

Expand All @@ -95,7 +101,9 @@ def get_rook_moves(board, side: str, position: int) -> list[tuple[int, int, int]
for i in range(max_left):
# Move left
_ = _ >> 1
valid, should_break = check_valid_position(board, side, 'rooks', position, _, moves)
valid, should_break = check_valid_position(
board, side, "rooks", position, _, moves
)
if should_break:
break

Expand Down Expand Up @@ -136,29 +144,37 @@ def get_bishop_moves(board, side: str, position: int) -> list[tuple[int, int, in
_ = position
for i in range(max_right):
_ = _ << 9
valid, should_break = check_valid_position(board, side, 'bishops', position, _, moves)
valid, should_break = check_valid_position(
board, side, "bishops", position, _, moves
)
if should_break:
break

_ = position
for i in range(max_right):
_ = _ >> 7
valid, should_break = check_valid_position(board, side, 'bishops', position, _, moves)
valid, should_break = check_valid_position(
board, side, "bishops", position, _, moves
)
if should_break:
break

max_left = file - 1
_ = position
for i in range(max_left):
_ = _ << 7
valid, should_break = check_valid_position(board, side, 'bishops', position, _, moves)
valid, should_break = check_valid_position(
board, side, "bishops", position, _, moves
)
if should_break:
break

_ = position
for i in range(max_left):
_ = _ >> 9
valid, should_break = check_valid_position(board, side, 'bishops', position, _, moves)
valid, should_break = check_valid_position(
board, side, "bishops", position, _, moves
)
if should_break:
break

Expand Down Expand Up @@ -200,34 +216,34 @@ def get_knight_moves(board, side: str, position: int) -> list[tuple[int, int, in
if rank >= 3:
if file >= 2:
_ = position >> 17
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)
if file <= 7:
_ = position >> 15
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)

if rank >= 2:
if file >= 3:
_ = position >> 10
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)
if file <= 6:
_ = position >> 6
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)

if rank <= 6:
if file >= 2:
_ = position << 15
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)
if file <= 7:
_ = position << 17
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)

if rank <= 7:
if file >= 3:
_ = position << 6
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)
if file <= 6:
_ = position << 10
check_valid_position(board, side, 'knights', position, _, moves)
check_valid_position(board, side, "knights", position, _, moves)

return moves

Expand Down Expand Up @@ -267,35 +283,35 @@ def get_king_moves(board, side: str, position: int) -> list[tuple[int, int, int]

if rank >= 2:
_ = position >> 8
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file >= 2:
_ = position >> 9
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file <= 7:
_ = position >> 7
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if rank <= 7:
_ = position << 8
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file >= 2:
_ = position << 7
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file <= 7:
_ = position << 9
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file >= 2:
_ = position >> 1
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if file <= 7:
_ = position << 1
check_valid_position(board, side, 'kings', position, _, moves)
check_valid_position(board, side, "kings", position, _, moves)

if side == "white":
if board.white_queen_side_castle:
Expand Down Expand Up @@ -373,35 +389,41 @@ def get_white_pawn_moves(board, position: int) -> list[tuple[int, int, int]]:
_ = position << 8
if board.all_pieces & _ == 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('white', 'pawns', position, _, end_piece, board.score)
score = score_from_move("white", "pawns", position, _, end_piece, board.score)
moves.append((position, _, score))
if rank == 2:
_ = position << 16
if board.all_pieces & _ == 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('white', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"white", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))
file = get_file(position)
if file >= 2:
_ = position << 7
if board.all_black & _ > 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('white', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"white", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))
if file <= 7:
_ = position << 9
if board.all_black & _ > 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('white', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"white", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))

en_passant_position = board.en_passant_position
if en_passant_position == position << 7 and file >= 2:
_ = position << 7
check_valid_position(board, "white", 'pawns', position, _, moves)
check_valid_position(board, "white", "pawns", position, _, moves)
if en_passant_position == position << 9 and file <= 7:
_ = position << 9
check_valid_position(board, "white", 'pawns', position, _, moves)
check_valid_position(board, "white", "pawns", position, _, moves)

return moves

Expand All @@ -421,32 +443,38 @@ def get_black_pawn_moves(board, position: int) -> list[tuple[int, int, int]]:
_ = position >> 8
if board.all_pieces & _ == 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('black', 'pawns', position, _, end_piece, board.score)
score = score_from_move("black", "pawns", position, _, end_piece, board.score)
moves.append((position, _, score))
if rank == 7:
_ = position >> 16
if board.all_pieces & _ == 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('black', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"black", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))
file = get_file(position)
if file >= 2:
_ = position >> 9
if board.all_white & _ > 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('black', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"black", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))
if file <= 7:
_ = position >> 7
if board.all_white & _ > 0:
end_side, end_piece, end_board = board.identify_piece_at(_)
score = score_from_move('black', 'pawns', position, _, end_piece, board.score)
score = score_from_move(
"black", "pawns", position, _, end_piece, board.score
)
moves.append((position, _, score))

en_passant_position = board.en_passant_position
if en_passant_position == position >> 9 and file >= 2:
_ = position >> 9
check_valid_position(board, "black", 'pawns', position, _, moves)
check_valid_position(board, "black", "pawns", position, _, moves)
if en_passant_position == position >> 7 and file <= 7:
_ = position >> 7
check_valid_position(board, "black", "pawns", position, _, moves)
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
project = "chessengine"
copyright = "2022, Hrushikesh Vaidya"
author = "Hrushikesh Vaidya"
release = "0.3.1"
release = "0.3.2"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ openings = ["*.pgn"]

[project]
name = "chessengine"
version = "0.3.1"
version = "0.3.2"
authors = [
{name="Hrushikesh Vaidya", email="hrushikeshrv@gmail.com"},
]
Expand Down

0 comments on commit 9774588

Please sign in to comment.