def prepareGame(self, status, queue) -> (): """Prepare Level 1 Do hardware-preparations :param status: current state of the game, used for web-frontend :param queue: Message-Q for hardware.messages to be launched return list of hardware-processes started here """ kbd = CheckKey(queue) startThreadClass(kbd) timer = Countdown(queue, 16) status.msg = str(_("Level01 starts..")) models.setGameState(self.user_id, status) startThreadClass(timer) glob = tlu_globals.globMgr.tlu_glob() glob.lcdMessagebyline( _("Level: ") + "01", str(_("Easy start ")) + ":)") status.msg = str(_("Level 1 running")) status.level_start = timezone.now() status.level_progress = 0 models.setGameState(self.user_id, status) return ( timer, kbd, )
def finishGame(self, status, hardware): """End game-level Close down hardware-activities started :param status: current state of the game, used for web-frontend :param hardware: List of hardware-processes that should be terminated here """ ( timer, kbd, touch, ) = hardware glob = tlu_globals.globMgr.tlu_glob() buz = None if status.result != None and status.result != Level.PASSED: buz = Buzzer(0.1) startThreadClass(buz) status.msg = str(_("Level 4 failed")) status.level_progress = 0 glob.matrixShow_symbol('triangle_down') time.sleep(0.3) #wait a bit else: status.msg = str(_("You have passed Level 4 :)")) status.level_progress = 100 status.result = Level.PASSED status.points = 20 glob.matrixShow_symbol('smiley') status.level_ended = timezone.now() models.setGameState(self.user_id, status) abortThread(touch, 0.5, "aborting Touch") abortThread(kbd, 1, "aborting Keyboard") abortThread(timer, 1, "aborting countdown") abortThread(buz, 0.5, "aborting Buzzer")
def msg(self, gameProcess, msg, progress, key=-1, error=False): status = models.getGameState(gameProcess.user_id) status.msg = msg if key > -1: status.msg += str(key) if error: status.result = Level.DIDNOTFINISH status.level_progress = progress models.setGameState(gameProcess.user_id, status)
def set_abortmsg(self, user_id): """ Internal service function :param user_id: The user in question """ status = models.getGameState(user_id) status.msg = _("Game aborted :(") status.result = Level.ABORT status.level_progress = 100 models.setGameState(user_id, status)
def run(self, stop_event, gameProcess, hardware, language): # @UnusedVariable """ Main loop for Level2 Main :param stop_event: event coming from main-loop, once set, level will terminate :param gameProcess: the main process running the level. Needed to check for termination requests and the user_id :param hardware: list of started threads """ translation.activate(language) self.clearQueue() #cleanup before we start keymatrix = {} thread = threading.currentThread() while True: if len(keymatrix) == 4: stop_event.set() break (queueobject, breakIndicator) = self.getQueueObject(stop_event, gameProcess, thread) if breakIndicator: break if queueobject == None: continue self.queue.task_done() #release object from queue if self.checkAbort(stop_event, gameProcess, thread, queueobject): break elif queueobject.msg_num == self.MSG_KEYPRESSED: glob = tlu_globals.globMgr.tlu_glob() glob.lcdMessagebyline( _("Level: ") + "02", str(_("Cursor=")) + tlu_cursor.cursorname(None, queueobject.msg_info)) keymatrix[queueobject.msg_info] = 1 symbolname = 'space' if queueobject.msg_info == 100: symbolname = 'arrow_up' elif queueobject.msg_info == 200: symbolname = 'arrow_right' elif queueobject.msg_info == 300: symbolname = 'arrow_down' elif queueobject.msg_info == 400: symbolname = 'arrow_left' glob.matrixShow_symbol(symbolname) status = models.getGameState(gameProcess.user_id) status.msg = str(_("You have just pressed cursor - ") ) + tlu_cursor.cursorname( None, queueobject.msg_info) status.level_progress = int(len(keymatrix) / 4 * 100) models.setGameState(gameProcess.user_id, status) time.sleep(0.5) #wait for messages to settle elif queueobject.msg_num == self.MSG_KEYRELEASED: pass
def prepareGame(self, status, queue) -> (): """Prepare Test Do hardware-preparations :param status: current state of the game, used for web-frontend :param queue: Message-Q for hardware.messages to be launched return list of hardware-processes started here """ timer = Countdown(queue, 0.5) status.msg = _("Level00 starts..") status.level_start = timezone.now() models.setGameState(self.user_id, status) startProcess(timer) return (timer, )
def prepareGame(self, status, queue) -> (): """ Method to be overwritten by implementation. Would be called before starting the processing of the message queue Use this as a *template* only! return list of started processes (needed to terminate them at the end) :param status: status object of the level :param queue: Message queu for game-messages """ timer = Countdown(queue, 1) status.msg = _("Level00 starts..") status.level_start = timezone.now() models.setGameState(self.user_id, status) startProcess(timer) return (timer, )
def run(self, *args, **kwargs): """ The main process for this level Please overwrite the following methods and not this one: * prepareGame and * finishGame besides * GameQueue.run as these 3 provide the necessary game-functionalities and not this "run" method """ logger.debug('level started') status = models.getCleanGameState(self.user_id) status.msg = (_("Level is running")) status.level_progress = 0 models.setGameState(self.user_id, status) if not userOk(self.user_id): status.msg = _("You have to login in order to play this level...") models.setGameState(self.user_id, status) return queue = self.GameQueue() stop_event = Event() hardware = self.prepareGame(status, queue) language = translation.get_language() #print(str(language)) qThread = startThread( queue.run, args=( stop_event, self, hardware, language, ), name="queue_for_level") #needed to loop through the messages stop_event.wait( ) #wait until queues stops processing or level gets terminated stop_event.clear() status = getGameState(self.user_id) self.finishGame(status, hardware) status = getGameState(self.user_id) logger.info('Level State= ' + str(status)) logger.debug('Level ended') queue.close() abortThread(qThread, 1, "aborting message-Queue") glob = tlu_globals.globMgr.tlu_glob() glob.startClock() #restart clock in case it had been stopped return
def test_status(self): """ Test the status object """ logging.debug('Test test_status started') game = self.getGame('test_status') gamestate = getCleanGameState(game.user.id) self.assertEqual(gamestate.level_progress, 0, "The initial Progress has to be 0") gamestate.msg = "HALLO" gamestate.level_progress = 55 setGameState(game.user.id, gamestate) gamestate = getGameState(game.user.id) self.assertEqual(gamestate.msg, "HALLO", "The messages differ :(") self.assertEqual(gamestate.level_progress, 55, "The Progress has to be 55") logging.debug('Test status ended')
def checkAbort(self, thread, user_id, msg): """ Check if a thread should be aborted. Each thread has now added an attribute "is_aborted", if set the thread should terminate itself :param thread: The thread in question :param user_id: user that is currently active, needed for the gamestated :param msg: Message that will be shown on the web once the task has been aborted """ if getattr(thread, "is_aborted", False): status = models.getGameState(user_id) status.msg = msg status.level_progress = 100 status.result = Level.ABORT models.setGameState(user_id, status) return True return False
def run(self, stop_event, gameProcess, hardware, language): # @UnusedVariable """ Queue loop for level 1 Main :param stop_event: event coming from main-loop, once set, level will terminate :param gameProcess: the main process running the level. Needed to check for termination requests and the user_id :param hardware: list of started threads """ translation.activate(language) self.clearQueue() #cleanup before we start keymatrix = {} thread = threading.currentThread() glob = tlu_globals.globMgr.tlu_glob() while True: if len(keymatrix) == 16: stop_event.set() break (queueobject, breakIndicator) = self.getQueueObject(stop_event, gameProcess, thread) if breakIndicator: break if queueobject == None: continue self.queue.task_done() #release object from queue if self.checkAbort(stop_event, gameProcess, thread, queueobject): break elif queueobject.msg_num == self.MSG_KEYPRESSED: glob.lcdMessagebyline( _("Level: ") + "01", str(_("Key = ")) + str(queueobject.msg_info)) keymatrix[queueobject.msg_info] = 1 status = models.getGameState(gameProcess.user_id) status.msg = str(_("You have just pressed Key #")) + str( queueobject.msg_info) status.level_progress = int(len(keymatrix) / 16 * 100) models.setGameState(gameProcess.user_id, status) elif queueobject.msg_num == self.MSG_KEYRELEASED: pass
def checkAbort(self, stop_event, gameProcess, thread, queueobject): """ Checks the current thread, queue and message object for an indication that we shall abort. Returns True in case we have to abort :param stop_event: the event from the main-level that would be "set" here in case the level ended or terminated :param gameProcess: the main process running the level. Needed to check for termination requests and the user_id :param thread: The thread where the queue is looping in :param queueobject: the message-object that we should check here """ if stop_event.is_set(): logger.debug('Gamequeue aborted') self.set_abortmsg(gameProcess.user_id) return True elif getattr(thread, 'is_aborted', False): logger.debug('Queue-Thread shall be aborted/stopped') self.set_abortmsg(gameProcess.user_id) stop_event.set() return True elif gameProcess.exit.is_set(): logger.debug('Game-Process shall be terminated') self.set_abortmsg(gameProcess.user_id) stop_event.set() return True elif queueobject.msg_num == self.MSG_STOP: logger.debug('Gamequeue stopped via msg') self.set_abortmsg(gameProcess.user_id) stop_event.set() return True elif queueobject.msg_num == self.MSG_TIMEOUT: logger.debug('Timeout raised in queue') status = models.getGameState(gameProcess.user_id) status.msg = _("Timeout reached :(") status.result = Level.TIMEOUT status.level_progress = 100 models.setGameState(gameProcess.user_id, status) stop_event.set() return True return False
def prepareGame(self, status, queue) -> (): """Prepare Level Do hardware-preparations :param status: current state of the game, used for web-frontend :param queue: Message-Q for hardware.messages to be launched return list of hardware-processes started here """ cc = CheckCursor(queue) startThreadClass(cc) timer = Countdown(queue, 4) status.msg = str(_("Level 2 starts..")) models.setGameState(self.user_id, status) startThreadClass(timer) glob = tlu_globals.globMgr.tlu_glob() glob.lcdMessagebyline(_("Level: ") + "02", str(_("Cursorkeys"))) status.msg = str(_("Level 2 running")) status.level_progress = 0 status.level_start = timezone.now() models.setGameState(self.user_id, status) return ( timer, cc, )
def finishGame(self, status, hardware): """ Method to be overwritten by implementation. Would be called after ending the processing of the message queue Use this as a *template* only! :param status: status of the current level :param hardware: started processes to run the level, needed to terminate them """ (timer, ) = hardware if status.result != None and status.result != Level.PASSED: status.msg = str(_("Level x failed")) status.level_progress = 0 else: status.msg = str(_("Level x passed")) status.level_progress = 100 status.result = Level.PASSED status.points = 5 status.level_ended = timezone.now() models.setGameState(self.user_id, status) abortProcess(timer) logger.info('Level x State= ' + str(status)) logger.debug('Level x ended')
def checkLevel(request, level_id): """ Check that the provided level is within the allowed range. If not raises an OutOfRangeError :param request: HTTP-request :param level_id: level-number (picked from url) """ if level_id == 1: #startup level is ever ok return user = request.user try: tlu_globals.init() tlu_hardware_global.init() game = user.game except: return if game.current_level == None: if (level_id > 1): status = getGameState(user.id) status.msg = _( "You just started from the beginning, so level has to be one, please restart the game!" ) setGameState(user.id, status) raise OutOfRangeError else: return if (level_id > game.current_level.levelnum + 1) or ( level_id < game.current_level.levelnum) or game.completed(level_id): status = getGameState(user.id) status.msg = _( "The requested level is not in line with our expectations, please restart the game!" ) setGameState(user.id, status) raise OutOfRangeError
def finishGame(self, status, hardware): """End game-level-test Close down hardware-activities started :param status: current state of the game, used for web-frontend :param hardware: List of hardware-processes that should be terminated here """ (timer, ) = hardware if status.result != None and status.result == Level.TIMEOUT: #for testing purposes timeout is the desired outcome status.msg = str(_("Level00 passed")) status.level_progress = 100 status.result = Level.PASSED status.points = 5 elif status.result != None and status.result != Level.PASSED: status.msg = str(_("Level00 failed")) status.level_progress = 0 else: status.msg = str(_("Level00 passed")) status.level_progress = 100 status.result = Level.PASSED status.points = 5 status.level_ended = timezone.now() models.setGameState(self.user_id, status) abortProcess(timer)
def run(self, stop_event, gameProcess, hardware, language): """ Queue loop for level 3 Main :param stop_event: event coming from main-loop, once set, level will terminate :param gameProcess: the main process running the level. Needed to check for termination requests and the user_id :param hardware: list of started threads """ translation.activate(language) self.clearQueue() #cleanup before we start key=-1 numkeys=0 secondstiltimeout=4 thread=threading.currentThread() (timer, kbd,) = hardware # @UnusedVariable glob=tlu_globals.globMgr.tlu_glob() while True: if emulatekey and (numkeys>8): stop_event.set() break elif numkeys >= 20: stop_event.set() break if key == -1: key=randint(1,16) status=models.getGameState(gameProcess.user_id) m=str(_("You have to press Key #")) status.msg=str(numkeys)+": "+m+str(key) status.level_progress=int(numkeys/20*100) models.setGameState(gameProcess.user_id, status) timer.changeSecondsAndRestart(secondstiltimeout) (queueobject,breakIndicator)=self.getQueueObject(stop_event, gameProcess, thread) if breakIndicator: break if queueobject == None: continue self.queue.task_done() #release object from queue if self.checkAbort(stop_event,gameProcess,thread,queueobject): if queueobject.msg_num==tlu_queue.MSG_TIMEOUT: glob.lcdMessagebyline(_("Level: ")+"03", str(_("Timeout"))+" :(") break if queueobject.msg_num == self.MSG_KEYPRESSED: glob.lcdMessagebyline(_("Level: ")+"03", "#"+str(numkeys+1)+": "+str(_("Key="))+str(queueobject.msg_info)+"/"+str(key)) if key != queueobject.msg_info: status=models.getGameState(gameProcess.user_id) status.level_progress=0 status.result=Level.DIDNOTFINISH status.msg="#"+str(queueobject.msg_info)+str(_(" was the wrong key, level terminates!")) models.setGameState(gameProcess.user_id, status) logging.info("Wrong Key:"+str(key)+" instead of:"+str(queueobject.msg_info)) stop_event.set() break else: timer.pause() numkeys += 1 glob.matrixShow_symbol('root') key=-1 #generate next key status=models.getGameState(gameProcess.user_id) status.level_progress=int(numkeys/20*100) models.setGameState(gameProcess.user_id, status) logging.info("Correct key pressed :)") secondstiltimeout=4 if numkeys > 5: secondstiltimeout = 3 if numkeys > 10: secondstiltimeout = 2.5 if numkeys > 15: secondstiltimeout = 2 elif queueobject.msg_num == self.MSG_KEYRELEASED: glob.matrixShow_symbol('space')