|  | @@ -6,7 +6,15 @@ pub struct Game
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |      pub pieces: [Bitboard; 12],
 | 
	
		
			
				|  |  |      pub turn: Side,
 | 
	
		
			
				|  |  | -    pub en_passant: u8,
 | 
	
		
			
				|  |  | +    pub en_passant: Option<u8>,
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    ///
 | 
	
		
			
				|  |  | +    /// castling rights in the following order
 | 
	
		
			
				|  |  | +    /// white kingside, white queenside, black kingside, black queenside
 | 
	
		
			
				|  |  | +    /// 
 | 
	
		
			
				|  |  | +    pub castling_rights: [bool; 4],
 | 
	
		
			
				|  |  | +    pub halfmoves_since_last_event: i32,
 | 
	
		
			
				|  |  | +    pub turn_number: i32,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  impl Default for Game {
 | 
	
	
		
			
				|  | @@ -27,61 +35,85 @@ impl Default for Game {
 | 
	
		
			
				|  |  |                  0x08 << 56,
 | 
	
		
			
				|  |  |              ],
 | 
	
		
			
				|  |  |              turn: WHITE,
 | 
	
		
			
				|  |  | -            en_passant: 0,
 | 
	
		
			
				|  |  | +            en_passant: None,
 | 
	
		
			
				|  |  | +            castling_rights: [true, true, true, true],
 | 
	
		
			
				|  |  | +            halfmoves_since_last_event: 0,
 | 
	
		
			
				|  |  | +            turn_number: 0
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  impl Game {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    pub fn from_fen(fen: &str) -> Option<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 {
 | 
	
		
			
				|  |  | +        let position = fen[0];
 | 
	
		
			
				|  |  | +        let turn = fen[1];
 | 
	
		
			
				|  |  | +        let castling_rights = fen[2];
 | 
	
		
			
				|  |  | +        let en_passant = fen[3];
 | 
	
		
			
				|  |  | +        let halfmoves_since_last_event = fen[4];
 | 
	
		
			
				|  |  | +        let turn_number = fen[5];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            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 mut col_index = 0;
 | 
	
		
			
				|  |  | -                    for c in row.chars() {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                        if col_index >= 8 {
 | 
	
		
			
				|  |  | -                            return None;
 | 
	
		
			
				|  |  | +                    let bit_to_set = from_indices(col_index, row_index);
 | 
	
		
			
				|  |  | +                    match c {
 | 
	
		
			
				|  |  | +                        'p' => { *game.pawns_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | +                        'n' => { *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 },
 | 
	
		
			
				|  |  | +                        'N' => { *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;
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                        let bit_to_set = from_indices(col_index, row_index);
 | 
	
		
			
				|  |  | -                        match c {
 | 
	
		
			
				|  |  | -                            'p' => { *game.pawns_mut(BLACK) |= bit_to_set },
 | 
	
		
			
				|  |  | -                            'n' => { *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 },
 | 
	
		
			
				|  |  | -                            'N' => { *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;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | +                    col_index += 1;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | -            None => return None
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        None
 | 
	
		
			
				|  |  | +        // parse castling rights
 | 
	
		
			
				|  |  | +        game.castling_rights[0] = castling_rights.contains('K');
 | 
	
		
			
				|  |  | +        game.castling_rights[1] = castling_rights.contains('Q');
 | 
	
		
			
				|  |  | +        game.castling_rights[2] = castling_rights.contains('k');
 | 
	
		
			
				|  |  | +        game.castling_rights[3] = castling_rights.contains('q');
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // parse castling rights
 | 
	
		
			
				|  |  | +        game.en_passant = en_passant.parse::<u8>().ok();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        game.halfmoves_since_last_event = halfmoves_since_last_event.parse::<i32>().unwrap_or(0);
 | 
	
		
			
				|  |  | +        game.turn_number = turn_number.parse::<i32>().unwrap_or(0);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        Some(game)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    pub fn from_fen_str(fen: &str) -> Option<Game> {
 | 
	
		
			
				|  |  | +        let mut fen_parts = fen.split_whitespace();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Self::from_fen(fen_parts.collect::<Vec<&str>>().as_slice())
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      pub fn parse_move(&self, mov: &str) -> Result<Move, ()> {
 |