Example on Arrays and Strings

/* Write a program so that the user can play Hangman (or Wheel-Of-Fortune) against the computer.
At the start of a game, the computer selects a word at random from an external file containing no more 999 words.
Then for each turn, the computer simulates a spin of the wheel of fortune, returning a random multiple of $100 (up to $500).
The player then guesses a letter.
If the secret word contains such a letter, the player's potential earnings are increased by the random dollar amount times the number of occurrences of the letter in the secret word.
If the guess is incorrect, the total earnings are not changed, and the incorrect letter is added to the string of incorrect guesses.
The player wins and keeps all the earnings if he or she guesses the word with no more than eight incorrect guesses.
A loser loses all his or her earnings.
The player will be ask if he or she wants to continue or quit.
*/
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;
const int MAX_NUMBER_GUESSES(8), NUMBER_REWARD_LEVELS(5);

void readWordList(string wordList[ ], int& wordNumber);
// read from a file "word.txt" a list of secret words and store them in wordList.
// The number of words on the list is wordNumber.
// Precond: wordList have been declared with size >= 999,
// wordNumber is declared an integer.
// Postcond: wordList contains an array of secret words
// total number of words is stored in wordNumber.

void selectWord(const string wordList[ ], int wordNumber, string& secretWord);
// select at random from wordList a secret word for the turn.
// Precond: wordList contains an array of secret words
// total number of words is given by wordNumber
// secretWord ha been declared a string.
// Postcond: secretWord contains a chosen secret word from wordList.

void initialWord(const string& secretWord, string& currentWord);
// curentWord set to a string the same length as the secret word
// but with all letters replaced by -'s.
// Precond: secretWord contain a secret word
// currentWord is an empty string
// Postcond: currentWord is set to a string the same length
// as the secret word but with all letters replaced by -'s.

void showGuesses(const string& currentWord,
    const string& wrongChars, int dollarsWon);
// display the current word, the wrong letters, and the earnings
// Precond: currentWord contains the current guess for the word
// wrongChars contains all the wrongly guessed letters
// dollarsWon has the current earnings
// Postcond: current word, the wrong letters, and the earnings
// are displayed on screen

void spinWheel(int& spinAmount);
// spin the wheel to get the amount per correct letter
// Precond: spinAmount has been declared
// Postcond: spinAmount is chosen at random from the following values:
// {100, 200, 300, 400, 500}

void processGuess(const string& secretWord, string& currentWord,
                                string& wrongChars, int spinAmount, int& dollarsWon);
// player is asked to choose a letter, if the letter is in the
// secret word, update the current word and the earning according
// to the spinAmount, otherwise the wrong letter is added to wrongChars.
// Precond: secretWord has the secret word
// currentWord has the current word
// wrongChars has a string of the wrong letters
// spinAmount has the dollar value of a correct letter in this turn
// dollarsWon has the current earnings
// Postcond: currentWord, wrongChars and dollarsWon are updated accordingly.

void showResults(const string& secretWord, const string& currentWord,
                              int& dollarsWon, char& ans);
// reveal secret word and inform player whether he or she won.
// ask player whether to continue or quit.
// Precond: secretWord contain the secret word
// currentWord contains the current word
// dollarsWon has the current earnings
// ans has been declared a char
// Postcond: display on screen the secret word, and whether the player
// has won or lost. Total earnings are displayed if won.
// Player is asked if he or she wants to continue or quit.

int main ( )
{
    string wordList[999], secretWord, currentWord, wrongChars;
    int wordNumber(0), spinAmount, dollarsWon(0);
    char ans;

    // read in a list of secret words
    readWordList(wordList, wordNumber);

    do {
        // select a secret word at random from the word list
        selectWord(wordList, wordNumber, secretWord);
        // initialize current word to a no. of dashes the same length as the secret word
        initialWord(secretWord, currentWord);
        do {
            // display the current word, the incorrect letters,
            // and the earnings
            showGuesses(currentWord, wrongChars, dollarsWon);
            // spin the wheel to get the amount per letter
            spinWheel(spinAmount);
            // process the guess
            processGuess(secretWord, currentWord, wrongChars,
                                spinAmount, dollarsWon);
        } while (wrongChars.length( ) < MAX_NUMBER_GUESSES && currentWord != secretWord);

        // reveal secret word and inform player whether he
        // or she won.
        // ask player whether to continue or quit.
        showResults(secretWord, currentWord, dollarsWon, ans);
        } while (ans == 'y' || ans == 'Y');
}

void readWordList(string wordList[ ], int& wordNumber)
{
    ifstream ins("words.txt");
    if (!ins)
    {
        cerr << "Can't open file words.txt for input!\n";
        exit(1);
    }

    while (ins >> wordList[wordNumber])
    {
        wordNumber++;
    }
    ins.close( );
}

void selectWord(const string wordList[ ], int wordNumber, string& secretWord)
{
    srand(time(0));
    int index = rand( ) % wordNumber;
    secretWord = wordList[index];
    cout << secretWord << endl;         //delete this line to suppress correct answer
}

void initialWord(const string& secretWord, string& currentWord)
{
    for (unsigned n = 0; n < secretWord.length( ); n++)
        currentWord = currentWord + '-';
}

void showGuesses(const string& currentWord, const string& wrongChars,
                        int dollarsWon)
{
    cout << endl;
    cout << "Current word: " << currentWord << endl;
    cout << "You've made " << wrongChars.length( )
        << " incorrect guesses: " << wrongChars << endl;
    cout << "Your current earnings is $" << dollarsWon << endl;
}

void spinWheel(int& spinAmount)
{
    cout << "This turn is worth $";
    spinAmount = 100 * ( rand( )% NUMBER_REWARD_LEVELS + 1);
    cout << spinAmount << endl;
}

void processGuess(const string& secretWord, string& currentWord,
                                string& wrongChars, int spinAmount, int& dollarsWon)
{
    char guess;
    int correctCount(0);
    // input a guess from player
    cout << "Pick a letter: ";
    cin >> guess;
    // update current word with newly correctly guessed letter
    // and count the number of those letters
    for (unsigned n = 0; n < secretWord.length( ); n++)
    if (secretWord[n] == guess)
    {
        currentWord[n] = guess;
        correctCount++;
    }

    if (correctCount > 0)
    // increase earnings if guess was in the secret word
    dollarsWon += (correctCount * spinAmount);
    else
    // add wrong guess to the wrongChars string
    wrongChars += guess;
}

void showResults(const string& secretWord, const string& currentWord,
                              int& dollarsWon, char& ans)
{
    cout << "\nThe secret word was " << secretWord << endl;

    if (currentWord == secretWord)
        cout << "Congratulations! \nYou won $" << dollarsWon;
    else
    {
        cout << "You've made 8 incorrect guesses and " <<
        "lost all your earnings.\n";
        dollarsWon = 0;
    }
    cout << endl;
    cout << "Do you want to play again ('y' or 'n')?\n";
    cin >> ans;
}

/*
In the actual game, the host will not allow a player to select letters that have been selected before. However in a computer game, the program must not allow the player to make any illegal moves. There is serious flaw in the above program for Hangman in that a player can make such an illegal move thereby endlessly increases his or her earnings!
It is a good exercise for you to attempt to close that loophole by modifying the above program. Afterward you can take a look at one of the possible solution below.
*/
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <ctime>

using namespace std;
const int EIGHT = 8, FIVE = 5;

void readWordList(string wordList[ ], int& wordNumber);
// read from a file "word.txt" a list of secret words and store
// them in wordList.
// The number of words on the list is wordNumber.
// Precond: wordList have been declared with size >= 999,
// wordNumber is declared an integer.
// Postcond: wordList contains an array of secret words
// total number of words is stored in wordNumber.

void selectWord(const string wordList[ ],
            int wordNumber, string& secretWord);
// select at random from wordList a secret word for the turn.
// Precond: wordList contains an array of secret words
// total number of words is given by wordNumber
// secretWord ha been declared a string.
// Postcond: secretWord contains a chosen secret word from wordList.

void initialWord(const string& secretWord, string& currentWord,
            string& wrongChars, string& rightChars);
// curentWord set to a string the same length as the secret word
// but with all letters replaced by -'s.
// Precond: secretWord contain a secret word
// currentWord is an empty string
// Postcond: currentWord is set to a string the same length
// as the secret word but with all letters replaced by -'s.

void showGuesses(const string& currentWord,
            const string& wrongChars, int dollarsWon);
// display the current word, the wrong letters, and the earnings
// Precond: currentWord contains the current guess for the word
// wrongChars contains all the wrongly guessed letters
// dollarsWon has the current earnings
// Postcond: current word, the wrong letters, and the earnings
// are displayed on screen

void spinWheel(int& spinAmount);
// spin the wheel to get the amount per correct letter
// Precond: spinAmount has been declared
// Postcond: spinAmount is chosen from the following values:
// {100, 200, 300, 400, 500}

void processGuess(const string& secretWord,
            string& currentWord, string& wrongChars,
            string& rightChars, int spinAmount, int& dollarsWon);
// player is asked to choose a letter, if the letter is in the
// secret word, update the current word and the earning according
// to the spinAmount, otherwise the wrong letter is added to wrongChars.
// Precond: secretWord has the secret word
// currentWord has the current word
// wrongChars has a string of the wrong letters
// spinAmount has the value of a correct letter in this turn
// dollarsWon has the current earnings
// Postcond: currentWord, wronChars and dollarsWon are updated
// accordingly.

char pickLetter(const string& rightChars);
// ask player to choose another letter
// make sure that letter has not been chosen before.
// Precond: rightChars is a string containing the correct letters
// Post cond: returns a char that is not in the string rightChars

void showResults(const string& secretWord,
            const string& currentWord, int& dollarsWon,
            char& ans);
// reveal secret word and inform player whether he or she won.
// ask player whether to continue or quit.
// Precond: secretWord contain the secret word
// currentWord contains the current word
// dollarsWon has the current earnings
// ans has been declared a char
// Postcond: display on screen the secret word, and whether the
// has won or lost. Total earnings displayed if won.
// Player is asked if he or she wants to continue or quit.

int main ()
{
    string wordList[999], secretWord, currentWord,
        wrongChars, rightChars;
    int wordNumber(0), spinAmount, dollarsWon(0);
    char ans;

    // read in a list of secret words
    readWordList(wordList, wordNumber);

    do {
        // select a secret word at random from the word list
        selectWord(wordList, wordNumber, secretWord);
        // initialize current word to a bunch of ---
        // having the same length as the secret word
        initialWord(secretWord, currentWord, wrongChars, rightChars);
        do {
            // display the current word, the incorrect letters,
            // and the earnings
            showGuesses(currentWord, wrongChars, dollarsWon);
            // spin the wheel to get the amount per letter
            spinWheel(spinAmount);
            // process the guess
        processGuess(secretWord, currentWord, wrongChars,
            rightChars, spinAmount, dollarsWon);
    } while (wrongChars.length() < EIGHT &&
    currentWord != secretWord);

    // reveal secret word and inform player whether he
    // or she won.
    // ask player whether to continue or quit.
    showResults(secretWord, currentWord, dollarsWon, ans);
    } while (ans == 'y' || ans == 'Y');
}

void readWordList(string wordList[], int& wordNumber)
{
    ifstream ins("word.txt");
    if (!ins)
    {
        cerr << "Can't open file word.txt for input!\n";
        exit(1);
    }

    while (ins >> wordList[wordNumber])
    {
        wordNumber++;
    }
    ins.close();
}

void selectWord(const string wordList[],
            int wordNumber, string& secretWord)
{
    srand((unsigned int)time(0));
    int index = rand() % wordNumber;
    secretWord = wordList[index];
}

void initialWord(const string& secretWord, string& currentWord,
        string& wrongChars, string& rightChars)
{
    currentWord = "";
    wrongChars = "";
    rightChars = "";
    for (unsigned n = 0; n < secretWord.length(); n++)
        currentWord = currentWord + '-';
    }
   
void showGuesses(const string& currentWord,
            const string& wrongChars,
            int dollarsWon)
{
    cout << endl;
    cout << "Current word: " << currentWord << endl;
    cout << "You've made " << (int)wrongChars.length()
    << " incorrect guesses: " << wrongChars << endl;
    cout << "Your current earnings is $" << dollarsWon << endl;
}

void spinWheel(int& spinAmount)
{
    cout << "This turn is worth $";
    spinAmount = 100 * ( rand()% FIVE + 1);
    cout << spinAmount << endl;
}

    void processGuess(const string& secretWord,
            string& currentWord, string& wrongChars,
            string& rightChars, int spinAmount,
    int& dollarsWon)
{
    char guess;
    int correctCount(0);
    // input a guess from player
    //cout << "Pick a letter: ";
    guess = pickLetter(rightChars);

    // update current word with newly correctly guessed letter
    // and count the number of those letters
    for (unsigned n = 0; n < secretWord.length(); n++)
        if (secretWord[n] == guess)
        {
        currentWord[n] = guess;
        correctCount++;
    }

    if (correctCount > 0)
    {
        // increase earnings if guess was in the secret word
        dollarsWon += (correctCount * spinAmount);
        // add letter in rightChars
        rightChars += guess;
    }
    else
    // add wrong guess to the wrongChars string
    wrongChars += guess;
}

char pickLetter(const string& rightChars)
{
    char guess;
    unsigned loc;
    cout << "Enter your next letter: ";
    cin >> guess;
    loc = rightChars.find(guess);
    while ( loc != string::npos )
    {
    cout << "You must choose another letter: ";
    cin >> guess;
    loc = rightChars.find(guess);
    }
    return guess;
}

void showResults(const string& secretWord,
        const string& currentWord, int& dollarsWon,
        char& ans)
{
    cout << "\nThe secret word was " << secretWord << endl;

    if (currentWord == secretWord)
        cout << "Congratulations! \nYou won $" << dollarsWon;
    else<br>     {
        cout << "You've made 8 incorrect guesses and " <<
        "lost all your earnings.\n";
    dollarsWon = 0;
        }
        cout << endl;
        cout << "Do you want to play again ('y' or 'n')?\n";
        cin >> ans;
}