|  | @@ -1,303 +1,34 @@
 | 
	
		
			
				|  |  |  use bitboard::*;
 | 
	
		
			
				|  |  |  use movegen::*;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +enum MoveUndo {
 | 
	
		
			
				|  |  | +    Default {
 | 
	
		
			
				|  |  | +        piece_type: PieceType,
 | 
	
		
			
				|  |  | +        before: Bitboard,
 | 
	
		
			
				|  |  | +        captured_type: PieceType,
 | 
	
		
			
				|  |  | +        captured_before: Bitboard,
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    Castling { rooks_before: Bitboard, king_before: Bitboard },
 | 
	
		
			
				|  |  | +    Promotion {
 | 
	
		
			
				|  |  | +        promoted_to: PieceType,
 | 
	
		
			
				|  |  | +        promoted_to_before: Bitboard,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -pub struct Game
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -    pub pieces: [Bitboard; 12],
 | 
	
		
			
				|  |  | -    en_passant: u8,
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -impl Default for Game {
 | 
	
		
			
				|  |  | -    fn default () -> Game {
 | 
	
		
			
				|  |  | -        Game {
 | 
	
		
			
				|  |  | -            pieces: [
 | 
	
		
			
				|  |  | -                ROW_2,
 | 
	
		
			
				|  |  | -                0x42,
 | 
	
		
			
				|  |  | -                0x24,
 | 
	
		
			
				|  |  | -                0x81,
 | 
	
		
			
				|  |  | -                0x10,
 | 
	
		
			
				|  |  | -                0x08,
 | 
	
		
			
				|  |  | -                ROW_7,
 | 
	
		
			
				|  |  | -                0x42 << 56,
 | 
	
		
			
				|  |  | -                0x24 << 56,
 | 
	
		
			
				|  |  | -                0x81 << 56,
 | 
	
		
			
				|  |  | -                0x10 << 56,
 | 
	
		
			
				|  |  | -                0x08 << 56,
 | 
	
		
			
				|  |  | -            ],
 | 
	
		
			
				|  |  | -            en_passant: 0,
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -impl Game {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn from_fen(fen: &str) -> Option<Game> {
 | 
	
		
			
				|  |  | -        let mut game: Game = Game::default();
 | 
	
		
			
				|  |  | -        let example = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
 | 
	
		
			
				|  |  | -        let mut fen_parts = fen.split_whitespace();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        match fen_parts.next() {
 | 
	
		
			
				|  |  | -            Some(position) => {
 | 
	
		
			
				|  |  | -                let rows = position.split('/');
 | 
	
		
			
				|  |  | -                let mut row_index = 0;
 | 
	
		
			
				|  |  | -                for row in rows {
 | 
	
		
			
				|  |  | -                    if row_index >= 8 {
 | 
	
		
			
				|  |  | -                        return None;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    let mut col_index = 0;
 | 
	
		
			
				|  |  | -                    for c in row.chars() {
 | 
	
		
			
				|  |  | -                        
 | 
	
		
			
				|  |  | -                        if col_index >= 8 {
 | 
	
		
			
				|  |  | -                            return None;
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                        let bit_to_set = single_bit_board(col_index, row_index);
 | 
	
		
			
				|  |  | -                        match c {
 | 
	
		
			
				|  |  | -                            'p' => { *game.pawns_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'k' => { *game.knights_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'b' => { *game.bishops_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'r' => { *game.rooks_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'q' => { *game.queens_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'k' => { *game.kings_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'P' => { *game.pawns_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'K' => { *game.knights_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'B' => { *game.bishops_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'R' => { *game.rooks_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'Q' => { *game.queens_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'K' => { *game.kings_mut(WHITE) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            num => {
 | 
	
		
			
				|  |  | -                                col_index += match num.to_digit(10) { Some(x) => x, None => {
 | 
	
		
			
				|  |  | -                                    return None;
 | 
	
		
			
				|  |  | -                                }} as u8 - 1;
 | 
	
		
			
				|  |  | -                            }
 | 
	
		
			
				|  |  | -                        }
 | 
	
		
			
				|  |  | -                        col_index += 1;
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | -            None => return None
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        None
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn bitboard(&self, pt: PieceType, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        if side == BLACK {
 | 
	
		
			
				|  |  | -            self.pieces[(pt + 6) as usize]
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -            self.pieces[pt as usize]
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * \return bitboard containig all occupied squares
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    pub fn occupied(&self) -> Bitboard {
 | 
	
		
			
				|  |  | -        self.pieces.into_iter().fold(0, |a, b| { a | b } )
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn pawns(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[0],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[6],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn knights(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[1],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[7],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn bishops(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[2],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[8],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn rooks(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[3],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[9],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn queens(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[4],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[10],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn kings(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[5],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[11],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn pawns_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[0],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[6],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn knights_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[1],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[7],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn bishops_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[2],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[8],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn rooks_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[3],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[9],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn queens_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[4],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[10],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn kings_mut(&mut self, side: Side) -> &mut Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => &mut self.pieces[5],
 | 
	
		
			
				|  |  | -            BLACK => &mut self.pieces[11],
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn get_all_side(&self, side: Side) -> Bitboard {
 | 
	
		
			
				|  |  | -        match side {
 | 
	
		
			
				|  |  | -            WHITE => self.pieces[0] | self.pieces[1] | self.pieces[2] | self.pieces[3] |
 | 
	
		
			
				|  |  | -                self.pieces[4] | self.pieces[5],
 | 
	
		
			
				|  |  | -            BLACK => self.pieces[6] | self.pieces[7] | self.pieces[8] | self.pieces[9] |
 | 
	
		
			
				|  |  | -                self.pieces[10] | self.pieces[11]
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    pub fn get_square(&self, square: Square) -> (PieceType, Side) {
 | 
	
		
			
				|  |  | -        let square_mask = 1 << square;
 | 
	
		
			
				|  |  | -        for i in 0..6 {
 | 
	
		
			
				|  |  | -            if self.pieces[i] & square_mask != 0 {
 | 
	
		
			
				|  |  | -                return (i as PieceType, WHITE);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if self.pieces[i + 6] & square_mask != 0 {
 | 
	
		
			
				|  |  | -                return (i as PieceType, BLACK);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        return (NO_PIECE, WHITE);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * @brief creates a unicode string containing the board
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * Example:
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     *   ┌───┬───┬───┬───┬───┬───┬───┬───┐
 | 
	
		
			
				|  |  | -     * 8 │ ♜ │ ♞ │ ♝ │ ♛ │ ♚ │ ♝ │ ♞ │ ♜ │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 7 │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │ ♟ │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 6 │   │   │   │   │   │   │   │   │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 5 │   │   │   │   │   │   │   │   │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 4 │   │   │   │   │   │   │   │   │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 3 │   │   │   │   │   │   │   │   │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 2 │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │ ♙ │
 | 
	
		
			
				|  |  | -     *   ├───┼───┼───┼───┼───┼───┼───┼───┤
 | 
	
		
			
				|  |  | -     * 1 │ ♖ │ ♘ │ ♗ │ ♕ │ ♔ │ ♗ │ ♘ │ ♖ │
 | 
	
		
			
				|  |  | -     *   └───┴───┴───┴───┴───┴───┴───┴───┘
 | 
	
		
			
				|  |  | -     *     a   b   c   d   e   f   g   h
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    pub fn beautiful_print(&self) -> String {
 | 
	
		
			
				|  |  | -        let chars = ['─', '│', '┌', '┐', '└', '┘', '├', '┤', '┬', '┴', '┼'];
 | 
	
		
			
				|  |  | -        let figures = ['♙', '♘', '♗', '♖', '♕', '♔', '♟', '♞', '♝', '♜', '♛', '♚'];
 | 
	
		
			
				|  |  | -        let mut board: String = String::new();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        #[derive(Copy, Clone)]
 | 
	
		
			
				|  |  | -        struct GridLine {
 | 
	
		
			
				|  |  | -            left: char,
 | 
	
		
			
				|  |  | -            center: char,
 | 
	
		
			
				|  |  | -            right: char,
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        let top = GridLine { left: chars[2], center: chars[8], right: chars[3] };
 | 
	
		
			
				|  |  | -        let center = GridLine { left: chars[6], center: chars[10], right: chars[7] };
 | 
	
		
			
				|  |  | -        let bot = GridLine { left: chars[4], center: chars[9], right: chars[5] };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        let generate_line = |gl: GridLine| {
 | 
	
		
			
				|  |  | -            let mut line = String::new();
 | 
	
		
			
				|  |  | -            for i in 0..33 {
 | 
	
		
			
				|  |  | -                match i {
 | 
	
		
			
				|  |  | -                    0 => { line.push(gl.left) }
 | 
	
		
			
				|  |  | -                    32 => { line.push(gl.right) }
 | 
	
		
			
				|  |  | -                    x => { line.push(if x % 4 == 0 { gl.center } else { chars[0] }) }
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return line;
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        let piece_line = |row: u8| {
 | 
	
		
			
				|  |  | -            let mut line = String::new();
 | 
	
		
			
				|  |  | -            line.push(chars[1]);
 | 
	
		
			
				|  |  | -            line.push(' ');
 | 
	
		
			
				|  |  | -            for i in 0..8 {
 | 
	
		
			
				|  |  | -                let (pt, side) = self.get_square(square_from_indices(i, row));
 | 
	
		
			
				|  |  | -                if pt == NO_PIECE {
 | 
	
		
			
				|  |  | -                    line.push(' ');
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                else {
 | 
	
		
			
				|  |  | -                    let fig_index = pt as usize + if side == BLACK { 6 } else { 0 };
 | 
	
		
			
				|  |  | -                    line.push(figures[fig_index]);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -                line.push(' '); line.push(chars[1]); line.push(' ');
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return line;
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        board.push_str("  ");
 | 
	
		
			
				|  |  | -        board.push_str(&generate_line(top));
 | 
	
		
			
				|  |  | -        board.push('\n');
 | 
	
		
			
				|  |  | -        for i in 0..8 {
 | 
	
		
			
				|  |  | -            board.push_str(&(8 - i).to_string());
 | 
	
		
			
				|  |  | -            board.push(' ');
 | 
	
		
			
				|  |  | -            board.push_str(&piece_line(i));
 | 
	
		
			
				|  |  | -            board.push('\n');
 | 
	
		
			
				|  |  | -            if i != 7 {
 | 
	
		
			
				|  |  | -                board.push_str("  ");
 | 
	
		
			
				|  |  | -                board.push_str(&generate_line(center));
 | 
	
		
			
				|  |  | -                board.push('\n');
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        board.push_str("  ");
 | 
	
		
			
				|  |  | -        board.push_str(&generate_line(bot));
 | 
	
		
			
				|  |  | -        board.push_str("\n    a   b   c   d   e   f   g   h");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        return board;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +//01 function negamax(node, depth, color)
 | 
	
		
			
				|  |  | +//02     if depth = 0 or node is a terminal node
 | 
	
		
			
				|  |  | +//03         return color * the heuristic value of node
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//04     bestValue := −∞
 | 
	
		
			
				|  |  | +//05     foreach child of node
 | 
	
		
			
				|  |  | +//06         v := −negamax(child, depth − 1, −color)
 | 
	
		
			
				|  |  | +//07         bestValue := max( bestValue, v )
 | 
	
		
			
				|  |  | +//08     return bestValue
 | 
	
		
			
				|  |  |  pub fn search() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/*fn negamax(game: &Game, depth: i32) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +}*/
 |