예제 #1
0
 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,
     )
예제 #2
0
 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")
예제 #3
0
 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)
예제 #4
0
 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)
예제 #5
0
        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
예제 #6
0
 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, )
예제 #7
0
 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, )
예제 #8
0
    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
예제 #9
0
 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')
예제 #10
0
 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
예제 #11
0
 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
예제 #12
0
 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
예제 #13
0
 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,
     )
예제 #14
0
 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')
예제 #15
0
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
예제 #16
0
 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)
예제 #17
0
 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')