33/// This struct holds bitmasks for each row, column, and 3x3 box in the Rustoku board.
44/// Each bit in the masks corresponds to a number from 1 to 9, where a bit set to 1 indicates
55/// that the corresponding number is present in that row, column, or box.
6- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
7- pub ( super ) struct Masks {
8- pub ( super ) row_masks : [ u16 ; 9 ] ,
9- pub ( super ) col_masks : [ u16 ; 9 ] ,
10- pub ( super ) box_masks : [ u16 ; 9 ] ,
6+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Default ) ]
7+ pub struct Masks {
8+ row_masks : [ u16 ; 9 ] ,
9+ col_masks : [ u16 ; 9 ] ,
10+ box_masks : [ u16 ; 9 ] ,
1111}
1212
1313impl Masks {
14- pub ( super ) fn new ( ) -> Self {
14+ pub fn new ( ) -> Self {
1515 Masks {
1616 row_masks : [ 0 ; 9 ] ,
1717 col_masks : [ 0 ; 9 ] ,
@@ -43,7 +43,7 @@ impl Masks {
4343 }
4444
4545 /// Checks if a number can be safely placed in the specified cell.
46- pub ( super ) fn is_safe ( & self , r : usize , c : usize , num : u8 ) -> bool {
46+ pub fn is_safe ( & self , r : usize , c : usize , num : u8 ) -> bool {
4747 let bit_to_check = 1 << ( num - 1 ) ;
4848 let box_idx = Self :: get_box_idx ( r, c) ;
4949
@@ -78,7 +78,7 @@ mod tests {
7878
7979 #[ test]
8080 fn test_new_initializes_empty_masks ( ) {
81- let masks = Masks :: new ( ) ;
81+ let masks = Masks :: default ( ) ;
8282 assert_eq ! ( masks. row_masks, [ 0 ; 9 ] ) ;
8383 assert_eq ! ( masks. col_masks, [ 0 ; 9 ] ) ;
8484 assert_eq ! ( masks. box_masks, [ 0 ; 9 ] ) ;
@@ -115,7 +115,7 @@ mod tests {
115115
116116 #[ test]
117117 fn test_add_number_single_cell ( ) {
118- let mut masks = Masks :: new ( ) ;
118+ let mut masks = Masks :: default ( ) ;
119119 masks. add_number ( 0 , 0 , 1 ) ;
120120 assert_eq ! ( masks. row_masks[ 0 ] , bit( 1 ) ) ;
121121 assert_eq ! ( masks. col_masks[ 0 ] , bit( 1 ) ) ;
@@ -124,7 +124,7 @@ mod tests {
124124
125125 #[ test]
126126 fn test_add_number_multiple_in_same_row ( ) {
127- let mut masks = Masks :: new ( ) ;
127+ let mut masks = Masks :: default ( ) ;
128128 masks. add_number ( 0 , 0 , 1 ) ;
129129 masks. add_number ( 0 , 1 , 5 ) ;
130130 assert_eq ! ( masks. row_masks[ 0 ] , bits( & [ 1 , 5 ] ) ) ;
@@ -135,7 +135,7 @@ mod tests {
135135
136136 #[ test]
137137 fn test_add_number_to_different_box ( ) {
138- let mut masks = Masks :: new ( ) ;
138+ let mut masks = Masks :: default ( ) ;
139139 masks. add_number ( 8 , 8 , 9 ) ;
140140 assert_eq ! ( masks. row_masks[ 8 ] , bit( 9 ) ) ;
141141 assert_eq ! ( masks. col_masks[ 8 ] , bit( 9 ) ) ;
@@ -144,7 +144,7 @@ mod tests {
144144
145145 #[ test]
146146 fn test_add_number_already_present_no_change ( ) {
147- let mut masks = Masks :: new ( ) ;
147+ let mut masks = Masks :: default ( ) ;
148148 masks. add_number ( 0 , 0 , 1 ) ;
149149 let initial_row_0 = masks. row_masks [ 0 ] ;
150150 masks. add_number ( 0 , 0 , 1 ) ; // Adding again
@@ -153,7 +153,7 @@ mod tests {
153153
154154 #[ test]
155155 fn test_remove_number_single_value_from_cell ( ) {
156- let mut masks = Masks :: new ( ) ;
156+ let mut masks = Masks :: default ( ) ;
157157 masks. add_number ( 0 , 0 , 1 ) ; // Add 1
158158 masks. remove_number ( 0 , 0 , 1 ) ; // Remove 1
159159 assert_eq ! ( masks. row_masks[ 0 ] , 0 ) ;
@@ -163,7 +163,7 @@ mod tests {
163163
164164 #[ test]
165165 fn test_remove_number_from_shared_row ( ) {
166- let mut masks = Masks :: new ( ) ;
166+ let mut masks = Masks :: default ( ) ;
167167 masks. add_number ( 0 , 0 , 1 ) ;
168168 masks. add_number ( 0 , 1 , 5 ) ;
169169 masks. remove_number ( 0 , 0 , 1 ) ;
@@ -175,7 +175,7 @@ mod tests {
175175
176176 #[ test]
177177 fn test_remove_number_not_present_no_change ( ) {
178- let mut masks = Masks :: new ( ) ;
178+ let mut masks = Masks :: default ( ) ;
179179 masks. add_number ( 0 , 0 , 1 ) ;
180180 let initial_row_0 = masks. row_masks [ 0 ] ;
181181 masks. remove_number ( 0 , 0 , 3 ) ; // Remove 3 (not present)
@@ -184,77 +184,77 @@ mod tests {
184184
185185 #[ test]
186186 fn test_is_safe_on_empty_board_always_true ( ) {
187- let masks = Masks :: new ( ) ;
187+ let masks = Masks :: default ( ) ;
188188 assert ! ( masks. is_safe( 0 , 0 , 1 ) ) ; // 1 should be safe anywhere
189189 assert ! ( masks. is_safe( 8 , 8 , 9 ) ) ; // 9 should be safe anywhere
190190 }
191191
192192 #[ test]
193193 fn test_is_safe_conflict_in_row ( ) {
194- let mut masks = Masks :: new ( ) ;
194+ let mut masks = Masks :: default ( ) ;
195195 masks. add_number ( 0 , 0 , 1 ) ; // Place 1 at (0,0)
196196 assert ! ( !masks. is_safe( 0 , 1 , 1 ) ) ; // 1 should not be safe in same row
197197 assert ! ( masks. is_safe( 0 , 1 , 2 ) ) ; // 2 should be safe in same row
198198 }
199199
200200 #[ test]
201201 fn test_is_safe_conflict_in_column ( ) {
202- let mut masks = Masks :: new ( ) ;
202+ let mut masks = Masks :: default ( ) ;
203203 masks. add_number ( 0 , 0 , 1 ) ; // Place 1 at (0,0)
204204 assert ! ( !masks. is_safe( 1 , 0 , 1 ) ) ; // 1 should not be safe in same col
205205 assert ! ( masks. is_safe( 1 , 0 , 2 ) ) ; // 2 should be safe in same col
206206 }
207207
208208 #[ test]
209209 fn test_is_safe_conflict_in_box ( ) {
210- let mut masks = Masks :: new ( ) ;
210+ let mut masks = Masks :: default ( ) ;
211211 masks. add_number ( 1 , 1 , 1 ) ; // Place 1 at (1,1) in box 0
212212 assert ! ( !masks. is_safe( 0 , 0 , 1 ) ) ; // 1 should not be safe in same box
213213 assert ! ( masks. is_safe( 0 , 0 , 2 ) ) ; // 2 should be safe in same box
214214 }
215215
216216 #[ test]
217217 fn test_is_safe_conflict_with_current_cell_value ( ) {
218- let mut masks = Masks :: new ( ) ;
218+ let mut masks = Masks :: default ( ) ;
219219 masks. add_number ( 0 , 0 , 1 ) ;
220220 assert ! ( !masks. is_safe( 0 , 0 , 1 ) ) ; // Should not be safe to place 1 where 1 already is
221221 assert ! ( masks. is_safe( 0 , 0 , 2 ) ) ; // Should be safe for other numbers
222222 }
223223
224224 #[ test]
225225 fn test_compute_candidates_empty_cell_all_available ( ) {
226- let masks = Masks :: new ( ) ;
226+ let masks = Masks :: default ( ) ;
227227 let candidates = masks. compute_candidates_mask_for_cell ( 0 , 0 ) ;
228228 assert_eq ! ( candidates, 0x1FF ) ; // All 9 bits should be set
229229 }
230230
231231 #[ test]
232232 fn test_compute_candidates_row_has_1_to_8_only_9_available ( ) {
233- let mut masks = Masks :: new ( ) ;
233+ let mut masks = Masks :: default ( ) ;
234234 masks. row_masks [ 0 ] = bits ( & [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ; // Directly set mask
235235 let candidates = masks. compute_candidates_mask_for_cell ( 0 , 0 ) ;
236236 assert_eq ! ( candidates, bit( 9 ) ) ;
237237 }
238238
239239 #[ test]
240240 fn test_compute_candidates_col_has_1_to_8_only_9_available ( ) {
241- let mut masks = Masks :: new ( ) ;
241+ let mut masks = Masks :: default ( ) ;
242242 masks. col_masks [ 0 ] = bits ( & [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ; // Directly set mask
243243 let candidates = masks. compute_candidates_mask_for_cell ( 0 , 0 ) ;
244244 assert_eq ! ( candidates, bit( 9 ) ) ;
245245 }
246246
247247 #[ test]
248248 fn test_compute_candidates_box_has_1_to_8_only_9_available ( ) {
249- let mut masks = Masks :: new ( ) ;
249+ let mut masks = Masks :: default ( ) ;
250250 masks. box_masks [ Masks :: get_box_idx ( 1 , 1 ) ] = bits ( & [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ; // Directly set mask for box 0
251251 let candidates = masks. compute_candidates_mask_for_cell ( 1 , 1 ) ;
252252 assert_eq ! ( candidates, bit( 9 ) ) ;
253253 }
254254
255255 #[ test]
256256 fn test_compute_candidates_mixed_restrictions ( ) {
257- let mut masks = Masks :: new ( ) ;
257+ let mut masks = Masks :: default ( ) ;
258258 // Row 0 has 1, 2
259259 masks. row_masks [ 0 ] = bits ( & [ 1 , 2 ] ) ;
260260 // Col 0 has 3, 4
@@ -268,7 +268,7 @@ mod tests {
268268
269269 #[ test]
270270 fn test_compute_candidates_no_candidates_left ( ) {
271- let mut masks = Masks :: new ( ) ;
271+ let mut masks = Masks :: default ( ) ;
272272 masks. row_masks [ 0 ] = 0x1FF ; // All 1-9 used in row
273273 let candidates = masks. compute_candidates_mask_for_cell ( 0 , 0 ) ;
274274 assert_eq ! ( candidates, 0 ) ; // No candidates
0 commit comments