use crate::flag::{Flag, FlagCheck};
use crate::parser;
use crate::piece::Piece;
use crate::square::Square;
use std::fmt;
#[derive(Clone, Debug, PartialEq)]
pub struct Move {
pub who: Piece,
pub dst: Square,
pub flags: u8,
pub src: Option<Vec<Square>>,
pub promotion: Option<Piece>,
}
impl Move {
fn constuct_src_string(src: &[Square]) -> String {
match src.len() {
1 => return src[0].to_string(),
8 => (),
_ => panic!("'Source' should contain a set of 8 ranks/files"),
}
let (file, rank) = {
let s = src[0].to_string();
let mut square_chars = s.chars();
(square_chars.next().unwrap(), square_chars.next().unwrap())
};
match src[1].to_string().contains(file) {
true => String::from(file),
false => String::from(rank),
}
}
}
impl FlagCheck for Move {
fn get_flags(&self) -> u8 {
self.flags
}
}
impl fmt::Display for Move {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = String::with_capacity(16);
if self.who != Piece::Pawn {
s.push(parser::get_piece_char(self.who));
}
if let Some(ref src) = self.src {
s.push_str(Self::constuct_src_string(src).as_str());
}
if self.check_flag(Flag::CAPTURE) {
s.push('x');
}
s.push_str(self.dst.to_string().as_str());
if let Some(promotion_piece) = self.promotion {
s.push('=');
s.push(parser::get_piece_char(promotion_piece));
}
if self.check_flag(Flag::CHECK) {
s.push('+');
} else if self.check_flag(Flag::CHECKMATE) {
s.push('#');
}
write!(f, "{}", s)
}
}