| """ |
| Time Manager for Nexus-Core |
| Simplified adaptive time control |
| """ |
|
|
| import time |
| from typing import Optional |
|
|
|
|
| class TimeManager: |
| """Adaptive time allocation for searches""" |
| |
| def __init__(self): |
| self.start_time = 0.0 |
| self.allocated_time = 0.0 |
| self.hard_limit = 0.0 |
| self.move_overhead = 0.050 |
| |
| def allocate_time( |
| self, |
| time_left: float, |
| increment: float = 0.0, |
| moves_to_go: Optional[int] = None, |
| move_number: int = 1 |
| ) -> tuple[float, float]: |
| """Calculate time allocation""" |
| |
| |
| emergency_reserve = min(2.0, time_left * 0.1) |
| available_time = max(0, time_left - emergency_reserve - self.move_overhead) |
| |
| |
| if moves_to_go: |
| expected_moves = moves_to_go |
| else: |
| expected_moves = max(20, 40 - move_number // 2) |
| |
| |
| base_time = available_time / expected_moves |
| increment_bonus = increment * 0.8 |
| |
| |
| soft_limit = base_time + increment_bonus |
| |
| |
| hard_limit = min( |
| soft_limit * 3.0, |
| available_time * 0.5 |
| ) |
| |
| |
| soft_limit = max(soft_limit, 0.1) |
| hard_limit = max(hard_limit, soft_limit) |
| |
| return soft_limit, hard_limit |
| |
| def start_search(self, allocated_time: float, hard_limit: float): |
| """Initialize timer""" |
| self.start_time = time.time() |
| self.allocated_time = allocated_time |
| self.hard_limit = hard_limit |
| |
| def should_stop(self, depth: int, best_move_stable: bool = False) -> bool: |
| """Check if should stop""" |
| elapsed = time.time() - self.start_time |
| |
| |
| if elapsed >= self.hard_limit: |
| return True |
| |
| |
| if elapsed >= self.allocated_time: |
| if best_move_stable or depth >= 4: |
| return True |
| |
| return False |
| |
| def elapsed(self) -> float: |
| """Get elapsed time""" |
| return time.time() - self.start_time |
| |
| def remaining(self) -> float: |
| """Get remaining time""" |
| return max(0, self.allocated_time - self.elapsed()) |