Add two BitBoard attributes to the struct that mark squares that should be marked or highlighted. Empty marked squares are shown with an asterisk (*). Marked squares with a piece don't have any change of appearance. (Something I'm still thinking about.) Highlighted squares are shown with the ANSI escape sequence for Reverse Video.
106 lines
2.6 KiB
Rust
106 lines
2.6 KiB
Rust
// Eryn Wells <eryn@erynwells.me>
|
|
|
|
use crate::Board;
|
|
use chessfriend_bitboard::BitBoard;
|
|
use chessfriend_core::{File, Rank, Square};
|
|
use std::fmt;
|
|
|
|
#[must_use]
|
|
pub struct DiagramFormatter<'a> {
|
|
board: &'a Board,
|
|
marked_squares: BitBoard,
|
|
highlighted_squares: BitBoard,
|
|
}
|
|
|
|
impl<'a> DiagramFormatter<'a> {
|
|
pub fn new(board: &'a Board) -> Self {
|
|
Self {
|
|
board,
|
|
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) {
|
|
write!(f, "{piece}")?;
|
|
} 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}");
|
|
}
|
|
}
|