class Controller: def __init__(self, connection): self._connection = connection self._engine = Engine() self._cmd_timestamps = deque([0] * 9, 5) # max 9 commands per second self._direction = Direction.STOP self._score = defaultdict(int) def start(self, botname, duelpartner = None): log.info("Started controller") if duelpartner == None: self._join_game(botname) else: self._request_duel(botname, duelpartner) self._mainloop() def _mainloop(self): response_handlers = { 'joined': self._game_joined, 'gameStarted': self._game_started, 'gameIsOn': self._make_move, 'gameIsOver': self._game_over } response = "" while True: try: response = self._connection.receive() msg_type, data = response['msgType'], response['data'] if response_handlers.has_key(msg_type): response_handlers[msg_type](data) else: log.warning('Invalid Message received: %s' % response) except: log.exception('Json data: %s' % response) def _game_joined(self, data): log.info('Game visualization url: %s' % data) def _game_started(self, data): log.info('Game started: %s vs. %s' % (data[0], data[1])) self._engine.start_round() def _game_over(self, data): log.info('Game ended. Winner: %s' % data) self._score[data] += 1 log.info('Score: %s' % self._score) def _make_move(self, data): dataentry = DataEntry(data) direction = self._engine.check_direction(dataentry) self._engine.update(dataentry) if direction != self._engine.direction: self._set_direction(self._engine.direction) def _join_game(self, botname): log.info('Joining game...') self._connection.send({'msgType': 'join', 'data': botname}) def _request_duel(self, botname, duelpartner): log.info('Challenging %s...' % duelpartner) self._connection.send({'msgType': 'requestDuel', 'data': [botname, duelpartner]}) def _set_direction(self, direction): if time.time() - self._cmd_timestamps[0] < Direction.DOWN: raise Exception("Discard message. Too many requests sent in one second!") self._cmd_timestamps.append(time.time()) self._connection.send({'msgType': 'changeDir', 'data': direction})