1use bitvec::slice::BitSlice;
2
3use crate::DimensionMismatch;
4
5pub trait BitBoard: Sized {
6 fn n_rows(&self) -> usize;
8
9 fn n_cols(&self) -> usize;
11
12 fn board_mut(&mut self) -> &mut BitSlice;
14
15 fn board(&self) -> &BitSlice;
17
18 fn index_of(&self, row: usize, col: usize) -> usize {
20 assert!(
21 row <= (self.n_rows() - 1),
22 "row cannot be greater than n_rows"
23 );
24 assert!(
25 col <= (self.n_cols() - 1),
26 "col cannot be greater than n_cols"
27 );
28 (row * self.n_cols()) + col
29 }
30
31 fn fill(&mut self, value: bool) {
33 self.board_mut().fill(value);
34 }
35
36 fn or(&self, other: &impl BitBoard) -> Result<Self, DimensionMismatch>;
37 fn and(&self, other: &impl BitBoard) -> Result<Self, DimensionMismatch>;
38
39 fn set(&mut self, row: usize, col: usize, value: bool) {
41 let new_ind = self.index_of(row, col);
42 self.board_mut().set(new_ind, value);
43 }
44 fn set_col(&mut self, col: usize, value: bool) {
46 for r_idx in 0..self.n_rows() {
48 let idx = (r_idx * self.n_cols()) + col;
50 self.board_mut().set(idx, value);
51 }
52 }
53
54 fn set_row(&mut self, row: usize, value: bool) {
56 for cidx in 0..self.n_cols() {
58 let idx = (row * self.n_cols()) + cidx;
60 self.board_mut().set(idx, value);
61 }
62 }
63
64 fn set_cardinal_neighbors(&mut self, row: usize, col: usize, value: bool) {
67 if row > 0 {
69 self.set(row - 1, col, value);
70 }
71
72 if row < self.n_rows() - 1 {
74 self.set(row + 1, col, value);
75 }
76
77 if col > 0 {
79 self.set(row, col - 1, value);
80 }
81
82 if col < self.n_cols() - 1 {
84 self.set(row, col + 1, value);
85 }
86 }
87
88 fn set_diagonals(&mut self, row: usize, col: usize, value: bool) {
91 if row > 0 && col > 0 {
93 self.set(row - 1, col - 1, value);
94 }
95
96 if row > 0 && col < self.n_cols() - 1 {
98 self.set(row - 1, col + 1, value);
99 }
100
101 if row < self.n_rows() - 1 && col > 0 {
103 self.set(row + 1, col - 1, value);
104 }
105
106 if row < self.n_rows() - 1 && col < self.n_cols() - 1 {
108 self.set(row + 1, col + 1, value);
109 }
110 }
111
112 fn set_all_neighbors(&mut self, row: usize, col: usize, value: bool) {
115 self.set_cardinal_neighbors(row, col, value);
116 self.set_diagonals(row, col, value);
117 }
118}