use crate::piece::*;
use crate::Board;
use std::collections::HashMap;
enum Filter {
Exactly(usize),
AtLeast(usize),
AtMost(usize),
}
pub struct BoardFilter { filters: HashMap<Piece, Filter>, }
impl BoardFilter {
pub(super) fn new() -> BoardFilter {
let mut filters: HashMap<Piece, Filter> = HashMap::new();
filters.insert(Piece::WK, Filter::Exactly(1));
filters.insert(Piece::WQ, Filter::Exactly(0));
filters.insert(Piece::WR, Filter::Exactly(0));
filters.insert(Piece::WB, Filter::Exactly(0));
filters.insert(Piece::WN, Filter::Exactly(0));
filters.insert(Piece::WP, Filter::Exactly(0));
filters.insert(Piece::BK, Filter::Exactly(1));
filters.insert(Piece::BQ, Filter::Exactly(0));
filters.insert(Piece::BR, Filter::Exactly(0));
filters.insert(Piece::BB, Filter::Exactly(0));
filters.insert(Piece::BN, Filter::Exactly(0));
filters.insert(Piece::BP, Filter::Exactly(0));
BoardFilter { filters }
}
pub fn at_least(mut self, n: usize, piece: &str) -> BoardFilter {
let piece = piece_from(&piece);
if piece == Piece::NO {
panic!("Unknown piece name passed to 'at_least'");
}
let filter = self.filters.entry(piece).or_insert(Filter::Exactly(0));
*filter = Filter::AtLeast(n);
self
}
pub fn at_most(mut self, n: usize, piece: &str) -> BoardFilter {
let piece = piece_from(&piece);
if piece == Piece::NO {
panic!("Unknown piece name passed to 'at_most'");
}
let filter = self.filters.entry(piece).or_insert(Filter::Exactly(0));
*filter = Filter::AtMost(n);
self
}
pub fn exactly(mut self, n: usize, piece: &str) -> BoardFilter {
let piece = piece_from(&piece);
if piece == Piece::NO {
panic!("Unknown piece name passed to 'exactly'");
}
let filter = self.filters.entry(piece).or_insert(Filter::Exactly(0));
*filter = Filter::Exactly(n);
self
}
pub(crate) fn is_match(&self, board: &Board) -> bool {
let counts = board.piece_counts();
for (piece, count) in counts.iter() {
match self.filters[piece] {
Filter::AtLeast(n) => {
if *count < n {
return false;
}
}
Filter::AtMost(n) => {
if *count > n {
return false;
}
}
Filter::Exactly(n) => {
if *count != n {
return false;
}
}
}
}
true
}
}