blunders_engine/boardrepr/
mailbox.rs1use std::fmt::{self, Display};
8use std::ops::{Index, IndexMut};
9
10use crate::boardrepr::PieceSets;
11use crate::coretypes::{
12 Color, Piece, PieceKind, Square, SquareIndexable, NUM_FILES, NUM_RANKS, NUM_SQUARES,
13};
14
15#[derive(Debug, Clone, Eq, PartialEq)]
24pub struct Mailbox {
25 board: [Option<Piece>; Self::SIZE],
26}
27
28impl Mailbox {
29 pub const FILES: usize = NUM_FILES;
30 pub const RANKS: usize = NUM_RANKS;
31 pub const SIZE: usize = NUM_SQUARES;
32
33 pub fn new() -> Self {
35 Mailbox {
36 board: [None; Mailbox::SIZE],
37 }
38 }
39
40 pub fn start_position() -> Self {
42 use Color::*;
43 use PieceKind::*;
44 use Square::*;
45 let mut mb = Self::new();
46
47 mb[A1] = Some(Piece::new(White, Rook));
48 mb[B1] = Some(Piece::new(White, Knight));
49 mb[C1] = Some(Piece::new(White, Bishop));
50 mb[D1] = Some(Piece::new(White, Queen));
51 mb[E1] = Some(Piece::new(White, King));
52 mb[F1] = Some(Piece::new(White, Bishop));
53 mb[G1] = Some(Piece::new(White, Knight));
54 mb[H1] = Some(Piece::new(White, Rook));
55 for square in [A2, B2, C2, D2, E2, F2, G2, H2] {
56 mb[square] = Some(Piece::new(White, Pawn));
57 }
58 mb[A8] = Some(Piece::new(Black, Rook));
59 mb[B8] = Some(Piece::new(Black, Knight));
60 mb[C8] = Some(Piece::new(Black, Bishop));
61 mb[D8] = Some(Piece::new(Black, Queen));
62 mb[E8] = Some(Piece::new(Black, King));
63 mb[F8] = Some(Piece::new(Black, Bishop));
64 mb[G8] = Some(Piece::new(Black, Knight));
65 mb[H8] = Some(Piece::new(Black, Rook));
66 for square in [A7, B7, C7, D7, E7, F7, G7, H7] {
67 mb[square] = Some(Piece::new(Black, Pawn));
68 }
69
70 mb
71 }
72
73 pub fn board(&self) -> &[Option<Piece>; Self::SIZE] {
74 &self.board
75 }
76
77 pub fn pretty(&self) -> String {
80 const RANK_SEP: &'static str = "+---+---+---+---+---+---+---+---+\n";
81 let mut pretty = String::with_capacity(626); pretty.push_str(RANK_SEP);
84 for rank in (0..Self::RANKS).rev() {
85 pretty.push_str("| ");
86
87 for file in 0..Self::FILES {
88 pretty.push(match self[rank * Self::RANKS + file] {
89 Some(piece) => char::from(piece),
90 None => ' ',
91 });
92 pretty.push_str(" | ");
93 }
94 pretty.push_str(&(rank + 1).to_string());
95 pretty.push('\n');
96 pretty.push_str(RANK_SEP);
97 }
98 pretty.push_str(" a b c d e f g h\n");
99
100 pretty
101 }
102}
103
104impl Index<usize> for Mailbox {
106 type Output = Option<Piece>;
107 fn index(&self, idx: usize) -> &Self::Output {
108 &self.board[idx]
109 }
110}
111
112impl IndexMut<usize> for Mailbox {
113 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
114 &mut self.board[idx]
115 }
116}
117
118impl<I: SquareIndexable> Index<I> for Mailbox {
119 type Output = Option<Piece>;
120 fn index(&self, idx: I) -> &Self::Output {
121 &self.board[idx.idx()]
122 }
123}
124
125impl<I: SquareIndexable> IndexMut<I> for Mailbox {
126 fn index_mut(&mut self, idx: I) -> &mut Self::Output {
127 &mut self.board[idx.idx()]
128 }
129}
130
131impl From<&PieceSets> for Mailbox {
132 fn from(pieces: &PieceSets) -> Mailbox {
133 let mut mb = Mailbox::new();
134
135 for color in Color::iter() {
136 for piece_kind in PieceKind::iter() {
137 let piece = Piece::new(color, piece_kind);
138 pieces[&piece]
139 .into_iter()
140 .for_each(|square| mb[square] = Some(piece));
141 }
142 }
143 mb
144 }
145}
146
147impl Default for Mailbox {
149 fn default() -> Self {
150 Mailbox::start_position()
151 }
152}
153
154impl Display for Mailbox {
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 write!(f, "{}", self.pretty())
157 }
158}
159
160#[cfg(test)]
161mod tests {
162 use super::*;
163
164 #[test]
165 fn display_start_position_mailbox() {
166 let mb = Mailbox::start_position();
167
168 println!("{}", mb.pretty().len());
169 println!("{}", mb);
170 }
171}