Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SDFileSystem app epson mbed msp430 pl tests
hangman.cpp@0:c643d398cdb6, 2018-01-11 (annotated)
- Committer:
- marcbax
- Date:
- Thu Jan 11 13:42:27 2018 +0000
- Revision:
- 0:c643d398cdb6
- Child:
- 1:5874c1a074a7
Marc Bax version 180111. It hangs on the WritePartImage in the RedrawAlphabet routine in hangman.cpp. Within that call it does execute Ypos(), but not Xpos().
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| marcbax | 0:c643d398cdb6 | 1 | |
| marcbax | 0:c643d398cdb6 | 2 | |
| marcbax | 0:c643d398cdb6 | 3 | #include "log.h" |
| marcbax | 0:c643d398cdb6 | 4 | #include "hangman.h" |
| marcbax | 0:c643d398cdb6 | 5 | #include "eink.h" |
| marcbax | 0:c643d398cdb6 | 6 | #include "mbed.h" |
| marcbax | 0:c643d398cdb6 | 7 | #include "SDFileSystem.h" |
| marcbax | 0:c643d398cdb6 | 8 | |
| marcbax | 0:c643d398cdb6 | 9 | namespace Flexbook |
| marcbax | 0:c643d398cdb6 | 10 | { |
| marcbax | 0:c643d398cdb6 | 11 | |
| marcbax | 0:c643d398cdb6 | 12 | HangmanGame::HangmanGame() |
| marcbax | 0:c643d398cdb6 | 13 | : finished(false), currentpos(13), oldpos(13), |
| marcbax | 0:c643d398cdb6 | 14 | alphabet(), word(""), guessed(""), |
| marcbax | 0:c643d398cdb6 | 15 | wordlength(0), hangstage(0) |
| marcbax | 0:c643d398cdb6 | 16 | { |
| marcbax | 0:c643d398cdb6 | 17 | Log("Creating hangman game"); |
| marcbax | 0:c643d398cdb6 | 18 | |
| marcbax | 0:c643d398cdb6 | 19 | // Display the game welcome screen |
| marcbax | 0:c643d398cdb6 | 20 | WriteImage("/base.pgm"); |
| marcbax | 0:c643d398cdb6 | 21 | DrawMan(0); |
| marcbax | 0:c643d398cdb6 | 22 | UpdateDisplay(); |
| marcbax | 0:c643d398cdb6 | 23 | |
| marcbax | 0:c643d398cdb6 | 24 | // Fill the array to indicate none of the letters has been used |
| marcbax | 0:c643d398cdb6 | 25 | for (int i=0; i<27; i++) |
| marcbax | 0:c643d398cdb6 | 26 | { |
| marcbax | 0:c643d398cdb6 | 27 | alphabet[i]=false; |
| marcbax | 0:c643d398cdb6 | 28 | } |
| marcbax | 0:c643d398cdb6 | 29 | |
| marcbax | 0:c643d398cdb6 | 30 | // Pick a random word from the hangdict.txt file, update *word, and return the number of characters |
| marcbax | 0:c643d398cdb6 | 31 | wordlength = ReturnWord(*word); |
| marcbax | 0:c643d398cdb6 | 32 | |
| marcbax | 0:c643d398cdb6 | 33 | //Change the word string so that "A" is 0, "M"=12, "N"=14 and "Z"=26 |
| marcbax | 0:c643d398cdb6 | 34 | for (int i=0; i<wordlength; i++) |
| marcbax | 0:c643d398cdb6 | 35 | { |
| marcbax | 0:c643d398cdb6 | 36 | word[i] = word[i] - 65; |
| marcbax | 0:c643d398cdb6 | 37 | if (word[i] > 12) word[i] = word[i] + 1; |
| marcbax | 0:c643d398cdb6 | 38 | guessed[i]=13; |
| marcbax | 0:c643d398cdb6 | 39 | printf(" %u", word[i]); |
| marcbax | 0:c643d398cdb6 | 40 | } |
| marcbax | 0:c643d398cdb6 | 41 | |
| marcbax | 0:c643d398cdb6 | 42 | // Display the game start screen |
| marcbax | 0:c643d398cdb6 | 43 | printf("\n"); |
| marcbax | 0:c643d398cdb6 | 44 | DrawWord(guessed, wordlength); |
| marcbax | 0:c643d398cdb6 | 45 | |
| marcbax | 0:c643d398cdb6 | 46 | } |
| marcbax | 0:c643d398cdb6 | 47 | |
| marcbax | 0:c643d398cdb6 | 48 | HangmanGame::~HangmanGame() |
| marcbax | 0:c643d398cdb6 | 49 | { |
| marcbax | 0:c643d398cdb6 | 50 | Log("deleting hangmangame"); |
| marcbax | 0:c643d398cdb6 | 51 | } |
| marcbax | 0:c643d398cdb6 | 52 | |
| marcbax | 0:c643d398cdb6 | 53 | // Function returning x-position of "letterpos" on the alphabet matrix |
| marcbax | 0:c643d398cdb6 | 54 | int HangmanGame::Xpos(const char letterpos) |
| marcbax | 0:c643d398cdb6 | 55 | { |
| marcbax | 0:c643d398cdb6 | 56 | int result; |
| marcbax | 0:c643d398cdb6 | 57 | result = 155 + ((letterpos%9)*25); |
| marcbax | 0:c643d398cdb6 | 58 | printf("xpos = %u, ", result); |
| marcbax | 0:c643d398cdb6 | 59 | return(result); |
| marcbax | 0:c643d398cdb6 | 60 | } |
| marcbax | 0:c643d398cdb6 | 61 | |
| marcbax | 0:c643d398cdb6 | 62 | // Function returning y-position of "letterpos" on the alphabet matrix |
| marcbax | 0:c643d398cdb6 | 63 | int HangmanGame::Ypos(const char letterpos) |
| marcbax | 0:c643d398cdb6 | 64 | { |
| marcbax | 0:c643d398cdb6 | 65 | int result; |
| marcbax | 0:c643d398cdb6 | 66 | result = 21 + ((letterpos/9)*30); |
| marcbax | 0:c643d398cdb6 | 67 | printf("ypos = %u\n", result); |
| marcbax | 0:c643d398cdb6 | 68 | return(result); |
| marcbax | 0:c643d398cdb6 | 69 | } |
| marcbax | 0:c643d398cdb6 | 70 | |
| marcbax | 0:c643d398cdb6 | 71 | // routine that redraws the alphabet matrix after a cursor move |
| marcbax | 0:c643d398cdb6 | 72 | void HangmanGame::RedrawAlphabet(const char newpos, const char oldpos, const bool alphabet[27]) |
| marcbax | 0:c643d398cdb6 | 73 | { |
| marcbax | 0:c643d398cdb6 | 74 | Log("redrawing newpos"); |
| marcbax | 0:c643d398cdb6 | 75 | if (alphabet[newpos]) |
| marcbax | 0:c643d398cdb6 | 76 | { |
| marcbax | 0:c643d398cdb6 | 77 | //writeimage of newpos letter greyed inverted |
| marcbax | 0:c643d398cdb6 | 78 | printf("writing %u grey inverted\n", newpos); |
| marcbax | 0:c643d398cdb6 | 79 | WritePartImage("/agi.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28); |
| marcbax | 0:c643d398cdb6 | 80 | } |
| marcbax | 0:c643d398cdb6 | 81 | else |
| marcbax | 0:c643d398cdb6 | 82 | { |
| marcbax | 0:c643d398cdb6 | 83 | //writeimage of newpos letter inverted |
| marcbax | 0:c643d398cdb6 | 84 | printf("writing %u inverted\n", newpos); |
| marcbax | 0:c643d398cdb6 | 85 | WritePartImage("/ai.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28); |
| marcbax | 0:c643d398cdb6 | 86 | } |
| marcbax | 0:c643d398cdb6 | 87 | Log("redrawing oldpos"); |
| marcbax | 0:c643d398cdb6 | 88 | if (alphabet[oldpos]) |
| marcbax | 0:c643d398cdb6 | 89 | { |
| marcbax | 0:c643d398cdb6 | 90 | //writeimage of oldpos letter greyed out |
| marcbax | 0:c643d398cdb6 | 91 | printf("writing %u greyed\n", oldpos); |
| marcbax | 0:c643d398cdb6 | 92 | WritePartImage("/ag.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28); |
| marcbax | 0:c643d398cdb6 | 93 | } |
| marcbax | 0:c643d398cdb6 | 94 | else |
| marcbax | 0:c643d398cdb6 | 95 | { |
| marcbax | 0:c643d398cdb6 | 96 | //writeimage of oldpos letter normal |
| marcbax | 0:c643d398cdb6 | 97 | printf("writing %u normal\n", oldpos); |
| marcbax | 0:c643d398cdb6 | 98 | WritePartImage("/an.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28); |
| marcbax | 0:c643d398cdb6 | 99 | } |
| marcbax | 0:c643d398cdb6 | 100 | // redraw the alphabet matrix based on a cursor move |
| marcbax | 0:c643d398cdb6 | 101 | UpdateDisplay(); |
| marcbax | 0:c643d398cdb6 | 102 | } |
| marcbax | 0:c643d398cdb6 | 103 | |
| marcbax | 0:c643d398cdb6 | 104 | //function to count number of eligible words in the dictionary file |
| marcbax | 0:c643d398cdb6 | 105 | int HangmanGame::NumDictWords() |
| marcbax | 0:c643d398cdb6 | 106 | { |
| marcbax | 0:c643d398cdb6 | 107 | FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r"); |
| marcbax | 0:c643d398cdb6 | 108 | if (fp1 == NULL) { |
| marcbax | 0:c643d398cdb6 | 109 | printf("Could not open hangdict.txt\n"); |
| marcbax | 0:c643d398cdb6 | 110 | } |
| marcbax | 0:c643d398cdb6 | 111 | else { |
| marcbax | 0:c643d398cdb6 | 112 | printf("hangdict.txt opened\n"); |
| marcbax | 0:c643d398cdb6 | 113 | } |
| marcbax | 0:c643d398cdb6 | 114 | int wordcount = 0; |
| marcbax | 0:c643d398cdb6 | 115 | int wordlength = 0; |
| marcbax | 0:c643d398cdb6 | 116 | int ch; |
| marcbax | 0:c643d398cdb6 | 117 | while (EOF != (ch = getc(fp1))) { |
| marcbax | 0:c643d398cdb6 | 118 | // check if character is an LF. If the word on that line is the right length, increment word counter |
| marcbax | 0:c643d398cdb6 | 119 | if (ch == 10) { |
| marcbax | 0:c643d398cdb6 | 120 | if ((wordlength > 7) && (wordlength < 15)) { |
| marcbax | 0:c643d398cdb6 | 121 | wordcount = wordcount + 1; |
| marcbax | 0:c643d398cdb6 | 122 | } |
| marcbax | 0:c643d398cdb6 | 123 | wordlength = 0; |
| marcbax | 0:c643d398cdb6 | 124 | } |
| marcbax | 0:c643d398cdb6 | 125 | else { |
| marcbax | 0:c643d398cdb6 | 126 | // if the character is not an LF, increment character count |
| marcbax | 0:c643d398cdb6 | 127 | wordlength = wordlength + 1; |
| marcbax | 0:c643d398cdb6 | 128 | } |
| marcbax | 0:c643d398cdb6 | 129 | } |
| marcbax | 0:c643d398cdb6 | 130 | fclose(fp1); |
| marcbax | 0:c643d398cdb6 | 131 | printf("Word count: %u\n", wordcount); |
| marcbax | 0:c643d398cdb6 | 132 | return wordcount; |
| marcbax | 0:c643d398cdb6 | 133 | } |
| marcbax | 0:c643d398cdb6 | 134 | |
| marcbax | 0:c643d398cdb6 | 135 | // routine to draw the current guess of the word on the display |
| marcbax | 0:c643d398cdb6 | 136 | void HangmanGame::DrawWord(const char guessed[14], const char wordlength) |
| marcbax | 0:c643d398cdb6 | 137 | { |
| marcbax | 0:c643d398cdb6 | 138 | for (int i = 0; i < wordlength; i++) { |
| marcbax | 0:c643d398cdb6 | 139 | WritePartImage("/an.pgm", 380-(25*(wordlength-i)), 191, guessed[i]*25, 0, 24, 28); |
| marcbax | 0:c643d398cdb6 | 140 | } |
| marcbax | 0:c643d398cdb6 | 141 | UpdateDisplay(); |
| marcbax | 0:c643d398cdb6 | 142 | } |
| marcbax | 0:c643d398cdb6 | 143 | |
| marcbax | 0:c643d398cdb6 | 144 | // routine to redraw the hanging man |
| marcbax | 0:c643d398cdb6 | 145 | void HangmanGame::DrawMan(const char manstate) |
| marcbax | 0:c643d398cdb6 | 146 | { |
| marcbax | 0:c643d398cdb6 | 147 | switch (manstate) |
| marcbax | 0:c643d398cdb6 | 148 | { |
| marcbax | 0:c643d398cdb6 | 149 | case 0: |
| marcbax | 0:c643d398cdb6 | 150 | WritePartImage("/man0.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 151 | break; |
| marcbax | 0:c643d398cdb6 | 152 | |
| marcbax | 0:c643d398cdb6 | 153 | case 1: |
| marcbax | 0:c643d398cdb6 | 154 | WritePartImage("/man1.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 155 | break; |
| marcbax | 0:c643d398cdb6 | 156 | |
| marcbax | 0:c643d398cdb6 | 157 | case 2: |
| marcbax | 0:c643d398cdb6 | 158 | WritePartImage("/man2.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 159 | break; |
| marcbax | 0:c643d398cdb6 | 160 | |
| marcbax | 0:c643d398cdb6 | 161 | case 3: |
| marcbax | 0:c643d398cdb6 | 162 | WritePartImage("/man3.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 163 | break; |
| marcbax | 0:c643d398cdb6 | 164 | |
| marcbax | 0:c643d398cdb6 | 165 | case 4: |
| marcbax | 0:c643d398cdb6 | 166 | WritePartImage("/man4.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 167 | break; |
| marcbax | 0:c643d398cdb6 | 168 | |
| marcbax | 0:c643d398cdb6 | 169 | case 5: |
| marcbax | 0:c643d398cdb6 | 170 | WritePartImage("/man5.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 171 | break; |
| marcbax | 0:c643d398cdb6 | 172 | |
| marcbax | 0:c643d398cdb6 | 173 | case 6: |
| marcbax | 0:c643d398cdb6 | 174 | WritePartImage("/man6.pgm", 35, 0, 0, 0, 74, 174); |
| marcbax | 0:c643d398cdb6 | 175 | break; |
| marcbax | 0:c643d398cdb6 | 176 | } |
| marcbax | 0:c643d398cdb6 | 177 | } |
| marcbax | 0:c643d398cdb6 | 178 | |
| marcbax | 0:c643d398cdb6 | 179 | // routine that picks a new word to guess, and returns the number of characters in the word |
| marcbax | 0:c643d398cdb6 | 180 | char HangmanGame::ReturnWord(char &word2guess) |
| marcbax | 0:c643d398cdb6 | 181 | { |
| marcbax | 0:c643d398cdb6 | 182 | //pick a random word from the hangdict.txt file |
| marcbax | 0:c643d398cdb6 | 183 | int wordindex = rand()%HangmanGame::NumDictWords(); |
| marcbax | 0:c643d398cdb6 | 184 | FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r"); |
| marcbax | 0:c643d398cdb6 | 185 | printf("Returning word: %u\n", wordindex); |
| marcbax | 0:c643d398cdb6 | 186 | for (int i = 0; i < wordindex; i++) { |
| marcbax | 0:c643d398cdb6 | 187 | fgets(&word2guess, 24, fp1); |
| marcbax | 0:c643d398cdb6 | 188 | while ((strlen(&word2guess) < 10) || (strlen(&word2guess) > 16)) { |
| marcbax | 0:c643d398cdb6 | 189 | fgets(&word2guess, 24, fp1); |
| marcbax | 0:c643d398cdb6 | 190 | } |
| marcbax | 0:c643d398cdb6 | 191 | } |
| marcbax | 0:c643d398cdb6 | 192 | printf("%s - length %u characters\n", &word2guess, strlen(&word2guess)-2); |
| marcbax | 0:c643d398cdb6 | 193 | fclose(fp1); |
| marcbax | 0:c643d398cdb6 | 194 | return (strlen(&word2guess)-2); |
| marcbax | 0:c643d398cdb6 | 195 | } |
| marcbax | 0:c643d398cdb6 | 196 | |
| marcbax | 0:c643d398cdb6 | 197 | // routine to move the cursor on the alphabet matrix when a nav button is pressed |
| marcbax | 0:c643d398cdb6 | 198 | // navbuttons: up=10; right=6; down=7; left=9; (select=8; cancel=5;) |
| marcbax | 0:c643d398cdb6 | 199 | char HangmanGame::MoveCursor(const bool alphabet[27], const char buttonnumber, char oldpos) |
| marcbax | 0:c643d398cdb6 | 200 | { |
| marcbax | 0:c643d398cdb6 | 201 | char newpos; |
| marcbax | 0:c643d398cdb6 | 202 | printf("%u, ", oldpos); |
| marcbax | 0:c643d398cdb6 | 203 | switch (buttonnumber) |
| marcbax | 0:c643d398cdb6 | 204 | { |
| marcbax | 0:c643d398cdb6 | 205 | case 10: |
| marcbax | 0:c643d398cdb6 | 206 | if (oldpos > 8) |
| marcbax | 0:c643d398cdb6 | 207 | newpos = oldpos-9; |
| marcbax | 0:c643d398cdb6 | 208 | else newpos=oldpos; |
| marcbax | 0:c643d398cdb6 | 209 | break; |
| marcbax | 0:c643d398cdb6 | 210 | |
| marcbax | 0:c643d398cdb6 | 211 | case 7: |
| marcbax | 0:c643d398cdb6 | 212 | if (oldpos < 18) |
| marcbax | 0:c643d398cdb6 | 213 | newpos = oldpos+9; |
| marcbax | 0:c643d398cdb6 | 214 | else newpos=oldpos; |
| marcbax | 0:c643d398cdb6 | 215 | break; |
| marcbax | 0:c643d398cdb6 | 216 | |
| marcbax | 0:c643d398cdb6 | 217 | case 9: |
| marcbax | 0:c643d398cdb6 | 218 | if ((oldpos == 0) || (oldpos == 9) || (oldpos == 18)) |
| marcbax | 0:c643d398cdb6 | 219 | newpos=oldpos; |
| marcbax | 0:c643d398cdb6 | 220 | else newpos=oldpos-1; |
| marcbax | 0:c643d398cdb6 | 221 | break; |
| marcbax | 0:c643d398cdb6 | 222 | |
| marcbax | 0:c643d398cdb6 | 223 | case 6: |
| marcbax | 0:c643d398cdb6 | 224 | if ((oldpos == 8) || (oldpos == 17) || (oldpos == 26)) |
| marcbax | 0:c643d398cdb6 | 225 | newpos=oldpos; |
| marcbax | 0:c643d398cdb6 | 226 | else newpos=oldpos+1; |
| marcbax | 0:c643d398cdb6 | 227 | break; |
| marcbax | 0:c643d398cdb6 | 228 | |
| marcbax | 0:c643d398cdb6 | 229 | default: |
| marcbax | 0:c643d398cdb6 | 230 | newpos=13; |
| marcbax | 0:c643d398cdb6 | 231 | } |
| marcbax | 0:c643d398cdb6 | 232 | printf("%u\n", newpos); |
| marcbax | 0:c643d398cdb6 | 233 | if (newpos != oldpos) RedrawAlphabet(newpos, oldpos, alphabet); |
| marcbax | 0:c643d398cdb6 | 234 | Log("alphabet redrawn"); |
| marcbax | 0:c643d398cdb6 | 235 | oldpos = newpos; |
| marcbax | 0:c643d398cdb6 | 236 | return(newpos); |
| marcbax | 0:c643d398cdb6 | 237 | } |
| marcbax | 0:c643d398cdb6 | 238 | |
| marcbax | 0:c643d398cdb6 | 239 | // routine called when a letter is selected - unfinished work in progress |
| marcbax | 0:c643d398cdb6 | 240 | bool HangmanGame::SelectLetter(const char letterpos, const char word2guess[14], const char wordlength, char* guessed[14], char hangmanstate) |
| marcbax | 0:c643d398cdb6 | 241 | { |
| marcbax | 0:c643d398cdb6 | 242 | bool goodguess = false; |
| marcbax | 0:c643d398cdb6 | 243 | // If the word contains the selected letter, update the guess |
| marcbax | 0:c643d398cdb6 | 244 | for (int i=0; i < wordlength; i++) |
| marcbax | 0:c643d398cdb6 | 245 | { |
| marcbax | 0:c643d398cdb6 | 246 | if (word2guess[i]==letterpos) |
| marcbax | 0:c643d398cdb6 | 247 | { |
| marcbax | 0:c643d398cdb6 | 248 | *guessed[i]=letterpos; |
| marcbax | 0:c643d398cdb6 | 249 | goodguess = true; |
| marcbax | 0:c643d398cdb6 | 250 | } |
| marcbax | 0:c643d398cdb6 | 251 | } |
| marcbax | 0:c643d398cdb6 | 252 | // If guess is correct, update the displayed word |
| marcbax | 0:c643d398cdb6 | 253 | if (goodguess) |
| marcbax | 0:c643d398cdb6 | 254 | { |
| marcbax | 0:c643d398cdb6 | 255 | DrawWord(*guessed, wordlength); |
| marcbax | 0:c643d398cdb6 | 256 | } |
| marcbax | 0:c643d398cdb6 | 257 | |
| marcbax | 0:c643d398cdb6 | 258 | // If the guess was wrong, hang the next segment of the man |
| marcbax | 0:c643d398cdb6 | 259 | if (!goodguess) |
| marcbax | 0:c643d398cdb6 | 260 | { |
| marcbax | 0:c643d398cdb6 | 261 | hangmanstate = hangmanstate+1; |
| marcbax | 0:c643d398cdb6 | 262 | DrawMan(hangmanstate); |
| marcbax | 0:c643d398cdb6 | 263 | } |
| marcbax | 0:c643d398cdb6 | 264 | |
| marcbax | 0:c643d398cdb6 | 265 | //body |
| marcbax | 0:c643d398cdb6 | 266 | UpdateDisplay(); |
| marcbax | 0:c643d398cdb6 | 267 | // The return value is false if the game is not finished yet, and true if the word is guessed or the man is hung |
| marcbax | 0:c643d398cdb6 | 268 | if ((hangmanstate==6) || (word2guess==*guessed)) |
| marcbax | 0:c643d398cdb6 | 269 | { |
| marcbax | 0:c643d398cdb6 | 270 | return(true); |
| marcbax | 0:c643d398cdb6 | 271 | } |
| marcbax | 0:c643d398cdb6 | 272 | else return (false); |
| marcbax | 0:c643d398cdb6 | 273 | } |
| marcbax | 0:c643d398cdb6 | 274 | |
| marcbax | 0:c643d398cdb6 | 275 | } |