use crate::*;
crate::helpers::simple_enum! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Rank {
A,
B,
C,
D,
E,
F,
G,
H,
I
}
}
crate::helpers::enum_char_conv! {
Rank, RankParseError {
A = 'a',
B = 'b',
C = 'c',
D = 'd',
E = 'e',
F = 'f',
G = 'g',
H = 'h',
I = 'i'
}
}
const MASK: u128 = 0x1008040201008040201;
const RANK_A: BitBoard = BitBoard(MASK);
const RANK_B: BitBoard = BitBoard(MASK << 1);
const RANK_C: BitBoard = BitBoard(MASK << 2);
const RANK_D: BitBoard = BitBoard(MASK << 3);
const RANK_E: BitBoard = BitBoard(MASK << 4);
const RANK_F: BitBoard = BitBoard(MASK << 5);
const RANK_G: BitBoard = BitBoard(MASK << 6);
const RANK_H: BitBoard = BitBoard(MASK << 7);
const RANK_I: BitBoard = BitBoard(MASK << 8);
const NORTH_A: BitBoard = BitBoard::EMPTY;
const NORTH_B: BitBoard = RANK_A;
const NORTH_C: BitBoard = NORTH_B.bitor(RANK_B);
const NORTH_D: BitBoard = NORTH_C.bitor(RANK_C);
const NORTH_E: BitBoard = NORTH_D.bitor(RANK_D);
const NORTH_F: BitBoard = NORTH_E.bitor(RANK_E);
const NORTH_G: BitBoard = NORTH_F.bitor(RANK_F);
const NORTH_H: BitBoard = NORTH_G.bitor(RANK_G);
const NORTH_I: BitBoard = NORTH_H.bitor(RANK_H);
const SOUTH_I: BitBoard = BitBoard::EMPTY;
const SOUTH_H: BitBoard = RANK_I;
const SOUTH_G: BitBoard = SOUTH_H.bitor(RANK_H);
const SOUTH_F: BitBoard = SOUTH_G.bitor(RANK_G);
const SOUTH_E: BitBoard = SOUTH_F.bitor(RANK_F);
const SOUTH_D: BitBoard = SOUTH_E.bitor(RANK_E);
const SOUTH_C: BitBoard = SOUTH_D.bitor(RANK_D);
const SOUTH_B: BitBoard = SOUTH_C.bitor(RANK_C);
const SOUTH_A: BitBoard = SOUTH_B.bitor(RANK_B);
#[inline(always)]
pub const fn no_fly_zone(color: Color, piece: Piece) -> BitBoard {
match piece {
Piece::Pawn | Piece::Lance => {
if color as usize == Color::White as usize {
RANK_I
} else {
RANK_A
}
}
Piece::Knight => {
if color as usize == Color::White as usize {
RANK_I.bitor(RANK_H)
} else {
RANK_A.bitor(RANK_B)
}
}
_ => BitBoard::EMPTY,
}
}
#[inline(always)]
pub const fn drop_zone(color: Color, piece: Piece) -> BitBoard {
match piece {
Piece::Pawn | Piece::Lance => {
if color as usize == Color::White as usize {
NORTH_I
} else {
SOUTH_A
}
}
Piece::Knight => {
if color as usize == Color::White as usize {
NORTH_H
} else {
SOUTH_B
}
}
_ => BitBoard::FULL,
}
}
#[inline(always)]
pub const fn prom_zone(color: Color) -> BitBoard {
match color {
Color::White => SOUTH_F,
Color::Black => NORTH_D,
}
}
#[inline(always)]
pub const fn must_prom_zone(color: Color, piece: Piece) -> BitBoard {
match piece {
Piece::Pawn | Piece::Lance => match color {
Color::White => RANK_I,
Color::Black => RANK_A,
},
Piece::Knight => match color {
Color::White => SOUTH_G,
Color::Black => NORTH_C,
},
_ => BitBoard::EMPTY,
}
}
impl Rank {
pub const RANK: [BitBoard; Self::NUM] = [
RANK_A, RANK_B, RANK_C, RANK_D, RANK_E, RANK_F, RANK_G, RANK_H, RANK_I,
];
pub const SOUTH: [BitBoard; Self::NUM] = [
SOUTH_A, SOUTH_B, SOUTH_C, SOUTH_D, SOUTH_E, SOUTH_F, SOUTH_G, SOUTH_H, SOUTH_I,
];
pub const NORTH: [BitBoard; Self::NUM] = [
NORTH_A, NORTH_B, NORTH_C, NORTH_D, NORTH_E, NORTH_F, NORTH_G, NORTH_H, NORTH_I,
];
#[inline(always)]
pub const fn bitboard(self) -> BitBoard {
Self::RANK[self as usize]
}
#[inline(always)]
pub const fn flip(self) -> Self {
Self::index_const(Self::I as usize - self as usize)
}
#[inline(always)]
pub const fn north(self) -> BitBoard {
Self::NORTH[self as usize]
}
#[inline(always)]
pub const fn south(self) -> BitBoard {
Self::SOUTH[self as usize]
}
#[inline(always)]
pub const fn relative_to(self, color: Color) -> Self {
match color {
Color::White => self,
Color::Black => self.flip(),
}
}
}