def test_start_delay(): timing = Timing(start_at=datetime.utcnow() + timedelta(seconds=20), black_main=timedelta(minutes=1), black_overtime=timedelta(seconds=30)) timing.timing_updated_at = datetime.utcnow() - timedelta(seconds=10) update_timing(timing, True) assert timing.black_main == timedelta(minutes=1) assert timing.black_overtime == timedelta(seconds=30)
def test_update_timing(): tests = [ # Player has 1min main and 30sec overtime. # Tests: time_passed, expected_main, expected_overtime [timedelta(seconds=20), timedelta(seconds=40), timedelta(seconds=30)], [timedelta(seconds=30), timedelta(seconds=30), timedelta(seconds=30)], [timedelta(seconds=60), timedelta(seconds=0), timedelta(seconds=30)], [timedelta(seconds=70), timedelta(seconds=0), timedelta(seconds=20)], [timedelta(seconds=80), timedelta(seconds=0), timedelta(seconds=10)], [timedelta(seconds=90), timedelta(seconds=0), timedelta(seconds=0)], [timedelta(seconds=100), timedelta(seconds=0), timedelta(seconds=-10)], ] for t in tests: timing = Timing(start_at=datetime.utcnow() - timedelta(seconds=1), black_main=timedelta(minutes=1), black_overtime=timedelta(seconds=30)) timing.timing_updated_at = datetime.utcnow() - t[0] has_time = update_timing(timing, True) assert timing.timing_updated_at - datetime.utcnow() < timedelta( seconds=1) assert round(timing.black_main.total_seconds()) == round( t[1].total_seconds()) assert round(timing.black_overtime.total_seconds()) == round( t[2].total_seconds()) assert has_time == (timing.black_total.total_seconds() > 0) timing = Timing(start_at=datetime.utcnow() - timedelta(seconds=1), white_main=timedelta(minutes=1), white_overtime=timedelta(seconds=30)) timing.timing_updated_at = datetime.utcnow() - t[0] has_time = update_timing(timing, False) assert timing.timing_updated_at - datetime.utcnow() < timedelta( seconds=1) assert round(timing.white_main.total_seconds()) == round( t[1].total_seconds()) assert round(timing.white_overtime.total_seconds()) == round( t[2].total_seconds()) assert has_time == (timing.white_total.total_seconds() > 0)
def _game_move(self, game, move): if self.user not in [game.black_user, game.white_user]: raise InvalidPlayerError() if game.stage == 'finished': raise InvalidStageError() if not game.timing.has_started: raise GameHasNotStartedError() if move == RESIGN: self._resign(game) return if game.stage != 'playing': raise InvalidStageError() if game.current_user != self.user: raise InvalidPlayerError() if not update_timing(game.timing, game.board.current == BLACK): self._win_by_time(game) return game.board.play(move) update_timing_after_move(game.timing, game.board.current != BLACK) if game.board.both_passed: game.stage = 'counting' self._update_score(game)
def check_due_moves(self): """Checks and updates all timings which are due for a move being played.""" timings = self.db.query(Timing).with_for_update().join('game').options(undefer('game.board')).filter( (Game.is_demo.is_(False)) & (Game.stage == 'playing') & (Timing.next_move_at <= datetime.utcnow())) for timing in timings: if not update_timing(timing, timing.game.board.current == BLACK): self._win_by_time(timing.game) self._finish_game(timing.game)