//*********************************************************************************************
// verifySequence_runTest()
// Tests the verifySequence state machine.
// It prints instructions to the touch-screen. The user responds by tapping the
// correct colors to match the sequence.
// Users can test the error conditions by waiting too long to tap a color or
// by tapping an incorrect color.
//*********************************************************************************************
void verifySequence_runTest()
{
    display_init();  // Always must do this.
    buttons_init();  // Need to use the push-button package so user can quit.
    int16_t sequenceLength = ONE;  // Start out with a sequence length of 1.
    verifySequence_printInstructions(sequenceLength, false);  // Tell the user what to do.
    utils_msDelay(MESSAGE_WAIT_MS);  // Give them a few seconds to read the instructions.
    simonDisplay_drawAllButtons()    // Now, draw the buttons.
    // Set the test sequence and it's length.
    globals_setSequence(verifySequence_testSequence, MAX_TEST_SEQUENCE_LENGTH);
    globals_setSequenceIterationLength(sequenceLength);
    // Enable the verifySequence state machine.
    verifySequence_enable();           // Everything is interlocked, so first enable the machine.
    while (!(buttons_read() & BTN0))// Need to hold button until it quits as you might be stuck in a delay.
    {
        // verifySequence uses the buttonHandler state machine so you need to "tick" both of them.
        verifySequence_tick();  // Advance the verifySequence state machine.
        simonbuttonHandler_tick();   // Advance the buttonHandler state machine.
        utils_msDelay(ONE_MS);       // Wait 1 ms.
        // If the verifySequence state machine has finished, check the result, otherwise just keep ticking both machines.
    if (verifySequence_isComplete())
    {
      if (verifySequence_isTimeOutError())
      {                      // Was the user too slow?
        verifySequence_printInfoMessage(user_time_out_e);         // Yes, tell the user that they were too slow.
      }
      else if (verifySequence_isUserInputError())
      {             // Did the user tap the wrong color?
        verifySequence_printInfoMessage(user_wrong_sequence_e);   // Yes, tell them so.
      }
      else
      {
        verifySequence_printInfoMessage(user_correct_sequence_e); // User was correct if you get here.
      }
      utils_msDelay(MESSAGE_WAIT_MS);                            // Allow the user to read the message.
      sequenceLength = incrementSequenceLength(sequenceLength);  // Increment the sequence.
      globals_setSequenceIterationLength(sequenceLength);  // Set the length for the verifySequence state machine.
      verifySequence_printInstructions(sequenceLength, V_ENABLED);    // Print the instructions.
      utils_msDelay(MESSAGE_WAIT_MS);                            // Let the user read the instructions.
      verifySequence_drawButtons();                              // Draw the buttons.
      verifySequence_disable();                                  // Interlock: first step of handshake.
      verifySequence_tick();                                     // Advance the verifySequence machine.
      utils_msDelay(ONE_MS);                                          // Wait for 1 ms.
      verifySequence_enable();                                   // Interlock: second step of handshake.
      utils_msDelay(ONE_MS);                                          // Wait 1 ms.
    }
  }
  verifySequence_printInfoMessage(user_quit_e);  // Quitting, print out an informational message.
}
Beispiel #2
0
// I used a busy-wait delay (utils_msDelay) that uses a for-loop and just blocks until the time has passed.
// When you implement the game, you CANNOT use this function as we discussed in class. Implement the delay
// using the non-blocking state-machine approach discussed in class.
void simonDisplay_runTest(uint16_t touchCount) {
  display_init();  // Always initialize the display.
  char str[MAX_STR];   // Enough for some simple printing.
  uint8_t regionNumber;
  uint16_t touches = 0;
  // Write an informational message and wait for the user to touch the LCD.
  display_fillScreen(DISPLAY_BLACK);        // clear the screen.
  display_setCursor(0, display_height()/2); //
  display_setTextSize(TEXT_SIZE);
  display_setTextColor(DISPLAY_RED, DISPLAY_BLACK);
  sprintf(str, "Touch and release to start the Simon demo.");
  display_println(str);
  display_println();
  sprintf(str, "Demo will terminate after %d touches.", touchCount);
  display_println(str);
  while (!display_isTouched());       // Wait here until the screen is touched.
  while (display_isTouched());        // Now wait until the touch is released.
  display_fillScreen(DISPLAY_BLACK);  // Clear the screen.
  simonDisplay_drawAllButtons();      // Draw all of the buttons.
  bool touched = false;  	      // Keep track of when the pad is touched.
  int16_t x, y;  		      // Use these to keep track of coordinates.
  uint8_t z;      		      // This is the relative touch pressure.
  while (touches < touchCount) {  // Run the loop according to the number of touches passed in.
    if (!display_isTouched() && touched) {         // user has stopped touching the pad.
      simonDisplay_drawSquare(regionNumber, true); // Erase the square.
      simonDisplay_drawButton(regionNumber);	   // DISPLAY_REDraw the button.
      touched = false;															// Released the touch, set touched to false.
    } else if (display_isTouched() && !touched) {   // User started touching the pad.
      touched = true;                               // Just touched the pad, set touched = true.
      touches++;  																	// Keep track of the number of touches.
      display_clearOldTouchData();  // Get rid of data from previous touches.
      // Must wait this many milliseconds for the chip to do analog processing.
      utils_msDelay(TOUCH_PANEL_ANALOG_PROCESSING_DELAY_IN_MS);
      display_getTouchedPoint(&x, &y, &z);                  // After the wait, get the touched point.
      regionNumber = simonDisplay_computeRegionNumber(x, y);// Compute the region number.
      simonDisplay_drawSquare(regionNumber, false);	    // Draw the square (erase = false).
    }
  }
  // Done with the demo, write an informational message to the user.
  display_fillScreen(DISPLAY_BLACK);        // clear the screen.
  display_setCursor(0, display_height()/2); // Place the cursor in the middle of the screen.
  display_setTextSize(2);                   // Make it readable.
  display_setTextColor(DISPLAY_RED, DISPLAY_BLACK);  // red is foreground color, black is background color.
  sprintf(str, "Simon demo terminated");    // Format a string using sprintf.
  display_println(str);                     // Print it to the LCD.
  sprintf(str, "after %d touches.", touchCount);  // Format the rest of the string.
  display_println(str);  // Print it to the LCD.
}
Beispiel #3
0
// Just clears the screen and draws the four buttons used in Simon.
void verifySequence_drawButtons() {
	display_fillScreen(DISPLAY_BLACK);
	simonDisplay_drawAllButtons();  // Draw the four buttons.
}
Beispiel #4
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;
        }

    }