Created
June 20, 2021 16:43
-
-
Save neofight78/6632465a693000422e9491999bec4eba to your computer and use it in GitHub Desktop.
Simple FEN Parser v1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fmt::{Display, Formatter}; | |
use std::{env, fmt, process}; | |
#[derive(Debug, Copy, Clone)] | |
enum Pieces { | |
None, | |
WPawn, | |
WKnight, | |
WBishop, | |
WRook, | |
WQueen, | |
WKing, | |
BPawn, | |
BKnight, | |
BBishop, | |
BRook, | |
BQueen, | |
BKing, | |
} | |
struct Position { | |
board: [[Pieces; 8]; 8], | |
} | |
impl Display for Position { | |
fn fmt(&self, f: &mut Formatter) -> fmt::Result { | |
for rank in (0..8).rev() { | |
for file in 0..8 { | |
write!( | |
f, | |
"{}", | |
match self.board[file][rank] { | |
Pieces::None => '.', | |
Pieces::WPawn => 'P', | |
Pieces::WKnight => 'N', | |
Pieces::WBishop => 'B', | |
Pieces::WRook => 'R', | |
Pieces::WQueen => 'Q', | |
Pieces::WKing => 'K', | |
Pieces::BPawn => 'p', | |
Pieces::BKnight => 'n', | |
Pieces::BBishop => 'b', | |
Pieces::BRook => 'r', | |
Pieces::BQueen => 'q', | |
Pieces::BKing => 'k', | |
} | |
)?; | |
} | |
writeln!(f)?; | |
} | |
Ok(()) | |
} | |
} | |
impl Position { | |
fn from_fen(fen: &str) -> Result<Position, &str> { | |
let parts = fen.split(' ').collect::<Vec<&str>>(); | |
if parts.len() != 6 { | |
return Err("Invalid FEN format. There should be six fields."); | |
} | |
let mut position = Position { | |
board: [[Pieces::None; 8]; 8], | |
}; | |
let mut file = 0; | |
let mut rank = 7; | |
for c in parts[0].chars() { | |
match c { | |
'P' if file < 8 => { | |
position.board[file][rank] = Pieces::WPawn; | |
file += 1; | |
} | |
'N' if file < 8 => { | |
position.board[file][rank] = Pieces::WKnight; | |
file += 1; | |
} | |
'B' if file < 8 => { | |
position.board[file][rank] = Pieces::WBishop; | |
file += 1; | |
} | |
'R' if file < 8 => { | |
position.board[file][rank] = Pieces::WRook; | |
file += 1; | |
} | |
'Q' if file < 8 => { | |
position.board[file][rank] = Pieces::WQueen; | |
file += 1; | |
} | |
'K' if file < 8 => { | |
position.board[file][rank] = Pieces::WKing; | |
file += 1; | |
} | |
'p' if file < 8 => { | |
position.board[file][rank] = Pieces::BPawn; | |
file += 1; | |
} | |
'n' if file < 8 => { | |
position.board[file][rank] = Pieces::BKnight; | |
file += 1; | |
} | |
'b' if file < 8 => { | |
position.board[file][rank] = Pieces::BBishop; | |
file += 1; | |
} | |
'r' if file < 8 => { | |
position.board[file][rank] = Pieces::BRook; | |
file += 1; | |
} | |
'q' if file < 8 => { | |
position.board[file][rank] = Pieces::BQueen; | |
file += 1; | |
} | |
'k' if file < 8 => { | |
position.board[file][rank] = Pieces::BKing; | |
file += 1; | |
} | |
d @ '1'..='8' => { | |
let d = d | |
.to_digit(10) | |
.ok_or("Invalid FEN format. Invalid piece placement.")?; | |
file += d as usize; | |
if file > 8 { | |
return Err("Invalid FEN format. Invalid piece placement."); | |
} | |
} | |
'/' if file == 8 && rank > 0 => { | |
rank -= 1; | |
file = 0; | |
} | |
_ => return Err("Invalid FEN format. Invalid piece placement."), | |
} | |
} | |
Ok(position) | |
} | |
} | |
fn main() { | |
let args: Vec<String> = env::args().collect(); | |
if args.len() != 2 { | |
eprintln!("Usage: fen2pic <fen>"); | |
process::exit(1); | |
} | |
match Position::from_fen(&args[1]) { | |
Ok(p) => { | |
print!("{}", p); | |
}, | |
Err(e) => { | |
eprintln!("{}", e); | |
process::exit(1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment