//*********************************************************************************************
// verifySequence_tick()
// verify sequence state machine
//*********************************************************************************************
void verifySequence_tick()
{
	switch(verify_state)
	{

    //verify_init
    //Resets all error cases and sets all timers to zero
    //Gets the current sequence length
    //enables the button handler
	case verify_init:
		verify_isTimeOutError = V_DISABLED;
		verify_isUserInputError = V_DISABLED;
		verify_completed = V_DISABLED;
		timer_waiting = INIT_ZERO;
		verifyValue = INIT_ZERO;
            
		verify_current_sequence_length = globals_getSequenceIterationLength();

		if(verify_enable)
		{
			simonbuttonHandler_enable();
			verify_state = verify_waiting;
		}
		break;

            
    //verify_waiting
    //provides the user with time to touch the screen
    //if the user does not touch before TIMER_EXPIRED_VALUE, verify_isTimeOutError occurs
    //disables the button handler after waiting is over
	case verify_waiting:
        timer_waiting++;
        if(timer_waiting == TIMER_EXPIRED_VALUE)
        {
            verify_isTimeOutError = V_ENABLED;
            simonbuttonHandler_disable();

            verify_state = verify_complete;
        }

        if(display_isTouched())
        {
            if(!simonbuttonHandler_releaseDetected() && timer_waiting < TIMER_EXPIRED_VALUE)
            {
                verify_state = verify_wait_release;
            }
        }
        break;

            
    //verify_wait_release
    //waits for the user to release the touch screen and disables the button handler
	case verify_wait_release:

        if(simonbuttonHandler_releaseDetected())
        {
            simonRegion = simonbuttonHandler_getRegionNumber();
            timer_waiting = INIT_ZERO;
            simonbuttonHandler_disable();
               
            verify_state = verify_validate;
        }
        break;


    //verify_validate
    //compares the verifyValue to the sequence value to see if the sequence is over
    //if they are not the same, user input error has occurred
    case verify_validate:

        if(simonRegion == globals_getSequenceValue(verifyValue))
        {
            verifyValue++;
            if(verifyValue == verify_current_sequence_length)
            {
                verifyValue = INIT_ZERO;
                verify_state = verify_complete;
            }
                
            else
            {
                timer_waiting = INIT_ZERO;
                verify_state = verify_waiting;
                simonbuttonHandler_enable();
            }
        }
            
        else
        {
            verify_isUserInputError = V_ENABLED;
            verify_state = verify_complete;
        }
        break;


    //verify_complete
    //signifies the state machine has completed
    //restarts if and only if the state machine is enabled
    case verify_complete:

        verify_completed = V_ENABLED;
        timer_waiting = INIT_ZERO;

        if(verify_enable)
        {
            verify_state = verify_init;
        }
        break;


	default:
            verify_state = verify_init;
            break;
	}
}
Beispiel #2
0
    void simonControl_tick()
    {
        SC_debugStatePrint();


        /// //ACTIONS***********************************************************************
        switch(SC_State)
        {
        case SC_init_st:
            //do nothing
            break;
        case SC_instructions_st:
            display_setTextColor(DISPLAY_WHITE);
            display_setCursor(SC_INSTRUCTION_CURSORX,SC_INSTRUCTION_CURSORY);
            display_setTextSize(SC_INSTRUCTION_TEXTSIZE);
            display_println(SC_INSTRUCTIONS);
            break;
        case SC_wait_first_touch_st:
            // do nothing
            break;
        case SC_get_sequence_st:
            SC_currentScore = 0; //reset
            SC_setSequence();
            break;
        case SC_flash_sequence_st:
            //do nothing
            break;
        case SC_verify_sequence_st:
            //do nothing
            break;
        case SC_error_st:
            errorTimer++;
            if (verifySequence_isTimeOutError()) // user didn't press
            {
                display_setTextSize(SC_TEXTSIZE);
                display_println(ERROR_MESSAGE_TIMEOUT);
            }
            else if (verifySequence_isUserInputError()) //pressed wrong input
            {
                display_setTextSize(SC_TEXTSIZE);
                display_println(ERROR_MESSAGE_INPUT);
            }
            verifySequence_disable(); //set this here so we can read these flags. disable resets the error flags
            break;
        case SC_print_score_st:
            sprintf(maxScoreString, SC_HIGHSCORE_MESSAGE, SC_maxScore);
            display_setTextSize(SC_TEXTSIZE); //decrease text size
            display_println(maxScoreString);
            //reset scores, index, and sequence
            SC_currentIndex = 1; //reset to 1. since this is sequence length, when we setSequence, don't put to zero
            SC_maxScore = 0; //reset
            errorTimer = 0; //reset timer
            lvlMessageTimer = 0;
            break;
        case SC_level_complete_st:
            lvlMessageTimer++;
            if(printFlag) //set a flag so it doesn't keep being printed
            {
                display_println(SC_LVL_MESSAGE);
                printFlag = false; //switch flag
            }
            break;
        default:
            printf(SC_ERROR_MESSAGE); //invalid state
            break;
        }


        //TRANSITIONS***********************************************************************
        switch(SC_State)
        {
        case SC_init_st:
            SC_State = SC_instructions_st; //just go to instructions
            break;
        case SC_instructions_st:
            SC_State = SC_wait_first_touch_st; //go wait after drawing.
            break;
        case SC_wait_first_touch_st:
            if (display_isTouched()) //if touched, move ahead
            {
                SC_State = SC_get_sequence_st;
                display_fillScreen(DISPLAY_BLACK); //clear screen of instructions
            }
            break;
        case SC_get_sequence_st:
            SC_State = SC_flash_sequence_st;
            flashSequence_enable();
            break;
        case SC_flash_sequence_st:
            if (flashSequence_completed())
            {
                SC_State = SC_verify_sequence_st; //go to verify
                flashSequence_disable(); //disable flash machine
                simonDisplay_drawAllButtons(); //draw the buttons upon exit
                verifySequence_enable();
            }
            break;
        case SC_verify_sequence_st:
            if (verifySequence_isComplete()) //done verifying
            {
                //if there a time out error or wrong input error
                if (verifySequence_isTimeOutError() || verifySequence_isUserInputError()) //no errors
                {
                    SC_State = SC_error_st;
                    display_fillScreen(DISPLAY_BLACK); //clear buttons off screen
                }
                //level complete
                else if (globals_getSequenceIterationLength() == SC_sequence_length)
                {
                    SC_sequence_length++;
                    SC_State = SC_level_complete_st;
                    verifySequence_disable();
                    display_fillScreen(DISPLAY_BLACK); //clear buttons off screen
                    SC_currentIndex = 1; //reset
                    SC_maxScore = SC_currentScore;
                }
                else
                {
                    SC_State = SC_flash_sequence_st;
                    flashSequence_enable();
                    SC_currentIndex++; //how many to flash?
                    globals_setSequenceIterationLength(SC_currentIndex); //udate how many to falsh
                    verifySequence_disable();
                    display_fillScreen(DISPLAY_BLACK); //clear buttons off screen
                    SC_currentScore++;
                    if (SC_currentScore > SC_maxScore) //before first level is complete, maxScore doesn't get set
                    {
                        SC_maxScore = SC_currentScore; //this mostly before first level is complete
                    }
                }
            }
            break;
        case SC_error_st:
            if (errorTimer >= SC_ERROR_EXPIRE)
            {
                SC_State = SC_print_score_st; //print highest score
                display_fillScreen(DISPLAY_BLACK);
            }

            break;
        case SC_print_score_st:
            SC_State = SC_instructions_st;
            SC_maxScore = 0; //reset the maxScore!
            sequenceSeed++; //change the seed
            break;
        case SC_level_complete_st:
            if (lvlMessageTimer > SC_LVL_MESSAGE_EXPIRE) //timed out
            {
                SC_State = SC_print_score_st;
            }
            else if (display_isTouched())
            {
                SC_State = SC_instructions_st;
                display_fillScreen(DISPLAY_BLACK); // clear screen
                sequenceSeed++; //change the seed
                printFlag = true; //rest print flag
            }
            break;
        default:
            printf(SC_ERROR_MESSAGE);
            break;
        }

    }
Beispiel #3
0
void verifySequence_tick() {
  static uint16_t index = 0;
  static uint16_t timeOutTimer = 0; // counter to track whether a timeout occurs

  /////////////////////////////////
  // Perform state action first. //
  /////////////////////////////////
  switch (verifySequence_state) {
    case init_st:
      isTimeOutError = false;
      isUserInputError = false;
      index = 0;
      timeOutTimer = 0;
      break;
    case wait_for_timeout_st:
      timeOutTimer++;
      buttonHandler_enable();
      break;
    case wait_for_release_st:
      break;
    case verification_st:
      break;

    case complete_st:

      break;
    default:
      printf("Default case hit in verifySequence tick.\n");
      break;
  }

  ////////////////////////////////
  // Perform state update next. //
  ////////////////////////////////
  switch (verifySequence_state) {
    case init_st:
      if (enabled) {
        buttonHandler_enable();
        verifySequence_state = wait_for_timeout_st;
      }
      else {
        verifySequence_state = init_st;
      }
      break;
    case wait_for_timeout_st:
      if(display_isTouched()) {
        timeOutTimer = 0;
        verifySequence_state = wait_for_release_st;
      }
      // If the use waits too long before doing anything
      else if (timeOutTimer >= WAIT_TIMEOUT)
      {
        //printf("userTouchTimer: %d", userTouchTimer);
        isTimeOutError = true;
        timeOutTimer = 0;
        verifySequence_state = complete_st;
      }
      else {
        verifySequence_state = wait_for_timeout_st;
      }
      break;
    case wait_for_release_st:
      if (buttonHandler_releaseDetected())
      {
        buttonHandler_disable();
        verifySequence_state = verification_st;
      }
      else {
        verifySequence_state = wait_for_release_st;
      }
      break;
    case verification_st:
      uint8_t tempSequenceValue, tempRegionNumber;
      tempSequenceValue = globals_getSequenceValue(index);
      tempRegionNumber = buttonHandler_getRegionNumber();

      if(tempSequenceValue == tempRegionNumber) { //user touched the correct square
        // If that was the last square
        if (globals_getSequenceIterationLength() == (index + 1)) { //because index starts at 0 and length at 1
          verifySequence_state = complete_st;
        }
        else {
          index++;
          verifySequence_state = wait_for_timeout_st;
        }
      }
      else {
        isUserInputError = true;
        //printf("USER INPUT ERROR");
        verifySequence_state = complete_st;
      }
      break;
    case complete_st:
      if (!enabled) {
        verifySequence_state = init_st;
      }
      else {
        verifySequence_state = complete_st;
      }
      break;
    default:
      printf("Default case hit in verifySequence tick.\n");
      break;
  }
}
Beispiel #4
0
// Standard tick function.
void verifySequence_tick(){
    // state actions
    switch (verifyState){
    case init_st:
        break;
    case enable_button_st:
        // enabble the buttonHandler state machine
        buttonHandler_enable();
        break;
    case wait_for_release_st:
        // Increment timout value while waiting for the display to be relased
        timeOut++;
        break;
    case verify_region_st:
        // disable the buttonhandler state machine
        buttonHandler_disable();
        // if the user tapped the wrong sequence, raise the errorFlag
        if (globals_getSequenceValue(index) != buttonHandler_getRegionNumber()){
            userErrorFlag = 1;
        }
        break;
    case increment_st:
        break;
    case done_st:
        break;
    }

    // state transitions
    switch (verifyState){
    case init_st:
        // wait for the state machine to be enabled
        if (verifyEnableFlag) {
            // reset all flags and counters
            index = 0;
            completeFlag = 0;
            timeOutFlag = 0;
            userErrorFlag = 0;
            timeOut = 0;
            verifyState = enable_button_st;
        }
        break;
    case enable_button_st:
        verifyState = wait_for_release_st;
        break;
    case wait_for_release_st:
        // if the timout value is reached
        if (timeOut == TIME_OUT_VALUE){
            // raise the timeOutFlag
            timeOutFlag = 1;
            // raise the completeFlag
            completeFlag = 1;
            // erase all the buttons
            simonDisplay_eraseAllButtons();
            // and go to done
            verifyState = done_st;
        }
        // if the display is currently touched, reset the counter.
        // I didn't want it to timeout if the user is holding the buton.
        else if (display_isTouched()){
            timeOut = 0;
        }
        // otherwise if the display was released
        else if (buttonHandler_releaseDetected()){
            // go check the region pressed against the reion in the sequence
            verifyState = verify_region_st;
        }
        break;
    case verify_region_st:
        verifyState = increment_st;
        break;
    case increment_st:
        // if we're at the end of the sequence
        if (index == (globals_getSequenceIterationLength())){
            // raise completeFlag to indicate it's over
            completeFlag = 1;
            // erase all the buttons
            simonDisplay_eraseAllButtons();
            // go to done
            verifyState = done_st;
        }
        // if the user made an error
        else if (userErrorFlag){
            // raise completeFlag
            completeFlag = 1;
            // erase the buttons
            simonDisplay_eraseAllButtons();
            // go to done
            verifyState = done_st;
        }
        else {
            // otherwise increase the index and verify the next button
            // in the sequence
            index++;
            verifyState = enable_button_st;
        }
        break;
    case done_st:
        // if the enable flag goes low
        if (!verifyEnableFlag) {
            // go to init
            verifyState = init_st;
        }
        break;
    }
}