Error as described in MBs email to MS
Dependencies: SDFileSystem app epson mbed msp430 pl tests
hangman.cpp@1:5874c1a074a7, 2018-01-11 (annotated)
- Committer:
- marcbax
- Date:
- Thu Jan 11 14:12:00 2018 +0000
- Revision:
- 1:5874c1a074a7
- Parent:
- 0:c643d398cdb6
Version 180111a with error as reported to Mark Symonds
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 | 1:5874c1a074a7 | 85 | WritePartImage("/ai.pgm", 230, 51, 300, 0, 24, 28); |
marcbax | 1:5874c1a074a7 | 86 | //WritePartImage("/ai.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28); |
marcbax | 0:c643d398cdb6 | 87 | } |
marcbax | 0:c643d398cdb6 | 88 | Log("redrawing oldpos"); |
marcbax | 0:c643d398cdb6 | 89 | if (alphabet[oldpos]) |
marcbax | 0:c643d398cdb6 | 90 | { |
marcbax | 0:c643d398cdb6 | 91 | //writeimage of oldpos letter greyed out |
marcbax | 0:c643d398cdb6 | 92 | printf("writing %u greyed\n", oldpos); |
marcbax | 0:c643d398cdb6 | 93 | WritePartImage("/ag.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28); |
marcbax | 0:c643d398cdb6 | 94 | } |
marcbax | 0:c643d398cdb6 | 95 | else |
marcbax | 0:c643d398cdb6 | 96 | { |
marcbax | 0:c643d398cdb6 | 97 | //writeimage of oldpos letter normal |
marcbax | 0:c643d398cdb6 | 98 | printf("writing %u normal\n", oldpos); |
marcbax | 0:c643d398cdb6 | 99 | WritePartImage("/an.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28); |
marcbax | 0:c643d398cdb6 | 100 | } |
marcbax | 0:c643d398cdb6 | 101 | // redraw the alphabet matrix based on a cursor move |
marcbax | 0:c643d398cdb6 | 102 | UpdateDisplay(); |
marcbax | 0:c643d398cdb6 | 103 | } |
marcbax | 0:c643d398cdb6 | 104 | |
marcbax | 0:c643d398cdb6 | 105 | //function to count number of eligible words in the dictionary file |
marcbax | 0:c643d398cdb6 | 106 | int HangmanGame::NumDictWords() |
marcbax | 0:c643d398cdb6 | 107 | { |
marcbax | 0:c643d398cdb6 | 108 | FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r"); |
marcbax | 0:c643d398cdb6 | 109 | if (fp1 == NULL) { |
marcbax | 0:c643d398cdb6 | 110 | printf("Could not open hangdict.txt\n"); |
marcbax | 0:c643d398cdb6 | 111 | } |
marcbax | 0:c643d398cdb6 | 112 | else { |
marcbax | 0:c643d398cdb6 | 113 | printf("hangdict.txt opened\n"); |
marcbax | 0:c643d398cdb6 | 114 | } |
marcbax | 0:c643d398cdb6 | 115 | int wordcount = 0; |
marcbax | 0:c643d398cdb6 | 116 | int wordlength = 0; |
marcbax | 0:c643d398cdb6 | 117 | int ch; |
marcbax | 0:c643d398cdb6 | 118 | while (EOF != (ch = getc(fp1))) { |
marcbax | 0:c643d398cdb6 | 119 | // check if character is an LF. If the word on that line is the right length, increment word counter |
marcbax | 0:c643d398cdb6 | 120 | if (ch == 10) { |
marcbax | 0:c643d398cdb6 | 121 | if ((wordlength > 7) && (wordlength < 15)) { |
marcbax | 0:c643d398cdb6 | 122 | wordcount = wordcount + 1; |
marcbax | 0:c643d398cdb6 | 123 | } |
marcbax | 0:c643d398cdb6 | 124 | wordlength = 0; |
marcbax | 0:c643d398cdb6 | 125 | } |
marcbax | 0:c643d398cdb6 | 126 | else { |
marcbax | 0:c643d398cdb6 | 127 | // if the character is not an LF, increment character count |
marcbax | 0:c643d398cdb6 | 128 | wordlength = wordlength + 1; |
marcbax | 0:c643d398cdb6 | 129 | } |
marcbax | 0:c643d398cdb6 | 130 | } |
marcbax | 0:c643d398cdb6 | 131 | fclose(fp1); |
marcbax | 0:c643d398cdb6 | 132 | printf("Word count: %u\n", wordcount); |
marcbax | 0:c643d398cdb6 | 133 | return wordcount; |
marcbax | 0:c643d398cdb6 | 134 | } |
marcbax | 0:c643d398cdb6 | 135 | |
marcbax | 0:c643d398cdb6 | 136 | // routine to draw the current guess of the word on the display |
marcbax | 0:c643d398cdb6 | 137 | void HangmanGame::DrawWord(const char guessed[14], const char wordlength) |
marcbax | 0:c643d398cdb6 | 138 | { |
marcbax | 0:c643d398cdb6 | 139 | for (int i = 0; i < wordlength; i++) { |
marcbax | 0:c643d398cdb6 | 140 | WritePartImage("/an.pgm", 380-(25*(wordlength-i)), 191, guessed[i]*25, 0, 24, 28); |
marcbax | 0:c643d398cdb6 | 141 | } |
marcbax | 0:c643d398cdb6 | 142 | UpdateDisplay(); |
marcbax | 0:c643d398cdb6 | 143 | } |
marcbax | 0:c643d398cdb6 | 144 | |
marcbax | 0:c643d398cdb6 | 145 | // routine to redraw the hanging man |
marcbax | 0:c643d398cdb6 | 146 | void HangmanGame::DrawMan(const char manstate) |
marcbax | 0:c643d398cdb6 | 147 | { |
marcbax | 0:c643d398cdb6 | 148 | switch (manstate) |
marcbax | 0:c643d398cdb6 | 149 | { |
marcbax | 0:c643d398cdb6 | 150 | case 0: |
marcbax | 0:c643d398cdb6 | 151 | WritePartImage("/man0.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 152 | break; |
marcbax | 0:c643d398cdb6 | 153 | |
marcbax | 0:c643d398cdb6 | 154 | case 1: |
marcbax | 0:c643d398cdb6 | 155 | WritePartImage("/man1.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 156 | break; |
marcbax | 0:c643d398cdb6 | 157 | |
marcbax | 0:c643d398cdb6 | 158 | case 2: |
marcbax | 0:c643d398cdb6 | 159 | WritePartImage("/man2.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 160 | break; |
marcbax | 0:c643d398cdb6 | 161 | |
marcbax | 0:c643d398cdb6 | 162 | case 3: |
marcbax | 0:c643d398cdb6 | 163 | WritePartImage("/man3.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 164 | break; |
marcbax | 0:c643d398cdb6 | 165 | |
marcbax | 0:c643d398cdb6 | 166 | case 4: |
marcbax | 0:c643d398cdb6 | 167 | WritePartImage("/man4.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 168 | break; |
marcbax | 0:c643d398cdb6 | 169 | |
marcbax | 0:c643d398cdb6 | 170 | case 5: |
marcbax | 0:c643d398cdb6 | 171 | WritePartImage("/man5.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 172 | break; |
marcbax | 0:c643d398cdb6 | 173 | |
marcbax | 0:c643d398cdb6 | 174 | case 6: |
marcbax | 0:c643d398cdb6 | 175 | WritePartImage("/man6.pgm", 35, 0, 0, 0, 74, 174); |
marcbax | 0:c643d398cdb6 | 176 | break; |
marcbax | 0:c643d398cdb6 | 177 | } |
marcbax | 0:c643d398cdb6 | 178 | } |
marcbax | 0:c643d398cdb6 | 179 | |
marcbax | 0:c643d398cdb6 | 180 | // routine that picks a new word to guess, and returns the number of characters in the word |
marcbax | 0:c643d398cdb6 | 181 | char HangmanGame::ReturnWord(char &word2guess) |
marcbax | 0:c643d398cdb6 | 182 | { |
marcbax | 0:c643d398cdb6 | 183 | //pick a random word from the hangdict.txt file |
marcbax | 0:c643d398cdb6 | 184 | int wordindex = rand()%HangmanGame::NumDictWords(); |
marcbax | 0:c643d398cdb6 | 185 | FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r"); |
marcbax | 0:c643d398cdb6 | 186 | printf("Returning word: %u\n", wordindex); |
marcbax | 0:c643d398cdb6 | 187 | for (int i = 0; i < wordindex; i++) { |
marcbax | 0:c643d398cdb6 | 188 | fgets(&word2guess, 24, fp1); |
marcbax | 0:c643d398cdb6 | 189 | while ((strlen(&word2guess) < 10) || (strlen(&word2guess) > 16)) { |
marcbax | 0:c643d398cdb6 | 190 | fgets(&word2guess, 24, fp1); |
marcbax | 0:c643d398cdb6 | 191 | } |
marcbax | 0:c643d398cdb6 | 192 | } |
marcbax | 0:c643d398cdb6 | 193 | printf("%s - length %u characters\n", &word2guess, strlen(&word2guess)-2); |
marcbax | 0:c643d398cdb6 | 194 | fclose(fp1); |
marcbax | 0:c643d398cdb6 | 195 | return (strlen(&word2guess)-2); |
marcbax | 0:c643d398cdb6 | 196 | } |
marcbax | 0:c643d398cdb6 | 197 | |
marcbax | 0:c643d398cdb6 | 198 | // routine to move the cursor on the alphabet matrix when a nav button is pressed |
marcbax | 0:c643d398cdb6 | 199 | // navbuttons: up=10; right=6; down=7; left=9; (select=8; cancel=5;) |
marcbax | 0:c643d398cdb6 | 200 | char HangmanGame::MoveCursor(const bool alphabet[27], const char buttonnumber, char oldpos) |
marcbax | 0:c643d398cdb6 | 201 | { |
marcbax | 0:c643d398cdb6 | 202 | char newpos; |
marcbax | 0:c643d398cdb6 | 203 | printf("%u, ", oldpos); |
marcbax | 0:c643d398cdb6 | 204 | switch (buttonnumber) |
marcbax | 0:c643d398cdb6 | 205 | { |
marcbax | 0:c643d398cdb6 | 206 | case 10: |
marcbax | 0:c643d398cdb6 | 207 | if (oldpos > 8) |
marcbax | 0:c643d398cdb6 | 208 | newpos = oldpos-9; |
marcbax | 0:c643d398cdb6 | 209 | else newpos=oldpos; |
marcbax | 0:c643d398cdb6 | 210 | break; |
marcbax | 0:c643d398cdb6 | 211 | |
marcbax | 0:c643d398cdb6 | 212 | case 7: |
marcbax | 0:c643d398cdb6 | 213 | if (oldpos < 18) |
marcbax | 0:c643d398cdb6 | 214 | newpos = oldpos+9; |
marcbax | 0:c643d398cdb6 | 215 | else newpos=oldpos; |
marcbax | 0:c643d398cdb6 | 216 | break; |
marcbax | 0:c643d398cdb6 | 217 | |
marcbax | 0:c643d398cdb6 | 218 | case 9: |
marcbax | 0:c643d398cdb6 | 219 | if ((oldpos == 0) || (oldpos == 9) || (oldpos == 18)) |
marcbax | 0:c643d398cdb6 | 220 | newpos=oldpos; |
marcbax | 0:c643d398cdb6 | 221 | else newpos=oldpos-1; |
marcbax | 0:c643d398cdb6 | 222 | break; |
marcbax | 0:c643d398cdb6 | 223 | |
marcbax | 0:c643d398cdb6 | 224 | case 6: |
marcbax | 0:c643d398cdb6 | 225 | if ((oldpos == 8) || (oldpos == 17) || (oldpos == 26)) |
marcbax | 0:c643d398cdb6 | 226 | newpos=oldpos; |
marcbax | 0:c643d398cdb6 | 227 | else newpos=oldpos+1; |
marcbax | 0:c643d398cdb6 | 228 | break; |
marcbax | 0:c643d398cdb6 | 229 | |
marcbax | 0:c643d398cdb6 | 230 | default: |
marcbax | 0:c643d398cdb6 | 231 | newpos=13; |
marcbax | 0:c643d398cdb6 | 232 | } |
marcbax | 0:c643d398cdb6 | 233 | printf("%u\n", newpos); |
marcbax | 0:c643d398cdb6 | 234 | if (newpos != oldpos) RedrawAlphabet(newpos, oldpos, alphabet); |
marcbax | 0:c643d398cdb6 | 235 | Log("alphabet redrawn"); |
marcbax | 0:c643d398cdb6 | 236 | oldpos = newpos; |
marcbax | 0:c643d398cdb6 | 237 | return(newpos); |
marcbax | 0:c643d398cdb6 | 238 | } |
marcbax | 0:c643d398cdb6 | 239 | |
marcbax | 0:c643d398cdb6 | 240 | // routine called when a letter is selected - unfinished work in progress |
marcbax | 0:c643d398cdb6 | 241 | bool HangmanGame::SelectLetter(const char letterpos, const char word2guess[14], const char wordlength, char* guessed[14], char hangmanstate) |
marcbax | 0:c643d398cdb6 | 242 | { |
marcbax | 0:c643d398cdb6 | 243 | bool goodguess = false; |
marcbax | 0:c643d398cdb6 | 244 | // If the word contains the selected letter, update the guess |
marcbax | 0:c643d398cdb6 | 245 | for (int i=0; i < wordlength; i++) |
marcbax | 0:c643d398cdb6 | 246 | { |
marcbax | 0:c643d398cdb6 | 247 | if (word2guess[i]==letterpos) |
marcbax | 0:c643d398cdb6 | 248 | { |
marcbax | 0:c643d398cdb6 | 249 | *guessed[i]=letterpos; |
marcbax | 0:c643d398cdb6 | 250 | goodguess = true; |
marcbax | 0:c643d398cdb6 | 251 | } |
marcbax | 0:c643d398cdb6 | 252 | } |
marcbax | 0:c643d398cdb6 | 253 | // If guess is correct, update the displayed word |
marcbax | 0:c643d398cdb6 | 254 | if (goodguess) |
marcbax | 0:c643d398cdb6 | 255 | { |
marcbax | 0:c643d398cdb6 | 256 | DrawWord(*guessed, wordlength); |
marcbax | 0:c643d398cdb6 | 257 | } |
marcbax | 0:c643d398cdb6 | 258 | |
marcbax | 0:c643d398cdb6 | 259 | // If the guess was wrong, hang the next segment of the man |
marcbax | 0:c643d398cdb6 | 260 | if (!goodguess) |
marcbax | 0:c643d398cdb6 | 261 | { |
marcbax | 0:c643d398cdb6 | 262 | hangmanstate = hangmanstate+1; |
marcbax | 0:c643d398cdb6 | 263 | DrawMan(hangmanstate); |
marcbax | 0:c643d398cdb6 | 264 | } |
marcbax | 0:c643d398cdb6 | 265 | |
marcbax | 0:c643d398cdb6 | 266 | //body |
marcbax | 0:c643d398cdb6 | 267 | UpdateDisplay(); |
marcbax | 0:c643d398cdb6 | 268 | // 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 | 269 | if ((hangmanstate==6) || (word2guess==*guessed)) |
marcbax | 0:c643d398cdb6 | 270 | { |
marcbax | 0:c643d398cdb6 | 271 | return(true); |
marcbax | 0:c643d398cdb6 | 272 | } |
marcbax | 0:c643d398cdb6 | 273 | else return (false); |
marcbax | 0:c643d398cdb6 | 274 | } |
marcbax | 0:c643d398cdb6 | 275 | |
marcbax | 0:c643d398cdb6 | 276 | } |