Make from_fen return Result<Board, FenError>
This commit is contained in:
58
src/fen.rs
58
src/fen.rs
@@ -2,39 +2,39 @@ use crate::board::{Board, Color, Kind, Piece};
|
||||
use crate::game::{Game, State};
|
||||
use String as FenError;
|
||||
|
||||
pub fn from_fen(fen: &str) -> Game {
|
||||
let mut board = Board::empty_board();
|
||||
pub fn from_fen(fen: &str) -> Result<Game, FenError> {
|
||||
let fen_parts: Vec<_> = fen.split_whitespace().collect();
|
||||
|
||||
piece_placement(fen_parts[0], &mut board);
|
||||
let board = piece_placement(fen_parts[0])?;
|
||||
|
||||
let side_to_move = side_to_move(fen_parts[1]);
|
||||
let side_to_move = side_to_move(fen_parts[1])?;
|
||||
|
||||
let castling_ability = castling_ability(fen_parts[2]);
|
||||
let castling_ability = castling_ability(fen_parts[2])?;
|
||||
|
||||
let en_passant_target_square: Result<u8, FenError> = en_passant_target_square(fen_parts[3]);
|
||||
let en_passant_target_square = en_passant_target_square(fen_parts[3])?;
|
||||
|
||||
let halfmove_clock = halfmove_clock(fen_parts[4]);
|
||||
let halfmove_clock = halfmove_clock(fen_parts[4])?;
|
||||
|
||||
let fullmove_counter = fullmove_counter(fen_parts[5]);
|
||||
let fullmove_counter = fullmove_counter(fen_parts[5])?;
|
||||
|
||||
Game {
|
||||
Ok(Game {
|
||||
board,
|
||||
state: State::load_state(
|
||||
side_to_move.unwrap(),
|
||||
castling_ability.unwrap(),
|
||||
en_passant_target_square.unwrap(),
|
||||
halfmove_clock.unwrap(),
|
||||
fullmove_counter.unwrap(),
|
||||
side_to_move,
|
||||
castling_ability,
|
||||
en_passant_target_square,
|
||||
halfmove_clock,
|
||||
fullmove_counter,
|
||||
),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn piece_placement(pieces: &str, board: &mut Board) {
|
||||
fn piece_placement(pieces: &str) -> Result<Board, FenError> {
|
||||
let mut board = Board::empty_board();
|
||||
let (mut file, mut rank): (u8, u8) = (0, 7);
|
||||
|
||||
for c in pieces.chars() {
|
||||
let square: u8 = rank * 8 + file;
|
||||
let square = rank * 8 + file;
|
||||
let color = if c.is_ascii_lowercase() {
|
||||
Color::Black
|
||||
} else {
|
||||
@@ -57,13 +57,18 @@ fn piece_placement(pieces: &str, board: &mut Board) {
|
||||
rank %= n.to_digit(10).unwrap_or(0) as u8;
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
_ => {
|
||||
return Err(FenError::from(
|
||||
"Error while parsing board piece state from FEN",
|
||||
))
|
||||
}
|
||||
} {
|
||||
board.set_piece(Piece::new(1 << square, kind, color));
|
||||
};
|
||||
|
||||
file += 1;
|
||||
}
|
||||
Ok(board)
|
||||
}
|
||||
|
||||
fn side_to_move(side: &str) -> Result<Color, FenError> {
|
||||
@@ -152,20 +157,25 @@ fn fullmove_counter(fullmove: &str) -> Result<u8, FenError> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const FEN_EXAMPLE: [&str; 4] = [
|
||||
const FEN_EXAMPLE: [&str; 5] = [
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||
"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
|
||||
"rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2",
|
||||
"rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2 ",
|
||||
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR x KQkq - 0 1",
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_sqrt() -> Result<(), String> {
|
||||
let game = from_fen(FEN_EXAMPLE[3]);
|
||||
println!("{}\n{}", game.board, game.state);
|
||||
|
||||
assert_eq!(from_fen(FEN_EXAMPLE[0]), Game::new());
|
||||
fn test_from_fen() -> Result<(), String> {
|
||||
let new_game = from_fen(FEN_EXAMPLE[0])?;
|
||||
assert_eq!(new_game, Game::new());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_fen_error() -> () {
|
||||
from_fen(FEN_EXAMPLE[4]).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ use crate::{
|
||||
board::{Board, Color},
|
||||
fen::from_fen,
|
||||
};
|
||||
use String as FenError;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Game {
|
||||
@@ -17,7 +18,7 @@ impl Game {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_fen(fen: &str) -> Game {
|
||||
pub fn new_from_fen(fen: &str) -> Result<Game, FenError> {
|
||||
from_fen(fen)
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ impl fmt::Display for State {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f,
|
||||
"side_to_move: {:?}\ncastling_ability: {:b}\nen_passant_target_square: {:b}\nhalfmove_clock: {}\nfullmove_counter: {}\n",
|
||||
self.side_to_move, self.castling_ability, 1u64 << self.en_passant_target_square, self.halfmove_clock, self.fullmove_counter)
|
||||
self.side_to_move, self.castling_ability, 1_u64 << self.en_passant_target_square, self.halfmove_clock, self.fullmove_counter)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user