pub fn parse_uci_coords(uci: &str) -> Option<(usize, usize, usize, usize)> {
let b: Vec<char> = uci.chars().collect();
if b.len() < 4 {
return None;
}
let c1 = (b[0] as u8).checked_sub(b'a')? as usize;
let r1 = 9usize.checked_sub(b[1].to_digit(10)? as usize)?;
let c2 = (b[2] as u8).checked_sub(b'a')? as usize;
let r2 = 9usize.checked_sub(b[3].to_digit(10)? as usize)?;
if r1 < 10 && c1 < 9 && r2 < 10 && c2 < 9 {
Some((r1, c1, r2, c2))
} else {
None
}
}
pub fn uci_from_coords(r1: usize, c1: usize, r2: usize, c2: usize) -> String {
format!(
"{}{}{}{}",
(b'a' + c1 as u8) as char,
9 - r1,
(b'a' + c2 as u8) as char,
9 - r2
)
}
#[inline]
pub fn uci_cell_label(file: u8, rank: u8) -> String {
format!("{}{}", (b'a' + file) as char, 9 - rank)
}
#[inline]
pub fn screen_to_internal(file: u8, screen_row: u8, rotated: bool) -> (u8, u8) {
if rotated {
(8 - file, 9 - screen_row)
} else {
(file, screen_row)
}
}
#[inline]
pub fn cursor_delta_internal(screen_dfile: i8, screen_drank: i8, rotated: bool) -> (i8, i8) {
if rotated {
(-screen_dfile, -screen_drank)
} else {
(screen_dfile, screen_drank)
}
}
#[inline]
#[cfg(test)]
pub fn internal_to_screen(file: u8, rank: u8, rotated: bool) -> (u8, u8) {
if rotated {
(8 - file, 9 - rank)
} else {
(file, rank)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn h2e2_maps_to_internal_ranks() {
let (r1, c1, r2, c2) = parse_uci_coords("h2e2").expect("coords");
assert_eq!((r1, c1, r2, c2), (7, 7, 7, 4));
assert_eq!(uci_from_coords(r1, c1, r2, c2), "h2e2");
}
#[test]
fn uci_cell_label_is_global() {
assert_eq!(uci_cell_label(0, 9), "a0");
assert_eq!(uci_cell_label(7, 7), "h2");
assert_eq!(uci_cell_label(8, 0), "i9");
}
#[test]
fn screen_map_flips_when_rotated() {
assert_eq!(screen_to_internal(0, 9, true), (8, 0));
assert_eq!(uci_cell_label(8, 0), "i9");
}
#[test]
fn cursor_delta_follows_screen_when_rotated() {
assert_eq!(cursor_delta_internal(0, -1, false), (0, -1));
assert_eq!(cursor_delta_internal(1, 0, false), (1, 0));
assert_eq!(cursor_delta_internal(0, -1, true), (0, 1));
assert_eq!(cursor_delta_internal(1, 0, true), (-1, 0));
}
}