Bulls and Cows do not display

I’ve gotten this far in the course and when I created the switch statement, and changed the for loop to a while loop, my bulls and cows stopped displaying when a guess is entered and I never get to game won or play again.

I’ve looked all over to find a thread and even ran through each line of the code to see where I was off, but can’t seem to find anything.

Any help is greatly appreciated!

Please post your code so we can see what’s going on and help you debug.

My apologies, I would forget the most important part.

Main.cpp:

#include
#include
#include “FBullCowGame.h”

using FText = std::string;
using int32 = int;

void PrintIntro();
void PlayGame();
FText GetValidGuess();
bool AskToPlayAgain();

FBullCowGame BCGame;

int main()
{
bool bPlayAgain = false;
do {
PrintIntro();
PlayGame();
bPlayAgain = AskToPlayAgain();
}
while (bPlayAgain);

return 0;

}

void PrintIntro()
{
std::cout << “\n\nWelcome to Bulls and Cows, a fun word game.\n”;
std::cout << “Can you guess the " << BCGame.GetHiddenWordLength();
std::cout << " letter isogram I’m thinking of?\n”;
std::cout << std::endl;
return;
}

void PlayGame()
{
BCGame.Reset();
int32 MaxTries = BCGame.GetMaxTries();

while (!BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries) {
	FText Guess = GetValidGuess();

	FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess);

	std::cout << "Bulls = " << BullCowCount.Bulls;
	std::cout << ". Cows = " << BullCowCount.Cows << "\n\n";
}

}

FText GetValidGuess()
{
EGuessStatus Status = EGuessStatus::Invalid_Status;
FText Guess = “”;

do {
	int32 CurrentTry = BCGame.GetCurrentTry();
	std::cout << "Try " << CurrentTry << ". Enter your guess: ";
	std::getline(std::cin, Guess);

	Status = BCGame.CheckGuessValidity(Guess);
	switch (Status)
	{
	case EGuessStatus::Wrong_Length:
		std::cout << "Please enter a " << BCGame.GetHiddenWordLength() << " letter word.\n";
		break;
	case EGuessStatus::Not_Isogram:
		std::cout << "Please enter a word without repeating letters.\n";
		break;
	case EGuessStatus::Not_Lowercase:
		std::cout << "Please enter all lowercase letters.\n";
		break;
	default:
		// Assume Guess is valid
		break;
	}
	std::cout << std::endl;
} while (Status != EGuessStatus::OK);
return Guess;

}

bool AskToPlayAgain()
{
std::cout << "Do you want to play again (y/n)? ";
FText Response = “”;
std::getline(std::cin, Response);
return (Response[0] == ‘y’) || (Response[0] == ‘Y’);
}

FBullCowGame.h:

#pragma once
#include

using FString = std::string;
using int32 = int;

struct FBullCowCount
{
int32 Bulls = 0;
int32 Cows = 0;
};

enum class EGuessStatus
{
Invalid_Status,
OK,
Not_Isogram,
Wrong_Length,
Not_Lowercase
};

class FBullCowGame {
public:
FBullCowGame();

int32 GetMaxTries() const;
int32 GetCurrentTry() const;
int32 GetHiddenWordLength() const;
bool IsGameWon() const;
EGuessStatus CheckGuessValidity(FString) const; 

void Reset();
FBullCowCount SubmitValidGuess(FString);

private:
int32 MyCurrentTry;
int32 MyMaxTries;
FString MyHiddenWord;
bool bGameIsWon;
};

FBullCow.cpp:

#include “FBullCowGame.h”

using int32 = int;

FBullCowGame::FBullCowGame() { Reset(); }

int32 FBullCowGame::GetMaxTries() const { return MyMaxTries; }
int32 FBullCowGame::GetCurrentTry() const { return MyCurrentTry; }
int32 FBullCowGame::GetHiddenWordLength() const { return MyHiddenWord.length(); }
bool FBullCowGame::IsGameWon() const { return bGameIsWon; }

void FBullCowGame::Reset()
{
constexpr int32 MAX_TRIES = 8;
const FString HIDDEN_WORD = “planet”;

MyMaxTries = MAX_TRIES;
MyHiddenWord = HIDDEN_WORD;
MyCurrentTry = 1;
bGameIsWon = false;
return;

}

EGuessStatus FBullCowGame::CheckGuessValidity(FString Guess) const
{
if (false)
{
return EGuessStatus::Not_Isogram;
}
else if (false)
{
return EGuessStatus::Not_Lowercase;
}
else if (Guess.length() != GetHiddenWordLength())
{
return EGuessStatus::Wrong_Length;
}
else
{
EGuessStatus::OK;
}
}

FBullCowCount FBullCowGame::SubmitValidGuess(FString Guess)
{
MyCurrentTry++;
FBullCowCount BullCowCount;
int32 WordLength = MyHiddenWord.length();

for (int32 MHWChar = 0; MHWChar < WordLength; MHWChar++) {
	for (int32 GChar = 0; GChar < WordLength; GChar++) {
		if (Guess[GChar] == MyHiddenWord[MHWChar]) { 
			if (MHWChar == GChar) { 
				BullCowCount.Bulls++;
			}
			else {
				BullCowCount.Cows++;
			}
		}
	}
}
if (BullCowCount.Bulls == WordLength) {
	bGameIsWon == true;
}
else 
{
	bGameIsWon == false;
}
return BullCowCount;

}

Hey Dylan,

So there’s just a few syntactic errors going on here that are pretty common when you are just starting out. First thing I just want to mention - if you take a look at your post you can see how some of the code is in formatted form, like this:

int main()
{
    return 0;
}

And some of your code just looks like regular text. When you paste your code into the webpage, be sure to surround the entire block with “Preformatted Text”; </> in the toolbar.

Now on to the code issues. First, warnings in Visual Studio are your friend. When you build your project, you should get a couple of warnings that look like this:

1>FBullCowGame.cpp
1>e:\dev\bullcows\bullcows\fbullcowgame.cpp(68): warning C4553: '==': result of expression not used; did you intend '='?
1>e:\dev\bullcows\bullcows\fbullcowgame.cpp(73): warning C4553: '==': result of expression not used; did you intend '='?
1>e:\dev\bullcows\bullcows\fbullcowgame.cpp(41): warning C4715: 'FBullCowGame::CheckGuessValidity': not all control paths return a value

The first warning is referring to the line where you are trying to set the value of bGameIsWon in SubmitVAlidGuess. The second warning is referring to another line with the same issue. By using the == operator, you are effectively just evaluating a boolean statement on that line, but not actually setting the value. What you likely intended to do was to actually assign bGameIsWon to a boolean value, which would look like bGameIsWon = true; or bGameIsWon = false;. This is why the warnings are asking about your intention on these lines.

The third warning refers to the fact that in CheckGuessValidity it is possible for the function to run without actually returning a value. Since the design of this function is to return early on any failure cases as indicated by the various error codes defined by the enumeration, you can assume that if you pass all error checking cases the function should return ‘success’, or in this case EGuessStatus::OK. Note that you also are not actually returning EGuessStatus::OK in the final else statement, it is essentially a no-op. So, with these issues in mind, you can fix the code by simply removing the last else statement and simply return EGuessStatus::OK; at the end of the function.

1 Like

Thank you for letting me know how to fix the format. I was wondering why my code looked different in certain spots.

And thank you so much for finding those bugs. I ran through my code for a couple of hours and never stumbled on the “==” issue. The weirdest part was I never got any warnings, which maybe I could have marked an exception at some point.

I really appreciate that you ran through the code and were able to fix issues I had. I definitely have quite a bit learning to do when it comes syntax still. Thank you again!

No problem! It wasn’t until recent compilers that warnings were even generated for unintentional use of the == operator. Runtime syntax issues can be difficult to track down, but the debugger is your friend in these situations. It’s good practice to step through the code line by line with the debugger and observe the values of your variables to see if they make sense.

I forgot to mention, I believe Visual Studio will build incrementally by default. This means that only files that change are re-compiled/linked into the final executable. This may be the reason why you don’t see warnings in the output after making some changes and building the project. Since these projects are small, they don’t take much time to perform a complete rebuild. You can do this by simply right clicking on the project from the Solution Explorer, and choosing ‘Rebuild’. Keep in mind that doing a full rebuild may not always be practical if the projects are very large (i.e. the UE4 engine which you will get to in the next section).

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms