chessfriend/board/src/move_counter.rs
2025-05-08 17:37:51 -07:00

74 lines
2.1 KiB
Rust

use chessfriend_core::Color;
#[derive(Default)]
pub enum AdvanceHalfMove {
Reset,
#[default]
Advance,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct Clock {
/// The number of completed turns. A turn finishes when every player has moved.
pub full_move_number: u16,
/// The number of moves by all players since the last pawn advance or capture.
pub half_move_number: u16,
}
impl Clock {
pub fn advance(&mut self, advance_half_move: &AdvanceHalfMove) {
let next_color = self.active_color.next();
match self.active_color {
Color::Black => self.full_move_number += 1,
Color::White => {}
}
self.half_move_number = match advance_half_move {
AdvanceHalfMove::Reset => 0,
AdvanceHalfMove::Advance => self.half_move_number + 1,
};
self.active_color = next_color;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_state() {
let clock = Clock::default();
assert_eq!(clock.active_color, Color::White);
assert_eq!(clock.half_move_number, 0);
assert_eq!(clock.full_move_number, 0);
}
#[test]
fn advance() {
let mut clock = Clock::default();
clock.advance(&AdvanceHalfMove::default());
assert_eq!(clock.active_color, Color::Black);
assert_eq!(clock.half_move_number, 1);
assert_eq!(clock.full_move_number, 0);
clock.advance(&AdvanceHalfMove::default());
assert_eq!(clock.active_color, Color::White);
assert_eq!(clock.half_move_number, 2);
assert_eq!(clock.full_move_number, 1);
clock.advance(&AdvanceHalfMove::default());
assert_eq!(clock.active_color, Color::Black);
assert_eq!(clock.half_move_number, 3);
assert_eq!(clock.full_move_number, 1);
// The half move clock resets after a capture or pawn push.
clock.advance(&AdvanceHalfMove::Reset);
assert_eq!(clock.active_color, Color::White);
assert_eq!(clock.half_move_number, 0);
assert_eq!(clock.full_move_number, 2);
}
}