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
Diff: hangman.cpp
- Revision:
- 0:c643d398cdb6
- Child:
- 1:5874c1a074a7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hangman.cpp Thu Jan 11 13:42:27 2018 +0000
@@ -0,0 +1,275 @@
+
+
+#include "log.h"
+#include "hangman.h"
+#include "eink.h"
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+namespace Flexbook
+{
+
+HangmanGame::HangmanGame()
+: finished(false), currentpos(13), oldpos(13),
+ alphabet(), word(""), guessed(""),
+ wordlength(0), hangstage(0)
+{
+ Log("Creating hangman game");
+
+ // Display the game welcome screen
+ WriteImage("/base.pgm");
+ DrawMan(0);
+ UpdateDisplay();
+
+ // Fill the array to indicate none of the letters has been used
+ for (int i=0; i<27; i++)
+ {
+ alphabet[i]=false;
+ }
+
+ // Pick a random word from the hangdict.txt file, update *word, and return the number of characters
+ wordlength = ReturnWord(*word);
+
+ //Change the word string so that "A" is 0, "M"=12, "N"=14 and "Z"=26
+ for (int i=0; i<wordlength; i++)
+ {
+ word[i] = word[i] - 65;
+ if (word[i] > 12) word[i] = word[i] + 1;
+ guessed[i]=13;
+ printf(" %u", word[i]);
+ }
+
+ // Display the game start screen
+ printf("\n");
+ DrawWord(guessed, wordlength);
+
+}
+
+HangmanGame::~HangmanGame()
+{
+ Log("deleting hangmangame");
+}
+
+// Function returning x-position of "letterpos" on the alphabet matrix
+int HangmanGame::Xpos(const char letterpos)
+{
+ int result;
+ result = 155 + ((letterpos%9)*25);
+ printf("xpos = %u, ", result);
+ return(result);
+}
+
+// Function returning y-position of "letterpos" on the alphabet matrix
+int HangmanGame::Ypos(const char letterpos)
+{
+ int result;
+ result = 21 + ((letterpos/9)*30);
+ printf("ypos = %u\n", result);
+ return(result);
+}
+
+// routine that redraws the alphabet matrix after a cursor move
+void HangmanGame::RedrawAlphabet(const char newpos, const char oldpos, const bool alphabet[27])
+{
+ Log("redrawing newpos");
+ if (alphabet[newpos])
+ {
+ //writeimage of newpos letter greyed inverted
+ printf("writing %u grey inverted\n", newpos);
+ WritePartImage("/agi.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28);
+ }
+ else
+ {
+ //writeimage of newpos letter inverted
+ printf("writing %u inverted\n", newpos);
+ WritePartImage("/ai.pgm", Xpos(newpos), Ypos(newpos), newpos*25, 0, 24, 28);
+ }
+ Log("redrawing oldpos");
+ if (alphabet[oldpos])
+ {
+ //writeimage of oldpos letter greyed out
+ printf("writing %u greyed\n", oldpos);
+ WritePartImage("/ag.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28);
+ }
+ else
+ {
+ //writeimage of oldpos letter normal
+ printf("writing %u normal\n", oldpos);
+ WritePartImage("/an.pgm", Xpos(oldpos), Ypos(oldpos), oldpos*25, 0, 24, 28);
+ }
+ // redraw the alphabet matrix based on a cursor move
+ UpdateDisplay();
+}
+
+//function to count number of eligible words in the dictionary file
+int HangmanGame::NumDictWords()
+{
+ FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r");
+ if (fp1 == NULL) {
+ printf("Could not open hangdict.txt\n");
+ }
+ else {
+ printf("hangdict.txt opened\n");
+ }
+ int wordcount = 0;
+ int wordlength = 0;
+ int ch;
+ while (EOF != (ch = getc(fp1))) {
+ // check if character is an LF. If the word on that line is the right length, increment word counter
+ if (ch == 10) {
+ if ((wordlength > 7) && (wordlength < 15)) {
+ wordcount = wordcount + 1;
+ }
+ wordlength = 0;
+ }
+ else {
+ // if the character is not an LF, increment character count
+ wordlength = wordlength + 1;
+ }
+ }
+ fclose(fp1);
+ printf("Word count: %u\n", wordcount);
+ return wordcount;
+}
+
+// routine to draw the current guess of the word on the display
+void HangmanGame::DrawWord(const char guessed[14], const char wordlength)
+{
+ for (int i = 0; i < wordlength; i++) {
+ WritePartImage("/an.pgm", 380-(25*(wordlength-i)), 191, guessed[i]*25, 0, 24, 28);
+ }
+ UpdateDisplay();
+}
+
+// routine to redraw the hanging man
+void HangmanGame::DrawMan(const char manstate)
+{
+ switch (manstate)
+ {
+ case 0:
+ WritePartImage("/man0.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 1:
+ WritePartImage("/man1.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 2:
+ WritePartImage("/man2.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 3:
+ WritePartImage("/man3.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 4:
+ WritePartImage("/man4.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 5:
+ WritePartImage("/man5.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+
+ case 6:
+ WritePartImage("/man6.pgm", 35, 0, 0, 0, 74, 174);
+ break;
+ }
+}
+
+// routine that picks a new word to guess, and returns the number of characters in the word
+char HangmanGame::ReturnWord(char &word2guess)
+{
+ //pick a random word from the hangdict.txt file
+ int wordindex = rand()%HangmanGame::NumDictWords();
+ FILE *fp1 = fopen("/sd/hangman/hangdict.txt", "r");
+ printf("Returning word: %u\n", wordindex);
+ for (int i = 0; i < wordindex; i++) {
+ fgets(&word2guess, 24, fp1);
+ while ((strlen(&word2guess) < 10) || (strlen(&word2guess) > 16)) {
+ fgets(&word2guess, 24, fp1);
+ }
+ }
+ printf("%s - length %u characters\n", &word2guess, strlen(&word2guess)-2);
+ fclose(fp1);
+ return (strlen(&word2guess)-2);
+}
+
+// routine to move the cursor on the alphabet matrix when a nav button is pressed
+// navbuttons: up=10; right=6; down=7; left=9; (select=8; cancel=5;)
+char HangmanGame::MoveCursor(const bool alphabet[27], const char buttonnumber, char oldpos)
+{
+ char newpos;
+ printf("%u, ", oldpos);
+ switch (buttonnumber)
+ {
+ case 10:
+ if (oldpos > 8)
+ newpos = oldpos-9;
+ else newpos=oldpos;
+ break;
+
+ case 7:
+ if (oldpos < 18)
+ newpos = oldpos+9;
+ else newpos=oldpos;
+ break;
+
+ case 9:
+ if ((oldpos == 0) || (oldpos == 9) || (oldpos == 18))
+ newpos=oldpos;
+ else newpos=oldpos-1;
+ break;
+
+ case 6:
+ if ((oldpos == 8) || (oldpos == 17) || (oldpos == 26))
+ newpos=oldpos;
+ else newpos=oldpos+1;
+ break;
+
+ default:
+ newpos=13;
+ }
+ printf("%u\n", newpos);
+ if (newpos != oldpos) RedrawAlphabet(newpos, oldpos, alphabet);
+ Log("alphabet redrawn");
+ oldpos = newpos;
+ return(newpos);
+}
+
+// routine called when a letter is selected - unfinished work in progress
+bool HangmanGame::SelectLetter(const char letterpos, const char word2guess[14], const char wordlength, char* guessed[14], char hangmanstate)
+{
+ bool goodguess = false;
+ // If the word contains the selected letter, update the guess
+ for (int i=0; i < wordlength; i++)
+ {
+ if (word2guess[i]==letterpos)
+ {
+ *guessed[i]=letterpos;
+ goodguess = true;
+ }
+ }
+ // If guess is correct, update the displayed word
+ if (goodguess)
+ {
+ DrawWord(*guessed, wordlength);
+ }
+
+ // If the guess was wrong, hang the next segment of the man
+ if (!goodguess)
+ {
+ hangmanstate = hangmanstate+1;
+ DrawMan(hangmanstate);
+ }
+
+ //body
+ UpdateDisplay();
+ // The return value is false if the game is not finished yet, and true if the word is guessed or the man is hung
+ if ((hangmanstate==6) || (word2guess==*guessed))
+ {
+ return(true);
+ }
+ else return (false);
+}
+
+}