1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
#[macro_use] extern crate lazy_static; extern crate itertools; extern crate myopic_core; extern crate regex; mod implementation; pub mod parse; use myopic_core::bitboard::BitBoard; use myopic_core::castlezone::CastleZone; use myopic_core::castlezone::CastleZoneSet; use myopic_core::pieces::Piece; use myopic_core::reflectable::Reflectable; use myopic_core::Side; use myopic_core::Square; pub use implementation::MutBoardImpl; const START_FEN: &'static str = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; #[derive(Debug, Clone, PartialEq)] pub struct Discards { pub rights: CastleZoneSet, pub piece: Option<Piece>, pub enpassant: Option<Square>, pub hash: u64, pub half_move_clock: usize, } #[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub enum Move { Standard(Piece, Square, Square), Enpassant(Square, Square), Promotion(Square, Square, Piece), Castle(CastleZone), } #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub enum MoveComputeType { All, Attacks, /// If a promoting move causes check then all promoting moves for /// the four different target pieces will be included for that pawn. AttacksChecks, } /// Represents the possible ways a game can be terminated, we only /// consider a game to be terminated when a side has no legal moves /// to make or if a special draw condition is met like position /// repetition. If a side has no legal moves and is currently in check /// then the game is lost, if it is not in check then the game is /// drawn. #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub enum Termination { Draw, Loss, } /// Trait representing a mutable state of play of a chess game /// which can be evolved/devolved via (applicable) Move instances, /// compute the set of legal moves and queried for a variety of /// properties. pub trait MutBoard: Clone + Send + Reflectable { /// Evolves this board in place according to the given move reference. /// The move must be one that is legal in this position otherwise the /// results are undefined. The data which is lost during this evolution /// is returned at the end of the procedure allowing for devolution to /// take place. fn evolve(&mut self, action: &Move) -> Discards; /// Reverses the given move, i.e. it devolves the board. It can only be /// called after the same move has been used to evolve the board. The /// discarded information produced by the evolve call must be provided /// here. If any of these conditions are not met the results of this /// procedure are undefined. fn devolve(&mut self, action: &Move, discards: Discards); /// Compute a vector of all the legal moves in this position for the /// given computation type. Note there is no particular ordering to the /// move vector. fn compute_moves(&mut self, computation_type: MoveComputeType) -> Vec<Move>; /// Compute the termination state of this node. If it is not terminal /// nothing is returned, if it is then the manner of termination is /// returned wrapped inside an Option. The termination can be only a /// draw or a loss since a side only loses when it runs out of moves, /// i.e. you don't play a winning move, you just fail to have a legal /// move. fn termination_status(&mut self) -> Option<Termination>; /// Determines whether the active side is in a state of check. fn in_check(&mut self) -> bool; /// Return the locations of all pieces on the given side. fn side(&self, side: Side) -> BitBoard; /// Return the locations of all white and black pieces. fn sides(&self) -> (BitBoard, BitBoard); /// Returns the Zobrist hash of this position. fn hash(&self) -> u64; /// Return the active side in this position, i.e. the one whose turn it is. fn active(&self) -> Side; /// Return the enpassant target square in this position. fn enpassant(&self) -> Option<Square>; /// Return the castling status of the given side. fn castle_status(&self, side: Side) -> Option<CastleZone>; /// Return the locations of the given piece. fn locs(&self, piece: Piece) -> BitBoard; /// Return the location of the king for the given side. fn king(&self, side: Side) -> Square; /// Return the piece occupying the given location. fn piece(&self, location: Square) -> Option<Piece>; /// Return the half move clock value at this position. fn half_move_clock(&self) -> usize; /// Return the total number of half moves played to reach this position. fn history_count(&self) -> usize; /// Returns the locations of a set of pieces as a single bitboard. fn locs_n(&self, pieces: &[Piece]) -> BitBoard { pieces.into_iter().map(|&p| self.locs(p)).collect() } /// Returns the locations of all pieces on the board. fn all_pieces(&self) -> BitBoard { let (w, b) = self.sides(); w | b } } /// Create a mutable board state from a fen string if it is valid. pub fn fen_position(fen: &str) -> Result<MutBoardImpl, String> { MutBoardImpl::from_fen(String::from(fen)) } /// Create a mutable board state representing the start of a standard /// chess game. pub fn start_position() -> MutBoardImpl { fen_position(START_FEN).unwrap() }