Skip to content

Commit

Permalink
chore: faster? idk. better ? yes
Browse files Browse the repository at this point in the history
  • Loading branch information
raklaptudirm committed May 25, 2024
1 parent 37517b1 commit 8669242
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 24 deletions.
5 changes: 5 additions & 0 deletions ataxx/src/bitboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ impl BitBoard {
pub fn msb(self) -> Square {
Square::try_from(63 - self.0.leading_zeros()).unwrap()
}

pub fn singles(self) -> BitBoard {
let bar = self | self.east() | self.west();
bar | bar.north() | bar.south()
}
}

// Iterator trait allows BitBoard to be used in a for loop.
Expand Down
32 changes: 8 additions & 24 deletions ataxx/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,13 +325,11 @@ impl Position {
// Pieces can only move to unoccupied Squares.
let allowed = !(stm | xtm | gap);

let mut single = BitBoard::EMPTY;
for piece in stm {
// All single moves to a single Square are equivalent, so a single
// BitBoard is sufficient to keep track of them all and cast out duplicates.
// An intersection with the allowed BitBoard is done once at the end.
single |= BitBoard::single(piece);
for target in stm.singles() & allowed {
movelist.push(Move::new_single(target));
}

for piece in stm {
// There may be multiple jump moves to a single Square, so they need to be
// verified (& allowed) and serialized into the movelist immediately.
let double = BitBoard::double(piece) & allowed;
Expand All @@ -340,12 +338,6 @@ impl Position {
}
}

// Serialize the single moves into the movelist.
single &= allowed;
for target in single {
movelist.push(Move::new_single(target));
}

// If there are no legal moves possible on the Position and the game isn't
// over, a pass move is the only move possible to be played.
if movelist.len() == 0 {
Expand All @@ -371,35 +363,27 @@ impl Position {
return 0;
}

let mut moves: usize = 0;

let stm = self.bitboard(self.side_to_move);
let xtm = self.bitboard(!self.side_to_move);
let gap = self.bitboard(Piece::Block);

// Pieces can only move to unoccupied Squares.
let allowed = !(stm | xtm | gap);

let mut single = BitBoard::EMPTY;
for piece in stm {
// All single moves to a single Square are equivalent, so a single
// BitBoard is sufficient to keep track of them all and cast out duplicates.
// An intersection with the allowed BitBoard is done once at the end.
single |= BitBoard::single(piece);
// Count the number single moves in the Position.
let mut moves: usize = (stm.singles() & allowed).cardinality();

for piece in stm {
// There may be multiple jump moves to a single Square, so they need to be
// verified (& allowed) and counted into the Position total immediately.
let double = BitBoard::double(piece) & allowed;
moves += double.cardinality();
}

// Count the number single moves in the Position.
moves += (single & allowed).cardinality();

// If there are no legal moves possible on the Position and the game isn't
// over, a pass move is the only move possible to be played.
if moves == 0 {
moves += 1;
return 1;
}

moves
Expand Down

0 comments on commit 8669242

Please sign in to comment.