views:

490

answers:

5

I'm writing a hangman game. I'm having a logic fail, both with myself and my game logic. Char guess (the letter the person guessed) isn't being added into the correct memory slot of the vector guessArray. Assume that word is an inputted word by the user.

I assume this would work if guessArray were a raw array. Is there some reason this isn't working with a vector?

//assume that attempts is num of attempts left
void coutWord(int attempts, std::string word, char guess)
{
std::vector<char> guessArray(word.length());


//this is supposed to add the guess to the correct area of guessArray;
//It's not. 

for (int i = 0; i < word.length(); i++) {
    if (guess == word[i]) {
        guessArray[i] = guess;
        std::cout << " " << guessArray[i] << " ";
        continue;
    }

    std::cout << " _ ";
}

std::cout << std::endl << std::endl;
}

EDIT: My objective with this code is to cout all the unguessed spaces AND the guessed spaces in the same for loop. I just need to "remember" previous guesses so that I get correct output. Given word = "Applesauce":

Input: a
a _ _ _ _ _ a _ _ _
Input: p
a p p _ _ _ a _ _ _

etc.

+3  A: 

A vector can be indexed with subscript notation [], and it is stored in contiguous memory. It is an STL container so, like an array, you can have one of any type.

A vector is automatically resized. An array is 'statically' sized, and cannot be easily resized (with the exception of a manual function called to realloc.) You can use a push_back function to handle this, and you can also .reserve() memory ahead of time to save on reallocation.

An array does not track it's own size, whereas a vector has functions that can check this.

If you're unsure of the size of a vector, just go ahead and use .push_back() to add items to handle the matter of automatically sizing. If you reserve a chunk of memory through resize() and then index into it, it's easier to use as an array, but you lose some of the syntatic benefit of using it as a dynamically-sized object.

Tony k
If you .reserve() a chunk of memory, it is technically incorrect to index into it. The reserve() function does not change the vector's conceptual size. The function to use in this case is resize().Very common mistake.
Andrew Shepherd
Thanks, Andrew; edited with correction.
Tony k
A: 

You should use push_back() function. See cpprefererence.com for details.

Also, you cannot simply replace guessArray with C-style array, because you need to excplicitly specify its size with constant known at compile-time, like

int guessArray[25];
Glorphindale
A: 

Answer to the EDIT:

guessArray vector is created locally in the function and hence, previous insertion into the vector will not be available for next attempt. You need to pass the vector by reference and update the vector for every attempt.

void coutWord(std::vector<char>& guessArray, int attempts, std::string word, char guess)

Pseudo code:

void coutWord(std::vector<char>& guessArray, int attempts, std::string word, char guess)
{

    for (int i = 0; i < word.length(); i++) 
    {
     if (guess == word[i]) 
     {
      //its current guess
      //insert and display as well
      guessArray[i] = guess;
        std::cout << " " << guessArray[i] << " ";

     }
     //Check if the previous attempt has already inserted the char ( previous guess)
     else if(guessArray[i] != 0)
     {
      //display previous guess too
      std::cout << " " << guessArray[i] << " ";

     }
     else
     { //not yet guessed
      std::cout << " _ ";
     }
    }

    std::cout << std::endl << std::endl;
}

define vector outside:

std::vector<char> guessArray(word.length());

    coutWord(guessArray, 1, word, 'a');
aJ
+2  A: 

There are fundamental logical flaws in your code, beyond the use of vector or arrays.

There are two tasks you are trying to do here:

  • Update an array of guesses
  • Output the array of guesses

It's easy to get mixed up while you're attempting to do both tasks in the one function. My suggestion to you is to put these into separate functions.

Here's a basic code structure (using functions that you can implement):

int attempts = 0;
std::vector<char> guessArray(word.length());
while( (attempts > maxAttemps) && (!HasFoundWord(guessArray) )
{
   char guess = InputGuess();
   UpdateResults(guessArray, guess, word);
   OutputGuess(guessArray);
   ++attempts;
}

The UpdateResults would have a function signature like:

void UpdateResults(std::vector<char>& guessArray, char guess, const std::string& word)

Once you have separated out the pieces of functionality, you'll find the problem a lot more straightforward to solve.

Andrew Shepherd
A: 

I'm surprised nobody has mentioned it yet, but std::vector isn't an array. It's a resizing contiguous container of elements that can be used for a lot of the same purposes as an array. If you want a wrapped array (and there are any number of reasons to), you should look at boost::array

Promit