Error as described in MBs email to MS

Dependencies:   SDFileSystem app epson mbed msp430 pl tests

hangman.cpp

Committer:
marcbax
Date:
2018-01-11
Revision:
1:5874c1a074a7
Parent:
0:c643d398cdb6

File content as of revision 1:5874c1a074a7:



#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", 230, 51, 300, 0, 24, 28);
            //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);
}

}