2025-11-11 13:39:26 +01:00
|
|
|
|
|
|
|
|
pub fn pop_lsb(value: &mut u64) -> usize {
|
2025-11-11 14:14:39 +01:00
|
|
|
let idx = value.trailing_zeros() as usize;
|
|
|
|
|
*value &= !(1 << idx);
|
|
|
|
|
return idx;
|
2025-11-11 13:39:26 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-11 13:51:14 +01:00
|
|
|
pub fn pop_msb(value: &mut u64) -> usize {
|
2025-11-11 14:16:33 +01:00
|
|
|
let idx = 63 - value.leading_zeros() as usize;
|
|
|
|
|
*value &= !(1 << idx);
|
|
|
|
|
return idx;
|
2025-11-11 13:51:14 +01:00
|
|
|
}
|
2025-11-11 13:39:26 +01:00
|
|
|
|
2025-11-11 14:21:11 +01:00
|
|
|
const RANK_NUMBERS: [char; 8] = ['1', '2', '3', '4', '5', '6', '7', '8'];
|
|
|
|
|
const FILE_LETTERS: [char; 8] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
|
2025-11-11 13:59:53 +01:00
|
|
|
pub fn notation_from_square_number(sq: u8) -> String {
|
2025-11-11 14:21:11 +01:00
|
|
|
let row = sq / 8;
|
|
|
|
|
let col = sq % 8;
|
|
|
|
|
let mut notation = String::new();
|
|
|
|
|
|
|
|
|
|
let row_not = RANK_NUMBERS[row as usize];
|
|
|
|
|
let col_not = FILE_LETTERS[col as usize];
|
|
|
|
|
|
|
|
|
|
notation.push(col_not);
|
|
|
|
|
notation.push(row_not);
|
|
|
|
|
return notation;
|
2025-11-11 13:59:53 +01:00
|
|
|
}
|
|
|
|
|
|
2025-11-11 13:39:26 +01:00
|
|
|
|
|
|
|
|
// <----- TESTS ----->
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn pop_lsb_test() {
|
|
|
|
|
|
|
|
|
|
// test setup
|
|
|
|
|
let test_values: [u64; 6] = [
|
2025-11-11 14:06:43 +01:00
|
|
|
0x8000_0000_0000_0000,
|
2025-11-11 13:39:26 +01:00
|
|
|
0x4E91_CF05_713E_451B,
|
|
|
|
|
0xD588_2D58_6962_34B0,
|
|
|
|
|
0x9581_3335_DCAB_1DD4,
|
|
|
|
|
0xBEAC_DBE0_903A_AC00,
|
|
|
|
|
0x01E8_C895_A6F0_0000
|
|
|
|
|
];
|
2025-11-11 14:06:43 +01:00
|
|
|
let expected_values: [usize; 6] = [63, 0, 4, 2, 10, 20];
|
2025-11-11 13:39:26 +01:00
|
|
|
|
|
|
|
|
// tests
|
|
|
|
|
for index in 0..6 {
|
|
|
|
|
let mut test_value = test_values[index];
|
|
|
|
|
assert_eq!(pop_lsb(&mut test_value), expected_values[index])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 13:51:14 +01:00
|
|
|
#[test]
|
|
|
|
|
fn pop_msb_test() {
|
|
|
|
|
// test setup
|
|
|
|
|
let test_values: [u64; 6] = [
|
|
|
|
|
0x86D6_8EB0_96A8_8D1C,
|
|
|
|
|
0x0000_0000_0000_0001,
|
|
|
|
|
0x3809_24AF_A7AE_8129,
|
|
|
|
|
0x0277_DA36_3B31_86D9,
|
|
|
|
|
0x0000_C1C3_201C_0DB1,
|
|
|
|
|
0x0000_0203_0DE4_E944
|
|
|
|
|
];
|
|
|
|
|
let expected_values: [usize; 6] = [63, 0, 61, 57, 47, 41];
|
|
|
|
|
|
|
|
|
|
// tests
|
|
|
|
|
for index in 0..6 {
|
|
|
|
|
let mut test_value = test_values[index];
|
2025-11-11 14:05:31 +01:00
|
|
|
assert_eq!(pop_msb(&mut test_value), expected_values[index])
|
2025-11-11 13:51:14 +01:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-11 13:59:53 +01:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn notation_from_square_number_test() {
|
|
|
|
|
// test setup
|
|
|
|
|
let square_indices: [u8; 8] = [1, 12, 22, 27, 32, 47, 53, 58];
|
|
|
|
|
let notations: [String; 8] = [
|
|
|
|
|
String::from("b1"),
|
|
|
|
|
String::from("e2"),
|
|
|
|
|
String::from("g3"),
|
|
|
|
|
String::from("d4"),
|
|
|
|
|
String::from("a5"),
|
|
|
|
|
String::from("h6"),
|
|
|
|
|
String::from("f7"),
|
|
|
|
|
String::from("c8")
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// tests
|
|
|
|
|
for index in 0..8 {
|
|
|
|
|
let notation = notation_from_square_number(square_indices[index].clone());
|
|
|
|
|
assert_eq!(notation, notations[index]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-11 13:39:26 +01:00
|
|
|
}
|