use crate::bitboard::{
Bitboard, FILE_BB, bishop_effect, dragon_effect, gold_effect, horse_effect, king_effect,
knight_effect, lance_effect, pawn_effect, rook_effect, silver_effect,
};
use crate::mate::tables::check_around_bb;
use crate::position::Position;
use crate::types::{Color, PieceType, Square};
use super::aligned;
pub fn attacks_slider(pos: &Position, us: Color) -> Bitboard {
let occ = pos.occupied();
let mut sum = Bitboard::EMPTY;
for from in pos.pieces(us, PieceType::Lance).iter() {
sum |= lance_effect(us, from, occ);
}
for from in pos.pieces(us, PieceType::Bishop).iter() {
sum |= bishop_effect(from, occ);
}
for from in pos.pieces(us, PieceType::Horse).iter() {
sum |= horse_effect(from, occ);
}
for from in pos.pieces(us, PieceType::Rook).iter() {
sum |= rook_effect(from, occ);
}
for from in pos.pieces(us, PieceType::Dragon).iter() {
sum |= dragon_effect(from, occ);
}
sum
}
pub fn attacks_slider_avoiding(
pos: &Position,
us: Color,
avoid_from: Square,
occ: Bitboard,
) -> Bitboard {
let avoid = !Bitboard::from_square(avoid_from);
let mut sum = Bitboard::EMPTY;
for from in (pos.pieces(us, PieceType::Lance) & avoid).iter() {
sum |= lance_effect(us, from, occ);
}
for from in
((pos.pieces(us, PieceType::Bishop) | pos.pieces(us, PieceType::Horse)) & avoid).iter()
{
sum |= bishop_effect(from, occ);
}
for from in
((pos.pieces(us, PieceType::Rook) | pos.pieces(us, PieceType::Dragon)) & avoid).iter()
{
sum |= rook_effect(from, occ);
}
sum
}
pub fn attacks_around_king_non_slider(pos: &Position, our_king: Color) -> Bitboard {
let them = !our_king;
let sq_king = pos.king_square(our_king);
let mut sum = Bitboard::EMPTY;
for from in pos.pieces(them, PieceType::Pawn).iter() {
sum |= pawn_effect(them, from);
}
let knights =
pos.pieces(them, PieceType::Knight) & check_around_bb(them, PieceType::Knight, sq_king);
for from in knights.iter() {
sum |= knight_effect(them, from);
}
let silvers =
pos.pieces(them, PieceType::Silver) & check_around_bb(them, PieceType::Silver, sq_king);
for from in silvers.iter() {
sum |= silver_effect(them, from);
}
let gold_like = (pos.pieces(them, PieceType::Gold)
| pos.pieces(them, PieceType::ProPawn)
| pos.pieces(them, PieceType::ProLance)
| pos.pieces(them, PieceType::ProKnight)
| pos.pieces(them, PieceType::ProSilver))
& check_around_bb(them, PieceType::Gold, sq_king);
for from in gold_like.iter() {
sum |= gold_effect(them, from);
}
let hdk = (pos.pieces(them, PieceType::King)
| pos.pieces(them, PieceType::Horse)
| pos.pieces(them, PieceType::Dragon))
& check_around_bb(them, PieceType::King, sq_king);
for from in hdk.iter() {
sum |= king_effect(from);
}
sum
}
pub fn attacks_around_king_slider(pos: &Position, our_king: Color) -> Bitboard {
let them = !our_king;
let sq_king = pos.king_square(our_king);
let occ = pos.occupied();
let mut sum = Bitboard::EMPTY;
let lances =
pos.pieces(them, PieceType::Lance) & check_around_bb(them, PieceType::Lance, sq_king);
for from in lances.iter() {
sum |= lance_effect(them, from, occ);
}
let bishops = (pos.pieces(them, PieceType::Bishop) | pos.pieces(them, PieceType::Horse))
& check_around_bb(them, PieceType::Bishop, sq_king);
for from in bishops.iter() {
sum |= bishop_effect(from, occ);
}
let rooks = (pos.pieces(them, PieceType::Rook) | pos.pieces(them, PieceType::Dragon))
& check_around_bb(them, PieceType::Rook, sq_king);
for from in rooks.iter() {
sum |= rook_effect(from, occ);
}
sum
}
pub fn attacks_around_king_in_avoiding(
pos: &Position,
us: Color,
from: Square,
occ: Bitboard,
) -> Bitboard {
let them = !us;
attacks_around_king_non_slider_in_avoiding(pos, them, us, from)
| attacks_slider_avoiding(pos, them, from, occ)
}
pub fn can_king_escape(
pos: &Position,
us: Color,
to: Square,
bb_avoid: Bitboard,
slide: Bitboard,
) -> bool {
let king_sq = pos.king_square(us);
let slide = slide | Bitboard::from_square(to);
let escape = king_effect(king_sq) & !(bb_avoid | pos.pieces_c(us));
for dest in escape.iter() {
let attacked = pos.attackers_to_occ(dest, slide) & pos.pieces_c(!us);
if attacked.is_empty() {
return true;
}
}
false
}
pub fn can_king_escape_with_from(
pos: &Position,
us: Color,
from: Square,
to: Square,
bb_avoid: Bitboard,
slide: Bitboard,
) -> bool {
let king_sq = pos.king_square(us);
let slide = (slide | Bitboard::from_square(to)) & !Bitboard::from_square(king_sq);
let our_pieces = pos.pieces_c(us) & !Bitboard::from_square(to);
let escape = king_effect(king_sq) & !(bb_avoid | our_pieces);
for dest in escape.iter() {
let attacked = pos.attackers_to_occ(dest, slide) & pos.pieces_c(!us);
let attacked_wo_from = attacked & !Bitboard::from_square(from);
if attacked_wo_from.is_empty() {
return true;
}
}
false
}
pub fn can_piece_capture(
pos: &Position,
us: Color,
to: Square,
pinned: Bitboard,
slide: Bitboard,
) -> bool {
let king_sq = pos.king_square(us);
let mut attackers = pos.attackers_to_occ(to, slide) & pos.pieces_c(us);
attackers &= !Bitboard::from_square(king_sq);
for from in attackers.iter() {
if pinned.contains(from) && !aligned(from, to, king_sq) {
continue;
}
return true;
}
false
}
pub fn can_piece_capture_avoiding(
pos: &Position,
us: Color,
to: Square,
avoid: Square,
pinned: Bitboard,
slide: Bitboard,
) -> bool {
let king_sq = pos.king_square(us);
let avoid_bb = Bitboard::from_square(avoid);
let mut attackers = pos.attackers_to_occ(to, slide) & pos.pieces_c(us);
attackers &= !avoid_bb;
attackers &= !Bitboard::from_square(king_sq);
for from in attackers.iter() {
if pinned.contains(from) && !aligned(from, to, king_sq) {
continue;
}
return true;
}
false
}
pub fn can_pawn_drop(pos: &Position, us: Color, sq: Square) -> bool {
if !pos.hand(us).has(PieceType::Pawn) {
return false;
}
let file_bb = FILE_BB[sq.file().index()];
if !(pos.pieces(us, PieceType::Pawn) & file_bb).is_empty() {
return false;
}
true
}
fn attacks_around_king_non_slider_in_avoiding(
pos: &Position,
them: Color,
our_king: Color,
avoid: Square,
) -> Bitboard {
let sq_king = pos.king_square(our_king);
let mut sum = Bitboard::EMPTY;
let avoid_bb = !Bitboard::from_square(avoid);
for from in pos.pieces(them, PieceType::Pawn).iter() {
sum |= pawn_effect(them, from);
}
let knights = (pos.pieces(them, PieceType::Knight)
& check_around_bb(them, PieceType::Knight, sq_king))
& avoid_bb;
for from in knights.iter() {
sum |= knight_effect(them, from);
}
let silvers = (pos.pieces(them, PieceType::Silver)
& check_around_bb(them, PieceType::Silver, sq_king))
& avoid_bb;
for from in silvers.iter() {
sum |= silver_effect(them, from);
}
let gold_like = (pos.pieces(them, PieceType::Gold)
| pos.pieces(them, PieceType::ProPawn)
| pos.pieces(them, PieceType::ProLance)
| pos.pieces(them, PieceType::ProKnight)
| pos.pieces(them, PieceType::ProSilver))
& check_around_bb(them, PieceType::Gold, sq_king)
& avoid_bb;
for from in gold_like.iter() {
sum |= gold_effect(them, from);
}
let hdk = (pos.pieces(them, PieceType::King)
| pos.pieces(them, PieceType::Horse)
| pos.pieces(them, PieceType::Dragon))
& check_around_bb(them, PieceType::King, sq_king)
& avoid_bb;
for from in hdk.iter() {
sum |= king_effect(from);
}
sum
}
#[cfg(test)]
mod tests {
#[test]
fn test_helper_functions_compile() {
}
}