Commit graph

113 commits

Author SHA1 Message Date
d2ee9244c2 [board] Update Position::player_has_right_to_castle callsites 2024-01-11 08:37:22 -08:00
094131822c [board] Implement move_formatter::AlgebraicMoveFormatter 2024-01-11 08:33:58 -08:00
caef0af244 [board] Implement Default for Position
Default returns an empty position.
2024-01-11 08:18:31 -08:00
0bc7e8d542 [board] Implement some castling checks on Move
Define some constants in Square that refer to the starting positions of the two
kings, and the target castling squares. Then implement the following methods that
use those constants to determine if a move is a castle.

- Move::is_kingside_castle()
- Move::is_queenside_castle()
- Move::is_castle()

These checks only apply to King moves, and if the king is moving from and to
specific squares.
2024-01-10 13:37:18 -08:00
31e5771d30 [board] Implement all the bit twiddling to track whether castling is allowed for each player and side of the board 2024-01-10 11:01:19 -08:00
8cc7e64ba6 [board] Fix a handful of linter warnings by allowing them
The linter also requires non-compliant formatting of the constants produced in
the coordinate_enum macro to be marked as allowed.
2024-01-06 20:51:23 -08:00
b62cd1fcd2 [board] Use Unicode chess characters to Display Pieces 2024-01-06 20:49:25 -08:00
ea8f5f47fd [board] A few miscellaneous clean ups in the moves module 2024-01-06 20:43:18 -08:00
e4a4477157 [board] Remove an unused BitBoard import from square.rs 2024-01-06 20:34:44 -08:00
626ac6245e [board] Copy the update_moves_with_ray macro into the rook move generator
This is an ugly copy/paste operation, but reduces the code in rook::ClassicalMoveGenerator somewhat.
2024-01-06 20:34:16 -08:00
edf7d1cd2f [board] Implement queen::ClassicalMoveGenerator
Implement a bishop move generator using the "classical" approach.
This approach walks each ray to find blockers and then masks out friendly pieces.
This is not efficient compared to other approaches, but it's much easier to implement.
2024-01-06 20:33:30 -08:00
c6e799f722 [board] Implement bishop::ClassicalMoveGenerator
Implement a bishop move generator using the "classical" approach.
This approach walks each ray to find blockers and then masks out friendly pieces.
This is not efficient compared to other approaches, but it's much easier to implement.
2024-01-06 20:06:54 -08:00
359bab9173 [board] Implement rook::ClassicalMoveGenerator
Implement a rook move generator using the "classical" approach.
This approach walks each ray to find blockers and then masks out friendly pieces.
This is not efficient compared to other approaches, but it's much easier to implement.
2024-01-06 19:51:06 -08:00
6e483b412b [board] Refactor ray BitBoard lookups
Rearrange the generated ray bitboards into a 2D grid by square and direction.
Use the Direction vector for lookup.
2024-01-06 19:47:55 -08:00
2394afc210 [board] Implement a TrailingBitScanner
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
2024-01-06 19:46:09 -08:00
35756e28cf [board] Add some notes about board geometry 2024-01-06 17:02:07 -08:00
e2d93b8c3c [board] Replace implementations of the king and knight move generators with a more generic version
While implementing these move generators, I realized I was duplicating a lot of code. So, I started thinking about how to do less of that. I create a MoveGeneratorInternal trait that these move generators implement. This trait provides default implementations of several methods.

I also discovered that I needed a way to keep track of move sets per piece for each kind (shape) of piece. The new move generators, and the generators still to come, can now keep track of moves per piece separately in MoveSet instances.
2024-01-06 17:01:16 -08:00
bcab682bb1 [board] Reimplement Square as an enum
Replace the implementation of Square as an enum. Add Rank and File enums to
support this.

Along the way, change implementations of various methods taking Squares and
BitBoards to take them by value instead of by reference. I don't think much is
gained passing these types by reference because they're such small POD structs.
2024-01-06 16:56:19 -08:00
14db74f212 Remove tests module 2024-01-06 16:45:13 -08:00
3b266cb94a Update king move generator tests 2024-01-06 16:40:21 -08:00
216140bdbc Update knight move generator 2024-01-06 16:39:24 -08:00
46495ce581 Update Pawn move generator 2024-01-06 16:39:11 -08:00
c79c05ddb6 Fix Pieces unit tests 2024-01-06 16:34:05 -08:00
c3e3ebfa97 Iterate by Rank and File when building a diagram 2024-01-06 16:25:03 -08:00
aac1a85507 In Position::place_piece, take piece and square by value
Use values for BitBoards and other things too.
2024-01-06 16:24:46 -08:00
657a501cb5 Take self by value in all BitBoard shift methods 2024-01-06 16:22:39 -08:00
5a7e498d5d Iterate on Squares when building the BitBoard library 2024-01-06 16:22:22 -08:00
ff839db041 BitBoard changes
- 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
2024-01-06 16:21:40 -08:00
2105004dc2 Reimplement Square as an enum; implement Rank and File enums
Replace the Square struct with an enum. This implementation is based on this one:

https://github.com/analog-hors/magic-bitboards-demo/blob/main/types/src/square.rs

This reduces a lot of code needed to construct squares, ranks, and files.
2024-01-06 16:08:34 -08:00
1689da9908 [board] Derive Ord and PartialOrd on Square 2024-01-06 08:50:27 -08:00
7c2b9ed97a [board] Add inline and const modifiers to methods on PlacedPiece 2024-01-06 08:49:51 -08:00
b842b3520b [board] Implement a MoveSet struct
This struct represents a set of moves for a PlacedPiece
2024-01-05 18:30:00 -08:00
e232d3e19b [board] Implement Into<BitBoard> on Squares
Returns a BitBoard representing the square.
2024-01-05 18:29:03 -08:00
3b3062108a [board] Implement fmt::Display on Square
Prints the square in algebraic notation
2024-01-05 18:29:01 -08:00
769886086c [board] Get king moves from the bitboard library 2024-01-02 08:42:47 -08:00
b95c34f51e [board] Implement KnightMoveGenerator
Use the generated knight_moves BitBoards from bitboard::MoveLibrary to generate knight moves.

This commit doesn't yet implement computing bitboards for knight moves.
2024-01-01 09:37:44 -08:00
fb6fd27453 [board] Remove Iterator implementations form move generator types; replace it with an iter() method
I was given some guidance[1] on the Rust developer forums that my approach of
implementing Iterator on these types wasn't quite right.

> In general, iterators are distinct data structures than the primary struct
that owns the data, in part due to issues like this, but also due to concerns
around iterator invalidation and the need to carry around iteration state more
generally.

I took this to heart and replace the Iterator implementations with an iter()
method that returns an `impl Iterator<Item=Move>`. This works so much better and
lets me delete a bunch of code!

Additionally, the iter() methods on the piece-wise move generator types return
`impl Iterator<Item=&Move>`, and then the top-level Moves::iter() returns a
.cloned().

Overall I'm really happy with this!

[1]: https://users.rust-lang.org/t/tricky-lifetime-may-not-live-long-enough-error-on-an-iterator-wrapping-a-boxed-iterator/104650/3
2024-01-01 09:33:37 -08:00
06bfc4ac57 [board] Implement a BitBoard MoveLibrary
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.
2024-01-01 09:25:35 -08:00
4a54d8b877 [board] Implement KingMoveGenerator
Generate moves for kings.

This struct is trying out a different approach to iterators where the type
itself isn't one, but it has an iter() method that returns an iterator over all
the move lists.

This struct also builds all the moves up front, in new() before the new instance
is returned.
2023-12-31 16:35:34 -08:00
af36b75df7 [board] Implement a pawn move generator
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.
2023-12-31 11:44:47 -08:00
750b16970f [board] Create const arrays for Shape that return &'static to its enum cases 2023-12-31 11:44:47 -08:00
878d771d86 [board] Replace Moves' separate properties with a Vec of Iterators
This makes iteration easier. Move to the next iterator if the current one returns None.
No tests for Moves yet though.
2023-12-31 11:44:47 -08:00
c2c0af20fb [board] Extend the Move type with two builder-style methods for capturing and promotion
These two methods replace self with one that has a populated capture or promotion field.
2023-12-31 09:28:21 -08:00
adc2f76e00 [board] Change the type of BitScanner.shift form u32 to usize 2023-12-31 09:27:16 -08:00
1cc8b4520f [board] Return copies of rank and file bitboards from static lists 2023-12-31 09:26:20 -08:00
e30bcb3105 [board] Implement BitBoard::file and fmt::Display for BitBoard
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.
2023-12-30 10:26:37 -08:00
c280258780 [board] Remove an unused local variable from pieces.rs 2023-12-29 16:34:26 -08:00
53dc80b6bb [board] Implement BitAndAssign and BitOrAssign on BitBoard 2023-12-29 16:34:11 -08:00
808222eef1 [board] Clean up the formatting of BitBoards
Use debug_tuple in the fmt::Debug implementation.
Implement fmt::Binary, fmt::UpperHex, and fmt::LowerHex by delegating to u64's version.
2023-12-29 15:37:38 -08:00
41421dddbb [board] Clean up interfaces of pieces and square structs 2023-12-29 09:17:33 -08:00