[bitboard] Implement a Square type; fix all the build issues after adding a mod line to lib.rs
This commit is contained in:
parent
d080ddc735
commit
ab55a7994c
4 changed files with 175 additions and 22 deletions
|
@ -1,4 +1,4 @@
|
||||||
// Eryn Wells <eryn@erynwells.me>
|
// Eryn Wells <eryn@erynwells.me>
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct BitBoard(u64);
|
pub struct BitBoard(pub u64);
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
#[cfg(test)]
|
mod bitboard;
|
||||||
mod tests {
|
mod position;
|
||||||
use super::*;
|
mod square;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
let result = add(2, 2);
|
|
||||||
assert_eq!(result, 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
// Eryn Wells <eryn@erynwells.me>
|
// Eryn Wells <eryn@erynwells.me>
|
||||||
|
|
||||||
|
use crate::bitboard::BitBoard;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
mod color {
|
mod color {
|
||||||
const WHITE = 0;
|
const WHITE: u8 = 0;
|
||||||
const BLACK = 1;
|
const BLACK: u8 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod piece {
|
mod piece {
|
||||||
const PAWN = 0;
|
const PAWN: u8 = 0;
|
||||||
const KNIGHT = 1;
|
const KNIGHT: u8 = 1;
|
||||||
const BISHOP = 2;
|
const BISHOP: u8 = 2;
|
||||||
const ROOK = 3;
|
const ROOK: u8 = 3;
|
||||||
const QUEEN = 4;
|
const QUEEN: u8 = 4;
|
||||||
const KING = 5;
|
const KING: u8 = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
|
@ -24,10 +27,64 @@ pub struct Position {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
static fn empty() -> Position {
|
fn empty() -> Position {
|
||||||
Position {
|
Position {
|
||||||
pieces_per_color = [],
|
pieces_per_color: [BitBoard(0), BitBoard(0)],
|
||||||
pieces_per_type = [],
|
pieces_per_type: [
|
||||||
|
[
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
BitBoard(0),
|
||||||
|
],
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a starting position.
|
||||||
|
fn starting() -> Position {
|
||||||
|
let white_pieces = [
|
||||||
|
BitBoard(0x00FF000000000000),
|
||||||
|
BitBoard(0x4200000000000000),
|
||||||
|
BitBoard(0x2400000000000000),
|
||||||
|
BitBoard(0x8100000000000000),
|
||||||
|
BitBoard(0x1000000000000000),
|
||||||
|
BitBoard(0x8000000000000000),
|
||||||
|
];
|
||||||
|
|
||||||
|
let black_pieces = [
|
||||||
|
BitBoard(0xFF00),
|
||||||
|
BitBoard(0x0042),
|
||||||
|
BitBoard(0x0024),
|
||||||
|
BitBoard(0x0081),
|
||||||
|
BitBoard(0x0010),
|
||||||
|
BitBoard(0x0080),
|
||||||
|
];
|
||||||
|
|
||||||
|
Position {
|
||||||
|
pieces_per_color: [
|
||||||
|
BitBoard(white_pieces.iter().map(|bb| bb.0).fold(0, |a, b| a | b)),
|
||||||
|
BitBoard(black_pieces.iter().map(|bb| bb.0).fold(0, |a, b| a | b)),
|
||||||
|
],
|
||||||
|
pieces_per_type: [white_pieces, black_pieces],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn piece_at_square(&self, sq: &str) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Position {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "abcdefg")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
103
bitboard/src/square.rs
Normal file
103
bitboard/src/square.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// Eryn Wells <eryn@erynwells.me>
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ParseSquareError;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SquareIndexOutOfBoundsError;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
struct Square {
|
||||||
|
rank: u8,
|
||||||
|
file: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Square {
|
||||||
|
fn from_index(index: u8) -> Result<Square, SquareIndexOutOfBoundsError> {
|
||||||
|
if index >= 64 {
|
||||||
|
return Err(SquareIndexOutOfBoundsError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Square {
|
||||||
|
rank: index / 8,
|
||||||
|
file: index % 8,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_algebraic_string(s: &str) -> Result<Square, ParseSquareError> {
|
||||||
|
s.parse()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rank_index(&self) -> usize {
|
||||||
|
self.rank.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_index(&self) -> usize {
|
||||||
|
self.file.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Square {
|
||||||
|
type Err = ParseSquareError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
if !s.is_ascii() || s.len() != 2 {
|
||||||
|
return Err(ParseSquareError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let chars: Vec<char> = s.chars().collect();
|
||||||
|
let rank_char = chars[0].to_ascii_lowercase();
|
||||||
|
if !rank_char.is_ascii_lowercase() {
|
||||||
|
return Err(ParseSquareError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rank = (rank_char as u8) - ('a' as u8) + 1;
|
||||||
|
if rank < 1 || rank > 8 {
|
||||||
|
return Err(ParseSquareError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = u8::try_from(chars[1].to_digit(10).ok_or(ParseSquareError)?)
|
||||||
|
.map_err(|_| ParseSquareError)?;
|
||||||
|
|
||||||
|
Ok(Square {
|
||||||
|
rank: rank - 1,
|
||||||
|
file: file - 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn indexes() {
|
||||||
|
let sq1 = Square::from_algebraic_string("c5").expect("Failed to parse 'c5' square");
|
||||||
|
assert_eq!(sq1.rank_index(), 2, "Rank doesn't match");
|
||||||
|
assert_eq!(sq1.file_index(), 4, "File doesn't match");
|
||||||
|
|
||||||
|
let sq2 = Square::from_algebraic_string("b2").expect("Failed to parse 'b2' square");
|
||||||
|
assert_eq!(sq2.rank_index(), 1, "Rank doesn't match");
|
||||||
|
assert_eq!(sq2.file_index(), 1, "File doesn't match");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_good_input() {
|
||||||
|
let sq1 = Square::from_algebraic_string("a4").expect("Failed to parse 'a4' square");
|
||||||
|
assert_eq!(sq1.rank, 0);
|
||||||
|
assert_eq!(sq1.file, 3);
|
||||||
|
|
||||||
|
let sq2 = Square::from_algebraic_string("B8").expect("Failed to parse 'B8' square");
|
||||||
|
assert_eq!(sq2.rank, 1);
|
||||||
|
assert_eq!(sq2.file, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_index() {
|
||||||
|
let sq1 = Square::from_index(4).expect("Unable to get Square from index");
|
||||||
|
assert_eq!(sq1.rank, 0);
|
||||||
|
assert_eq!(sq1.file, 4);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue