119 lines
3 KiB
Rust
119 lines
3 KiB
Rust
// Eryn Wells <eryn@erynwells.me>
|
|
|
|
use crate::Board;
|
|
use chessfriend_bitboard::BitBoard;
|
|
use chessfriend_core::{File, Rank, Square};
|
|
use std::fmt;
|
|
|
|
#[derive(Default)]
|
|
pub enum PieceDisplayStyle {
|
|
#[default]
|
|
Unicode,
|
|
ASCII,
|
|
}
|
|
|
|
#[must_use]
|
|
pub struct DiagramFormatter<'a> {
|
|
board: &'a Board,
|
|
piece_style: PieceDisplayStyle,
|
|
marked_squares: BitBoard,
|
|
highlighted_squares: BitBoard,
|
|
}
|
|
|
|
impl<'a> DiagramFormatter<'a> {
|
|
pub fn new(board: &'a Board) -> Self {
|
|
Self {
|
|
board,
|
|
piece_style: PieceDisplayStyle::default(),
|
|
marked_squares: BitBoard::default(),
|
|
highlighted_squares: BitBoard::default(),
|
|
}
|
|
}
|
|
|
|
pub fn mark(mut self, bitboard: BitBoard) -> Self {
|
|
self.marked_squares = bitboard;
|
|
self
|
|
}
|
|
|
|
pub fn highlight(mut self, bitboard: BitBoard) -> Self {
|
|
self.highlighted_squares = bitboard;
|
|
self
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for DiagramFormatter<'_> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
writeln!(f, " ╔═════════════════╗")?;
|
|
|
|
for rank in Rank::ALL.into_iter().rev() {
|
|
write!(f, "{rank} ║ ")?;
|
|
|
|
for file in File::ALL {
|
|
let square = Square::from_file_rank(file, rank);
|
|
|
|
let should_highlight = self.highlighted_squares.contains(square);
|
|
if should_highlight {
|
|
write!(f, "\x1b[7m")?;
|
|
}
|
|
|
|
if let Some(piece) = self.board.get_piece(square) {
|
|
let ch = match self.piece_style {
|
|
PieceDisplayStyle::Unicode => piece.to_unicode(),
|
|
PieceDisplayStyle::ASCII => piece.to_ascii(),
|
|
};
|
|
write!(f, "{ch}")?;
|
|
} else {
|
|
let ch = if self.marked_squares.contains(square) {
|
|
'*'
|
|
} else {
|
|
'·'
|
|
};
|
|
write!(f, "{ch}")?;
|
|
}
|
|
|
|
if should_highlight {
|
|
write!(f, "\x1b[0m")?;
|
|
}
|
|
|
|
write!(f, " ")?;
|
|
}
|
|
|
|
writeln!(f, "║")?;
|
|
}
|
|
|
|
writeln!(f, " ╚═════════════════╝")?;
|
|
write!(f, " a b c d e f g h")?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::{test_board, Board};
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn empty() {
|
|
let board = test_board!(empty);
|
|
let diagram = DiagramFormatter::new(&board);
|
|
println!("{diagram}");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn one_king() {
|
|
let board = test_board![Black King on H3];
|
|
let diagram = DiagramFormatter::new(&board);
|
|
println!("{diagram}");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn starting() {
|
|
let board = test_board!(starting);
|
|
let diagram = DiagramFormatter::new(&board);
|
|
println!("{diagram}");
|
|
}
|
|
}
|