Skip to content

BE: PlayerClock::time_out() ignores a running clock (flag-fall undetected on the mover's turn) #941

Description

@abdulwaarith0

Bug

backend/modules/chess/src/time_control.rsPlayerClock::time_out() checks the raw remaining_time field, which is only decremented on stop():

pub fn time_out(&self) -> bool {
    self.remaining_time.is_zero()
}

While a clock is_running, elapsed time is not reflected in remaining_time (it is applied later in stop()). So a player who sits on a running clock past zero is never reported as flagged. get_real_time_remaining() already accounts for the running clock:

pub fn get_real_time_remaining(&self) -> Duration {
    if self.is_running {
        if let Some(last_move_time) = self.last_move_time {
            return self.remaining_time.saturating_sub(last_move_time.elapsed());
        }
    }
    self.remaining_time
}

This is exactly the case flag-detection must catch: the player on the move letting their clock run out without moving. Game::check_time_out() (in game.rs) relies on time_out(), so it cannot detect that timeout.

Fix

pub fn time_out(&self) -> bool {
    self.get_real_time_remaining().is_zero()
}

This does not break the existing test in tests/time_control_tests.rs (it asserts !time_out() on a stopped clock and time_out() after set_remaining_time(0) — both still hold).

Note (latent / related cleanup)

This is currently a latent defect: game.rs is not declared in chess/src/lib.rs (lib.rs only exposes bitboard, time_control, pgn, rating), so check_time_out() is uncompiled, and no live server code imports PlayerClock yet. But PlayerClock/time_out() are exported public API and will bite whoever wires up the clock. game.rs also mixes diesel while the rest of the crate uses sea_orm — possibly worth a separate cleanup issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions