Tyler Weaver
/
qp_hangman
Hangman game using qp a 16x2 LCD and joystick.
Diff: host.cpp
- Revision:
- 0:1521c946a57b
- Child:
- 1:4efaebc256d3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/host.cpp Wed Feb 08 22:20:11 2012 +0000 @@ -0,0 +1,185 @@ +#include "qp_port.h" +#include "hangman.h" +#include "bsp.h" + +class Host : public QActive { +private: + char* word; + uint8_t selected_word; + uint8_t num_letters; + uint8_t incorrect_letters; + char* used_letters; + + char letter; + char output1[17]; // buffer for display + char output2[17]; + +public: + Host(); + +private: + static QState initial(Host *me, QEvent const *e); + static QState welcome(Host *me, QEvent const *e); + static QState playing(Host *me, QEvent const *e); +}; + +#define BANK_SIZE 4 +char* const word_bank[] = { "hangmann", "global", "micro", "sensor" }; +char* const win_msg = " You Win!"; +char* const loose_msg = " You suck!"; +char* const press_play_msg = "Push to continue"; + + +// Local objects ------------------------------------------------------------- +static Host l_host; // local Host object + +// Public-scope objects ------------------------------------------------------ +QActive * const AO_Host = &l_host; // "opaque" AO pointer + +//............................................................................ +Host::Host() : QActive((QStateHandler)&Host::initial) { +} + +//............................................................................ +QState Host::initial(Host *me, QEvent const *e) { + + QS_OBJ_DICTIONARY(&l_host); + QS_FUN_DICTIONARY(&QHsm::top); + QS_FUN_DICTIONARY(&Host::initial); + QS_FUN_DICTIONARY(&Host::playing); + + QS_SIG_DICTIONARY(TERMINATE_SIG, 0); // global signal + + QS_SIG_DICTIONARY(START_SIG, me); // signals for Host + QS_SIG_DICTIONARY(SCROLL_SIG, me); + QS_SIG_DICTIONARY(SELECT_SIG, me); + + me->subscribe(TERMINATE_SIG); + + // output welcome message + BSP_lcdUpdate("Push btn to play mbed hangman!",""); + wait(2.0); // pause for 2 seconds + + return Q_TRAN(&Host::welcome); +} + +//............................................................................ +QState Host::welcome(Host *me, QEvent const *e) { + HostEvt *pe; + + switch (e->sig) { + case START_SIG: { + uint8_t idx; + + // init the game + time_t seconds = time(NULL); + me->selected_word = seconds % BANK_SIZE; + me->word = word_bank[me->selected_word]; + me->num_letters = strlen(me->word); + me->incorrect_letters = 0; + for (int i = 0; i < 17; i++) { // clear output + me->output1[i] = ' '; + me->output2[i] = ' '; + } + + for (idx = 0; idx < me->num_letters; idx++) { + me->output1[idx] = '_'; + } + for (; idx < 16; idx++) { + me->output1[idx] = ' '; + } + me->letter = 'a'; + idx = 16; + me->output1[idx] = me->letter; + // clear output2 + for (idx = 0; idx < 17; idx++) + me->output2[idx] = ' '; + + BSP_lcdUpdate(me->output1, me->output2); // update display + + // post play to player + pe = Q_NEW(HostEvt, PLAY_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + return Q_TRAN(&Host::playing); + } + case TERMINATE_SIG: { + QF::stop(); + return Q_HANDLED(); + } + } + return Q_SUPER(&QHsm::top); +} + +//............................................................................ +QState Host::playing(Host *me, QEvent const *e) { + + HostEvt *pe; + + switch (e->sig) { + case SCROLL_SIG: { + if (((HostEvt const *)e)->scroll_pos < 0) { // go down + if (me->letter == 'a') // wrap around + me->letter = 'z'; + else + me->letter--; + } else if (((HostEvt const *)e)->scroll_pos > 0) { // go up + if (me->letter == 'z') // wrap around + me->letter = 'a'; + else + me->letter++; + } + me->output1[16] = me->letter; + BSP_lcdUpdate(me->output1,me->output2); + + return Q_HANDLED(); + } + case SELECT_SIG: { + // test for letter in word + char * pch; + pch=strchr(me->word,me->letter); + if (pch != NULL) { // found in word + do { + me->word[pch-me->word] = ' '; + me->output1[pch-me->word] = me->letter; + pch=strchr(pch+1,me->letter); + } while (pch!=NULL); + // update screen + BSP_lcdUpdate(me->output1,me->output2); + // test for win + if (strpbrk(me->word,"abcdefghijklmnopqrs") == NULL) { // win! + BSP_lcdScrollIn(win_msg, press_play_msg); // win msg + // post play to player + HostEvt *pe = Q_NEW(HostEvt, WIN_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + // go to welcome state + return Q_TRAN(&Host::welcome); + } + } else { + if (++me->incorrect_letters >= MAX_LETTERS) { // loose + BSP_lcdScrollIn(loose_msg, press_play_msg); // message + // post play to player + HostEvt *pe = Q_NEW(HostEvt, WIN_SIG); + pe->scroll_pos = 0; // center + QF::PUBLISH(pe, me); + + // go to welcome state + return Q_TRAN(&Host::welcome); + } else { + // post to used letters + me->output2[me->incorrect_letters-1] = (char)(me->letter - 33); // make uppercase + BSP_lcdUpdate(me->output1,me->output2); // update screen + } + } + return Q_HANDLED(); + } + case TERMINATE_SIG: { + QF::stop(); + return Q_HANDLED(); + } + } + return Q_SUPER(&QHsm::top); +}