Tyler Weaver / Mbed 2 deprecated qp_hangman

Dependencies:   TextLCD mbed qp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers host.cpp Source File

host.cpp

00001 #include "qp_port.h"
00002 #include "hangman.h"
00003 #include "bsp.h"
00004 
00005 Q_DEFINE_THIS_FILE
00006 
00007 class Host : public QActive {
00008 private:
00009     char* word;
00010     uint8_t selected_word;
00011     uint8_t num_letters;
00012     uint8_t incorrect_letters;
00013     char* used_letters;
00014 
00015     char letter;
00016     char output1[17]; // buffer for display
00017     char output2[17];
00018 
00019 public:
00020     Host();
00021 
00022 private:
00023     static QState initial(Host *me, QEvent const *e);
00024     static QState welcome(Host *me, QEvent const *e);
00025     static QState playing(Host *me, QEvent const *e);
00026 };
00027 
00028 #define BANK_SIZE   4
00029 char* const word_bank[] = { "hangmann", "global", "micro", "sensor" };
00030 char* const win_msg = "   You Win!";
00031 char* const loose_msg = "   You suck!";
00032 char* const press_play_msg = "Push to continue";
00033 
00034 
00035 // Local objects -------------------------------------------------------------
00036 static Host l_host;                                    // local Host object
00037 
00038 // Public-scope objects ------------------------------------------------------
00039 QActive * const AO_Host = &l_host;                    // "opaque" AO pointer
00040 
00041 //............................................................................
00042 Host::Host() : QActive((QStateHandler)&Host::initial) {
00043 }
00044 
00045 //............................................................................
00046 QState Host::initial(Host *me, QEvent const *e) {
00047 
00048     QS_OBJ_DICTIONARY(&l_host);
00049     QS_FUN_DICTIONARY(&QHsm::top);
00050     QS_FUN_DICTIONARY(&Host::initial);
00051     QS_FUN_DICTIONARY(&Host::playing);
00052 
00053     QS_SIG_DICTIONARY(TERMINATE_SIG, 0); // global signal
00054 
00055     QS_SIG_DICTIONARY(START_SIG, me);     // signals for Host
00056     QS_SIG_DICTIONARY(SCROLL_SIG, me);
00057     QS_SIG_DICTIONARY(SELECT_SIG, me);
00058 
00059     me->subscribe(TERMINATE_SIG);
00060 
00061     // output welcome message
00062     BSP_lcdUpdate("Push btn to play mbed hangman!","");
00063     wait(2.0);  // pause for 2 seconds
00064 
00065     return Q_TRAN(&Host::welcome);
00066 }
00067 
00068 //............................................................................
00069 QState Host::welcome(Host *me, QEvent const *e) {
00070     HostEvt *pe;
00071 
00072     switch (e->sig) {
00073         case START_SIG: {
00074             uint8_t idx;
00075 
00076             // init the game
00077             time_t seconds = time(NULL);
00078             me->selected_word = seconds % BANK_SIZE;
00079             me->word = word_bank[me->selected_word];
00080             me->num_letters = strlen(me->word);
00081             me->incorrect_letters = 0;
00082             for (int i = 0; i < 17; i++) { // clear output
00083                 me->output1[i] = ' ';
00084                 me->output2[i] = ' ';
00085             }
00086 
00087             for (idx = 0; idx < me->num_letters; idx++) {
00088                 me->output1[idx] = '_';
00089             }
00090             for (; idx < 16; idx++) {
00091                 me->output1[idx] = ' ';
00092             }
00093             me->letter = 'a';
00094             idx = 16;
00095             me->output1[idx] = me->letter;
00096             // clear output2
00097             for (idx = 0; idx < 17; idx++)
00098                 me->output2[idx] = ' ';
00099 
00100             BSP_lcdUpdate(me->output1, me->output2); // update display
00101 
00102             // post play to player
00103             pe = Q_NEW(HostEvt, PLAY_SIG);
00104             pe->scroll_pos = 0; // center
00105             QF::PUBLISH(pe, me);
00106 
00107             return Q_TRAN(&Host::playing);
00108         }
00109         case TERMINATE_SIG: {
00110             QF::stop();
00111             return Q_HANDLED();
00112         }
00113     }
00114     return Q_SUPER(&QHsm::top);
00115 }
00116 
00117 //............................................................................
00118 QState Host::playing(Host *me, QEvent const *e) {
00119 
00120     HostEvt *pe;
00121 
00122     switch (e->sig) {
00123         case SCROLL_SIG: {
00124             if (((HostEvt const *)e)->scroll_pos < 0) { // go down
00125                 if (me->letter == 'a') // wrap around
00126                     me->letter = 'z';
00127                 else
00128                     me->letter--;
00129             } else if (((HostEvt const *)e)->scroll_pos > 0) { // go up
00130                 if (me->letter == 'z') // wrap around
00131                     me->letter = 'a';
00132                 else
00133                     me->letter++;
00134             }
00135             me->output1[16] = me->letter;
00136             BSP_lcdUpdate(me->output1,me->output2);
00137 
00138             return Q_HANDLED();
00139         }
00140         case SELECT_SIG: {
00141             // test for letter in word
00142             char * pch;
00143             pch=strchr(me->word,me->letter);
00144             if (pch != NULL) { // found in word
00145                 do {
00146                     me->word[pch-me->word] = ' ';
00147                     me->output1[pch-me->word] = me->letter;
00148                     pch=strchr(pch+1,me->letter);
00149                 } while (pch!=NULL);
00150                 // update screen
00151                 BSP_lcdUpdate(me->output1,me->output2);
00152                 // test for win
00153                 if (strpbrk(me->word,"abcdefghijklmnopqrs") == NULL) { // win!
00154                     BSP_lcdScrollIn(win_msg, press_play_msg); // win msg
00155                     // post play to player
00156                     HostEvt *pe = Q_NEW(HostEvt, FINISHED_SIG);
00157                     pe->scroll_pos = 1; // win
00158                     QF::PUBLISH(pe, me);
00159 
00160                     // go to welcome state
00161                     return Q_TRAN(&Host::welcome);
00162                 }
00163             } else {
00164                 if (++me->incorrect_letters >= MAX_LETTERS) { // loose
00165                     BSP_lcdScrollIn(loose_msg, press_play_msg); // message
00166                     // post play to player
00167                     HostEvt *pe = Q_NEW(HostEvt, FINISHED_SIG);
00168                     pe->scroll_pos = 0; // loss
00169                     QF::PUBLISH(pe, me);
00170 
00171                     // go to welcome state
00172                     return Q_TRAN(&Host::welcome);
00173                 } else {
00174                     // post to used letters
00175                     me->output2[me->incorrect_letters-1] = (char)(me->letter - 33); // make uppercase
00176                     BSP_lcdUpdate(me->output1,me->output2); // update screen
00177                 }
00178             }
00179             return Q_HANDLED();
00180         }
00181         case TERMINATE_SIG: {
00182             QF::stop();
00183             return Q_HANDLED();
00184         }
00185     }
00186     return Q_SUPER(&QHsm::top);
00187 }