Turns out I was doing the starting position really wrong. In an upcoming commit,
I will implement FEN output for Positions. While doing that work, I found several
issues that were causing the output of the FEN formatter to return garbage.
Implement a handful of unit tests to track down the errors.
Rename Shape::_ascii_representation() → Shape::to_ascii.
Implement to_ascii() on Piece.
This builder takes a Position and a Move, validates the move, and makes the move
in that position. Its build() method returns a new Position with the move made.
Implement bitwise AND and OR for all permutations of BitBoard and &BitBoard.
Refer to the std::ops traits by fully-qualified path rather than requiring the
module to import those traits to implement them.
Implement bitwise AND and OR assignment (&= and |=) for BitBoard and &BitBoard.
Implement XOR and XOR assignment for BitBoards.
This makes Position immutable, even if declared mut. I think this will also make
it easier to build positions going forward.
Moving to a PieceBitBoards struct also required a lot of places that return owned
BitBoards to return refs. This is basically fine except for adding a few more &
here and there.
This was a huge refactoring project. All the move generators and a bunch of
BitBoard stuff needed to be updated.
The Builder enables cleanly building a BitBoard out of squares.
The macro lets you create a BitBoard from a simple list of coordinates:
bitboard!(A1, B2, C3, D4, …)
This bit scanner iterates populated bits in a BitBoard from the trailing (least-significant) end.
Rename BitScanner → LeadingBitScanner.
Factor implementation of these two into a macro.
Clean up iterator returned by BitBoard::occupied_squares
Implement BitBoard::occupied_squares_trailing
- Clean up operator traits: remove the & versions and make the macro do more with less input
- Implement From<Square> for BitBoards: simplify conversion of Squares to BitBoards
- Take BitBoards by value in several places
- Clean up unit tests
This struct computes and stores piece moves per square to speed up computation
of move lists.
Initialize a `static mut` instance once via std::sync::Once, and return a static
reference to it. So far, it computes king and knight moves.
Make BitBoard::empty() and MoveLibrary::new() const functions, enabling static
construction of the MOVE_LIBRARY instance without needing to wrap it in an
Option.
Holy heck I went on a *journey* here. Ultimately, I needed to implement my own
index-based iterator instead of using the Vec's Iterator.
This type establishes some patterns I want to carry forward to other move
generators.
1. The use of a Parameters struct to fully parameterize the move generation
per-color. That lets these types only need a single color-based branch
2. A list of move lists, one list for each of captures, promotions, and quiet
moves.
3. An index-based move iterator.
4. Separate impl for generating bitboard representations of these moves
Additional changes:
- Implement BitBoard::from_square()
- Implement a Square::e5() for tests
This class doesn't implement en passant yet. It also doesn't yet have tests for
the bitboard stuff.
BitBoard::file returns a BitBoard representing the 0-indexed file.
fmt::Display prints a grid of bits in the standard orientation (white on bottom, left to right)
Add asserts to the rank and file constructors to catch out of bounds arguments.
Move position.rs to the position module and create a mod.rs.
Do the same for bitboard.rs in the bitboard modules.
Export Color, Piece, Position, and Square and use crate::Thing directly instead of referring to the symbol in the nested modules.