Skip to content

Instantly share code, notes, and snippets.

@neofight78
Created June 20, 2021 16:43
Show Gist options
  • Save neofight78/6632465a693000422e9491999bec4eba to your computer and use it in GitHub Desktop.
Save neofight78/6632465a693000422e9491999bec4eba to your computer and use it in GitHub Desktop.
Simple FEN Parser v1
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