Marc Bax / Mbed 2 deprecated Flexbook180111a

Dependencies:   SDFileSystem app epson mbed msp430 pl tests

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hangman.cpp Source File

hangman.cpp

00001 
00002 
00003 #include "log.h"
00004 #include "hangman.h"
00005 #include "eink.h"
00006 #include "mbed.h"
00007 #include "SDFileSystem.h"
00008 
00009 namespace Flexbook
00010 {
00011 
00012 HangmanGame::HangmanGame()
00013 : finished(false), currentpos(13), oldpos(13),
00014   alphabet(), word(""), guessed(""),
00015   wordlength(0), hangstage(0)
00016 {
00017     Log("Creating hangman game");
00018     
00019     // Display the game welcome screen
00020      WriteImage("/base.pgm");
00021     DrawMan(0);
00022     UpdateDisplay();
00023     
00024     // Fill the array to indicate none of the letters has been used
00025     for (int i=0; i<27; i++)
00026     {
00027         alphabet[i]=false;
00028         }
00029         
00030     // Pick a random word from the hangdict.txt file, update *word, and return the number of characters
00031     wordlength = ReturnWord(*word);
00032     
00033     //Change the word string so that "A" is 0, "M"=12, "N"=14 and "Z"=26
00034     for (int i=0; i<wordlength; i++)
00035     {
00036         word[i] = word[i] - 65;
00037         if (word[i] > 12) word[i] = word[i] + 1;
00038         guessed[i]=13;
00039         printf(" %u", word[i]);
00040         }
00041         
00042     // Display the game start screen
00043     printf("\n");
00044     DrawWord(guessed, wordlength);
00045     
00046 }
00047 
00048 HangmanGame::~HangmanGame()
00049 {
00050     Log("deleting hangmangame");
00051 }
00052 
00053 // Function returning x-position of "letterpos" on the alphabet matrix
00054 int HangmanGame::Xpos(const char letterpos)
00055 {
00056     int result;
00057     result = 155 + ((letterpos%9)*25);
00058     printf("xpos = %u, ", result);
00059     return(result);
00060 }
00061 
00062 // Function returning y-position of "letterpos" on the alphabet matrix
00063 int HangmanGame::Ypos(const char letterpos)
00064 {
00065     int result;
00066     result = 21 + ((letterpos/9)*30);
00067     printf("ypos = %u\n", result);
00068     return(result);
00069 }
00070 
00071 // routine that redraws the alphabet matrix after a cursor move
00072 void HangmanGame::RedrawAlphabet(const char newpos, const char oldpos, const bool alphabet[27])
00073 {  
00074     Log("redrawing newpos");
00075     if (alphabet[newpos])
00076         {
00077         //writeimage of newpos letter greyed inverted
00078         printf("writing %u grey inverted\n", newpos);
00079         WritePartImage("/agi.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28);
00080         }
00081         else
00082             {
00083             //writeimage of newpos letter inverted
00084             printf("writing %u inverted\n", newpos);
00085             WritePartImage("/ai.pgm", 230, 51, 300, 0, 24, 28);
00086             //WritePartImage("/ai.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28);
00087             }
00088     Log("redrawing oldpos");
00089     if (alphabet[oldpos])
00090         {
00091         //writeimage of oldpos letter greyed out
00092         printf("writing %u greyed\n", oldpos);
00093         WritePartImage("/ag.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28);
00094         }
00095         else
00096             {
00097             //writeimage of oldpos letter normal
00098             printf("writing %u normal\n", oldpos);
00099             WritePartImage("/an.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28);
00100             }
00101     // redraw the alphabet matrix based on a cursor move
00102     UpdateDisplay();
00103 }
00104 
00105 //function to count number of eligible words in the dictionary file
00106 int HangmanGame::NumDictWords()
00107 {
00108     FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r");
00109     if (fp1 == NULL) {
00110         printf("Could not open hangdict.txt\n");
00111         }
00112         else {
00113             printf("hangdict.txt opened\n");
00114             }
00115     int wordcount = 0;
00116     int wordlength = 0;
00117     int ch;
00118     while (EOF != (ch = getc(fp1))) {
00119         // check if character is an LF. If the word on that line is the right length, increment word counter
00120         if (ch == 10) {
00121             if ((wordlength > 7) && (wordlength < 15)) {
00122                 wordcount = wordcount + 1;
00123                 }
00124                 wordlength = 0;
00125             }
00126         else {
00127             // if the character is not an LF, increment character count
00128             wordlength = wordlength + 1;
00129             }
00130         }
00131     fclose(fp1);
00132     printf("Word count: %u\n", wordcount);
00133     return wordcount;
00134 }
00135 
00136 // routine to draw the current guess of the word on the display
00137 void HangmanGame::DrawWord(const char guessed[14], const char wordlength)
00138 {
00139     for (int i = 0; i < wordlength; i++) {
00140         WritePartImage("/an.pgm", 380-(25*(wordlength-i)), 191, guessed[i]*25, 0, 24, 28);
00141         }
00142     UpdateDisplay();
00143 }
00144 
00145 // routine to redraw the hanging man
00146 void HangmanGame::DrawMan(const char manstate)
00147 {
00148     switch (manstate)
00149     {       
00150         case 0:
00151             WritePartImage("/man0.pgm", 35, 0, 0, 0, 74, 174);
00152             break;
00153             
00154         case 1:
00155             WritePartImage("/man1.pgm", 35, 0, 0, 0, 74, 174);
00156             break;
00157             
00158         case 2:
00159             WritePartImage("/man2.pgm", 35, 0, 0, 0, 74, 174);
00160             break;
00161             
00162         case 3:
00163             WritePartImage("/man3.pgm", 35, 0, 0, 0, 74, 174);
00164             break;
00165             
00166         case 4:
00167             WritePartImage("/man4.pgm", 35, 0, 0, 0, 74, 174);
00168             break;
00169             
00170         case 5:
00171             WritePartImage("/man5.pgm", 35, 0, 0, 0, 74, 174);
00172             break;
00173             
00174         case 6:
00175             WritePartImage("/man6.pgm", 35, 0, 0, 0, 74, 174);
00176             break;
00177     }
00178 }                                                          
00179 
00180 // routine that picks a new word to guess, and returns the number of characters in the word
00181 char HangmanGame::ReturnWord(char &word2guess)
00182 {
00183     //pick a random word from the hangdict.txt file
00184     int wordindex = rand()%HangmanGame::NumDictWords();
00185     FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r");
00186     printf("Returning word: %u\n", wordindex);
00187     for (int i = 0; i < wordindex; i++) {
00188         fgets(&word2guess, 24, fp1);
00189         while ((strlen(&word2guess) < 10) || (strlen(&word2guess) > 16)) {
00190             fgets(&word2guess, 24, fp1);
00191         }
00192     }
00193     printf("%s - length %u characters\n", &word2guess, strlen(&word2guess)-2);
00194     fclose(fp1);
00195     return (strlen(&word2guess)-2);
00196 }
00197 
00198 // routine to move the cursor on the alphabet matrix when a nav button is pressed
00199 // navbuttons: up=10; right=6; down=7; left=9; (select=8; cancel=5;)
00200 char HangmanGame::MoveCursor(const bool alphabet[27], const char buttonnumber, char oldpos)
00201 {
00202     char newpos;
00203     printf("%u, ", oldpos);
00204     switch (buttonnumber)
00205     {
00206         case 10:
00207             if (oldpos > 8)
00208                 newpos = oldpos-9;
00209                 else newpos=oldpos;
00210                 break;    
00211             
00212         case 7:
00213             if (oldpos < 18)
00214                 newpos = oldpos+9;
00215                 else newpos=oldpos;
00216                 break;
00217             
00218         case 9:
00219             if ((oldpos == 0) || (oldpos == 9) || (oldpos == 18))
00220                 newpos=oldpos;
00221                 else newpos=oldpos-1;
00222                 break;
00223                 
00224         case 6:
00225             if ((oldpos == 8) || (oldpos == 17) || (oldpos == 26))
00226                 newpos=oldpos;
00227                 else newpos=oldpos+1;
00228                 break;
00229                 
00230         default:
00231             newpos=13;
00232         }
00233     printf("%u\n", newpos);
00234     if (newpos != oldpos) RedrawAlphabet(newpos, oldpos, alphabet);
00235     Log("alphabet redrawn");
00236     oldpos = newpos;
00237     return(newpos);
00238 }
00239 
00240 // routine called when a letter is selected - unfinished work in progress
00241 bool HangmanGame::SelectLetter(const char letterpos, const char word2guess[14], const char wordlength, char* guessed[14], char hangmanstate)
00242 {
00243     bool goodguess = false;
00244     // If the word contains the selected letter, update the guess
00245     for (int i=0; i < wordlength; i++)
00246     {
00247         if (word2guess[i]==letterpos)
00248         {
00249             *guessed[i]=letterpos;
00250             goodguess = true;
00251             }
00252         }
00253     // If guess is correct, update the displayed word
00254     if (goodguess)
00255     {
00256         DrawWord(*guessed, wordlength);
00257     }
00258     
00259     // If the guess was wrong, hang the next segment of the man
00260     if (!goodguess)
00261     {
00262         hangmanstate = hangmanstate+1;
00263         DrawMan(hangmanstate);
00264     }
00265         
00266     //body
00267     UpdateDisplay();
00268     // The return value is false if the game is not finished yet, and true if the word is guessed or the man is hung
00269     if ((hangmanstate==6) || (word2guess==*guessed))
00270     {
00271         return(true);
00272         }
00273         else return (false);
00274 }
00275 
00276 }