Skip to content

Commit

Permalink
Merge pull request #63 from hrushikeshrv/simplify_board
Browse files Browse the repository at this point in the history
Simplified board attributes
  • Loading branch information
hrushikeshrv authored Mar 7, 2023
2 parents 1db7f11 + e5d2eb2 commit cb51b74
Show file tree
Hide file tree
Showing 42 changed files with 935 additions and 425 deletions.
133 changes: 48 additions & 85 deletions chessengine/bitboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,41 +83,7 @@ def __init__(self, side: str):
self.black_queens = 576460752303423488 # (D8)
self.black_kings = 1152921504606846976 # (E8)

self.all_white = (
self.white_pawns
| self.white_rooks
| self.white_knights
| self.white_bishops
| self.white_queens
| self.white_kings
)

self.all_black = (
self.black_pawns
| self.black_rooks
| self.black_knights
| self.black_bishops
| self.black_queens
| self.black_kings
)

self.all_pieces = self.all_black | self.all_white

self.score = 0
self.piece_count = {
("white", "kings"): 1,
("white", "queens"): 1,
("white", "rooks"): 2,
("white", "bishops"): 2,
("white", "knights"): 2,
("white", "pawns"): 8,
("black", "kings"): 1,
("black", "queens"): 1,
("black", "rooks"): 2,
("black", "bishops"): 2,
("black", "knights"): 2,
("black", "pawns"): 8,
}

if side.lower().strip() not in ["black", "white"]:
raise ValueError(f'side must be one of "black" or "white". Got {side}')
Expand All @@ -129,9 +95,16 @@ def __init__(self, side: str):
self.black_king_side_castle = True
self.black_queen_side_castle = True

# A dictionary matching a side and piece to its corresponding bit board.
# Useful when we want to iterate through all of the bitboards of the board.
self.board = {
# Keep track of all moves made
self.moves = []

@property
def board(self):
"""
A dictionary mapping a side and piece to its corresponding bitboard.
Useful when we want to iterate over all the bitboards of the board
"""
return {
("white", "kings"): self.white_kings,
("white", "queens"): self.white_queens,
("white", "rooks"): self.white_rooks,
Expand All @@ -146,8 +119,44 @@ def __init__(self, side: str):
("black", "pawns"): self.black_pawns,
}

# Keep track of all moves made
self.moves = []
@property
def all_white(self):
return (
self.white_pawns
| self.white_rooks
| self.white_knights
| self.white_bishops
| self.white_queens
| self.white_kings
)

@property
def all_black(self):
return (
self.black_pawns
| self.black_rooks
| self.black_knights
| self.black_bishops
| self.black_queens
| self.black_kings
)

@property
def all_pieces(self):
return (
self.black_pawns
| self.black_rooks
| self.black_knights
| self.black_bishops
| self.black_queens
| self.black_kings
| self.white_pawns
| self.white_rooks
| self.white_knights
| self.white_bishops
| self.white_queens
| self.white_kings
)

def __repr__(self):
piece_list = ["." for _ in range(64)]
Expand Down Expand Up @@ -345,47 +354,6 @@ def get_self_piece_bitboard(self, piece: str) -> int:
"""
return self.get_bitboard(side=self.side, piece=piece)

def update_board_state(self) -> None:
"""
Updates all Board attributes when a move is made or the state of the Board
changes in any way. You should call this if you manually make any changes to
bitboards attributes, otherwise it is called automatically.
"""
self.all_white = (
self.white_pawns
| self.white_rooks
| self.white_knights
| self.white_bishops
| self.white_queens
| self.white_kings
)

self.all_black = (
self.black_pawns
| self.black_rooks
| self.black_knights
| self.black_bishops
| self.black_queens
| self.black_kings
)

self.all_pieces = self.all_black | self.all_white

self.board = {
("white", "kings"): self.white_kings,
("white", "queens"): self.white_queens,
("white", "rooks"): self.white_rooks,
("white", "bishops"): self.white_bishops,
("white", "knights"): self.white_knights,
("white", "pawns"): self.white_pawns,
("black", "kings"): self.black_kings,
("black", "queens"): self.black_queens,
("black", "rooks"): self.black_rooks,
("black", "bishops"): self.black_bishops,
("black", "knights"): self.black_knights,
("black", "pawns"): self.black_pawns,
}

def set_bitboard(self, side: str, piece: str, board: int) -> None:
"""
Sets the bitboard for the passed arguments to the passed bitboard
Expand All @@ -396,7 +364,6 @@ def set_bitboard(self, side: str, piece: str, board: int) -> None:
"""
attrname = side + "_" + piece
setattr(self, attrname, board)
self.update_board_state()

def identify_piece_at(self, position: int) -> tuple:
"""
Expand Down Expand Up @@ -515,7 +482,6 @@ def move(self, start: int, end: int, score: int = None, track: bool = True) -> N
black_pawn_bb = self.get_bitboard("black", "pawns")
black_pawn_bb &= clear_position[end >> 8]
self.set_bitboard("black", "pawns", black_pawn_bb)
self.piece_count[("black", "pawns")] -= 1
self.en_passant_position = 0

# Clear self.en_passant_position
Expand All @@ -533,7 +499,6 @@ def move(self, start: int, end: int, score: int = None, track: bool = True) -> N
white_pawn_bb = self.get_bitboard("white", "pawns")
white_pawn_bb &= clear_position[end << 8]
self.set_bitboard("white", "pawns", white_pawn_bb)
self.piece_count[("white", "pawns")] -= 1
self.en_passant_position = 0

# Clear self.en_passant_position
Expand All @@ -548,7 +513,6 @@ def move(self, start: int, end: int, score: int = None, track: bool = True) -> N
opp_side_board = self.get_bitboard(end_side, end_piece)
opp_side_board &= clear_position[end]
self.set_bitboard(end_side, end_piece, opp_side_board)
self.piece_count[(end_side, end_piece)] -= 1

# Clear the moved piece's original position (set "start" to 0)
move_side_board = self.get_bitboard(start_side, start_piece)
Expand Down Expand Up @@ -772,7 +736,6 @@ def undo_move(self) -> None:
self.move(start=start, end=end, track=False)
if side is not None:
self.set_bitboard(side, piece, board)
self.piece_count[(side, piece)] += 1

def get_moves(
self, side: str, piece: str = None, position: int = None
Expand Down
Binary file modified docs/_build/doctrees/api.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/chessboard.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/contributing.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/environment.pickle
Binary file not shown.
Binary file modified docs/_build/doctrees/index.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/playing.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.bitboard.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.exceptions.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.lookup_tables.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.moves.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.pgn.node.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.pgn.parser.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/ref/chessengine.utils.doctree
Binary file not shown.
Binary file modified docs/_build/doctrees/usage.doctree
Binary file not shown.
5 changes: 3 additions & 2 deletions docs/_build/html/_sources/chessboard.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ Attributes For Chess Board
- A dictionary mapping tuples of the format ``(side, piece)`` to the corresponding bitboard. For example, ``board[("white", "pawns")]`` returns the bitboard corresponding to white pawns.
* - ``Board.moves``
- ``list[tuple]``
- A list of all moves made on the board. Moves are stored as a 6-tuple in the format ``(start, end, captured_side, captured_piece, captured_bitboard, castle_type)`` where -
- A list of all moves made on the board. Moves are stored as a 6-tuple in the format ``(start, end, captured_side, captured_piece, captured_bitboard, castle_type, score)`` where -
* ``start`` is the :ref:`position <position_representation>` the piece started from
* ``end`` is the position the piece landed on
* ``captured_side`` is the side of the piece captured (if any, else ``None``)
* ``captured_piece`` is the piece captured (if any, else ``None``)
* ``captured_bitboard`` is the bitboard of the captured piece before it was captured (used to restore it when we want to undo moves).
* ``castle_type`` is a string representing the castle type the move was (if it was a castle), else ``None``. ``castle_type`` can take values ``"white_kingside"``, ``"white_queenside"``, ``"black_kingside"``, ``"black_queenside"``.
* ``score`` is the score (current static evaluation) of the board
* - ``Board.piece_count``
- ``dict[tuple[str,str], int]``
- A dictionary mapping tuples of the format (side, piece) to the number of pieces of that side on the board currently. For example, at the start of the game ``piece_count[("white", "pawns")]`` will be 8.
Expand Down Expand Up @@ -130,4 +131,4 @@ be specified as mentioned here. Moreover, the ``Board.move`` function also requi
its ``start`` and ``end`` arguments.

To help with converting between coordinates on the board, positions, and powers
of 2, you can use the ``chessengine.lookup_tables`` module.
of 2, you can use the :ref:`lookup_tables` module.
69 changes: 56 additions & 13 deletions docs/_build/html/_sources/ref/chessengine.lookup_tables.rst.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,66 @@
chessengine.lookup\_tables
.. _lookup_tables:

chessengine.lookup\_tables
==========================

.. automodule:: chessengine.lookup_tables




.. py:data:: pos_to_coords
:type: dict[int, str]

A dictionary mapping position *indices* on the board to their square names. 0 is mapped to "A1", 1
is mapped to "B1", 8 is mapped to "A2", 9 is mapped to "B2", and so on.


.. py:data:: coords_to_pos
:type: dict[str, int]

A dictionary mapping squares on the board to their position *indices*. Basically the reverse mapping
of ``pos_to_coords``. "A1" is mapped to 0, "B1" is mapped to 1, "A2" is mapped to 8, "B2" is mapped
to 9, and so on.


.. py:data:: clear_rank
:type: dict[int, int]

A dictionary mapping ranks to a bitboard having 0s only on that rank. For example,
``clear_rank[1]`` is a bitboard having only 0s on positions on the first rank,
and 1s on all other positions.


.. py:data:: mask_rank
:type: dict[int, int]

A dictionary mapping ranks to a bitboard having 1s only on that rank, and 0s on all
other ranks. For example, ``mask_rank[1]`` is a bitboard having only 1s on positions
on the first rank, and 0s on all other position.


.. py:data:: clear_file
:type: dict[int, int]

A dictionary mapping files to a bitboard having 0s only on that file, and 1s on all
other ranks. For example, ``clear_file[1]`` is a bitboard having only 0s on positions
on the first file, and 1s on all other positions.


.. py:data:: mask_file



:type: dict[int, int]




A dictionary mapping files to a bitboard having 1s only on that file, and 0s on all
other ranks. For example, ``mask_file[1]`` is a bitboard having only 1s on positions
on the first file, and 0s on all other positions.





.. py:data:: clear_position
:type: dict[int, int]

A dictionary mapping *positions* to bitboards with a 0 at that position and 1 at all
other positions.
Loading

0 comments on commit cb51b74

Please sign in to comment.