Make from_fen return Result<Board, FenError>

This commit is contained in:
2024-05-29 20:39:38 +03:00
parent 9876fc0465
commit b471aaf109
2 changed files with 37 additions and 26 deletions

View File

@@ -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();
}
}

View File

@@ -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)
}
}