pub use crate::Chess;
pub use crate::position::Atomic;
pub use crate::position::Giveaway;
pub use crate::position::KingOfTheHill;
pub use crate::position::ThreeCheck;
pub use crate::position::Crazyhouse;
pub use crate::position::RacingKings;
pub use crate::position::Horde;
use crate::{Board, Color, Bitboard, Square, Material, RemainingChecks};
use crate::{Role, Move, MoveList, CastlingSide, Outcome, Castles};
use crate::{Setup, FromSetup, Position, PositionError};
use crate::setup::SwapTurn;
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub enum Variant {
Chess,
Atomic,
Giveaway,
KingOfTheHill,
ThreeCheck,
Crazyhouse,
RacingKings,
Horde,
}
#[derive(Debug, Clone)]
pub enum VariantPosition {
Chess(Chess),
Atomic(Atomic),
Giveaway(Giveaway),
KingOfTheHill(KingOfTheHill),
ThreeCheck(ThreeCheck),
Crazyhouse(Crazyhouse),
RacingKings(RacingKings),
Horde(Horde),
}
impl From<Chess> for VariantPosition {
fn from(pos: Chess) -> VariantPosition {
VariantPosition::Chess(pos)
}
}
impl From<Atomic> for VariantPosition {
fn from(pos: Atomic) -> VariantPosition {
VariantPosition::Atomic(pos)
}
}
impl From<Giveaway> for VariantPosition {
fn from(pos: Giveaway) -> VariantPosition {
VariantPosition::Giveaway(pos)
}
}
impl From<KingOfTheHill> for VariantPosition {
fn from(pos: KingOfTheHill) -> VariantPosition {
VariantPosition::KingOfTheHill(pos)
}
}
impl From<ThreeCheck> for VariantPosition {
fn from(pos: ThreeCheck) -> VariantPosition {
VariantPosition::ThreeCheck(pos)
}
}
impl From<Crazyhouse> for VariantPosition {
fn from(pos: Crazyhouse) -> VariantPosition {
VariantPosition::Crazyhouse(pos)
}
}
impl From<RacingKings> for VariantPosition {
fn from(pos: RacingKings) -> VariantPosition {
VariantPosition::RacingKings(pos)
}
}
impl From<Horde> for VariantPosition {
fn from(pos: Horde) -> VariantPosition {
VariantPosition::Horde(pos)
}
}
impl VariantPosition {
pub fn new(variant: Variant) -> VariantPosition {
match variant {
Variant::Chess => Chess::default().into(),
Variant::Atomic => Atomic::default().into(),
Variant::Giveaway => Giveaway::default().into(),
Variant::KingOfTheHill => KingOfTheHill::default().into(),
Variant::ThreeCheck => ThreeCheck::default().into(),
Variant::Crazyhouse => Crazyhouse::default().into(),
Variant::RacingKings => RacingKings::default().into(),
Variant::Horde => Horde::default().into(),
}
}
pub fn from_setup(variant: Variant, setup: &dyn Setup) -> Result<VariantPosition, PositionError> {
match variant {
Variant::Chess => Chess::from_setup(setup).map(VariantPosition::Chess),
Variant::Atomic => Atomic::from_setup(setup).map(VariantPosition::Atomic),
Variant::Giveaway => Giveaway::from_setup(setup).map(VariantPosition::Giveaway),
Variant::KingOfTheHill => KingOfTheHill::from_setup(setup).map(VariantPosition::KingOfTheHill),
Variant::ThreeCheck => ThreeCheck::from_setup(setup).map(VariantPosition::ThreeCheck),
Variant::Crazyhouse => Crazyhouse::from_setup(setup).map(VariantPosition::Crazyhouse),
Variant::RacingKings => RacingKings::from_setup(setup).map(VariantPosition::RacingKings),
Variant::Horde => Horde::from_setup(setup).map(VariantPosition::Horde),
}
}
pub fn swap_turn(self) -> Result<VariantPosition, PositionError> {
VariantPosition::from_setup(self.variant(), &SwapTurn(self))
}
pub fn variant(&self) -> Variant {
match self {
VariantPosition::Chess(_) => Variant::Chess,
VariantPosition::Atomic(_) => Variant::Atomic,
VariantPosition::Giveaway(_) => Variant::Giveaway,
VariantPosition::KingOfTheHill(_) => Variant::KingOfTheHill,
VariantPosition::ThreeCheck(_) => Variant::ThreeCheck,
VariantPosition::Crazyhouse(_) => Variant::Crazyhouse,
VariantPosition::RacingKings(_) => Variant::RacingKings,
VariantPosition::Horde(_) => Variant::Horde,
}
}
fn borrow(&self) -> &dyn Position {
match *self {
VariantPosition::Chess(ref pos) => pos,
VariantPosition::Atomic(ref pos) => pos,
VariantPosition::Giveaway(ref pos) => pos,
VariantPosition::KingOfTheHill(ref pos) => pos,
VariantPosition::ThreeCheck(ref pos) => pos,
VariantPosition::Crazyhouse(ref pos) => pos,
VariantPosition::RacingKings(ref pos) => pos,
VariantPosition::Horde(ref pos) => pos,
}
}
fn borrow_mut(&mut self) -> &mut dyn Position {
match *self {
VariantPosition::Chess(ref mut pos) => pos,
VariantPosition::Atomic(ref mut pos) => pos,
VariantPosition::Giveaway(ref mut pos) => pos,
VariantPosition::KingOfTheHill(ref mut pos) => pos,
VariantPosition::ThreeCheck(ref mut pos) => pos,
VariantPosition::Crazyhouse(ref mut pos) => pos,
VariantPosition::RacingKings(ref mut pos) => pos,
VariantPosition::Horde(ref mut pos) => pos,
}
}
}
impl Setup for VariantPosition {
fn board(&self) -> &Board { self.borrow().board() }
fn pockets(&self) -> Option<&Material> { self.borrow().pockets() }
fn turn(&self) -> Color { self.borrow().turn() }
fn castling_rights(&self) -> Bitboard { self.borrow().castling_rights() }
fn ep_square(&self) -> Option<Square> { self.borrow().ep_square() }
fn remaining_checks(&self) -> Option<&RemainingChecks> { self.borrow().remaining_checks() }
fn halfmoves(&self) -> u32 { self.borrow().halfmoves() }
fn fullmoves(&self) -> u32 { self.borrow().fullmoves() }
}
impl Position for VariantPosition {
fn legal_moves(&self, moves: &mut MoveList) { self.borrow().legal_moves(moves) }
fn san_candidates(&self, role: Role, to: Square, moves: &mut MoveList) { self.borrow().san_candidates(role, to, moves) }
fn castling_moves(&self, side: CastlingSide, moves: &mut MoveList) { self.borrow().castling_moves(side, moves) }
fn en_passant_moves(&self, moves: &mut MoveList) { self.borrow().en_passant_moves(moves) }
fn capture_moves(&self, moves: &mut MoveList) { self.borrow().capture_moves(moves) }
fn promotion_moves(&self, moves: &mut MoveList) { self.borrow().promotion_moves(moves) }
fn is_irreversible(&self, m: &Move) -> bool { self.borrow().is_irreversible(m) }
fn king_attackers(&self, square: Square, attacker: Color, occupied: Bitboard) -> Bitboard { self.borrow().king_attackers(square, attacker, occupied) }
fn castles(&self) -> &Castles { self.borrow().castles() }
fn checkers(&self) -> Bitboard { self.borrow().checkers() }
fn is_variant_end(&self) -> bool { self.borrow().is_variant_end() }
fn has_insufficient_material(&self, color: Color) -> bool { self.borrow().has_insufficient_material(color) }
fn variant_outcome(&self) -> Option<Outcome> { self.borrow().variant_outcome() }
fn play_unchecked(&mut self, m: &Move) { self.borrow_mut().play_unchecked(m) }
}