Why is there 2 for loops in SubmitGuess()?

There doesn’t seem to be a need for 2 for loops in SubmitGuess() with the way I have it created.
I got it to work with just one, with no faults in the logic.
Returns correct amount of Cows and Bulls, correctly displays them

 #include "FBullCowGame.h"

//Constructor
FBullCowGame::FBullCowGame()
{
	Reset();
	My_Hidden_Word = "****";

}


//Getters
int32 FBullCowGame::GetMaxTries() const {return MyMaxTries;}

int32 FBullCowGame::GetCurrentTry() const {return MyCurrentTry;}

int32 FBullCowGame::GetWORD_LENGTH() const {return My_Hidden_Word.length();}


//Resetting the game
void FBullCowGame::Reset()
{
	constexpr  int32 MAX_TRIES = 8;
	MyMaxTries = MAX_TRIES;
	MyCurrentTry = 1;	
	return;
	
}

//function for checking if game is won
bool FBullCowGame::bIsGameWon() const 
{
	return false;
}

//function to check for the validity of a guess
bool FBullCowGame::bCheckGuessValidity(FString)
{
	//TODO input handling. Things to check will be: correct word length, no numbers, if word is an isogram.
	//TODO message to console telling error is invalid word is entered
	return false;
}

//recieves a VALID guess, increments turn and return count
FBullCowCount FBullCowGame::SubmitGuess(FString Guess)
{	
	// increment the turn number
	MyCurrentTry++;
	//setup a return variable
	FBullCowCount FBullCowCount{ 0 };
	//TODO setup an error handling variable
	int32 HiddenWordLength = My_Hidden_Word.length();

	//loop through all letters in the guess and compare each letter in the guess against the hidden word
	for (int32 GChar = 0; GChar < HiddenWordLength; GChar++)
	{
		//if letter matches
		if (Guess[GChar] == My_Hidden_Word[GChar])
		{
			FBullCowCount.Bulls++; //increment bulls
		}
		else //if letter does not
		{
			FBullCowCount.Cows++; //increment ows
		}
	}
	return FBullCowCount;	
}
#pragma once
#include <string>

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


// Struct is the same as a class except all members are public while classes can have private members
struct FBullCowCount
{
	int32 Bulls{ 0 };
	int32 Cows{ 0 };
};



class FBullCowGame
{

public:
	FBullCowGame(); //constructor

	// Public method declarations
	//const means it is not modifiable

	int32 GetMaxTries() const;
	int32 GetCurrentTry() const;
	int32 GetWORD_LENGTH() const;
	
	bool bIsGameWon() const ;
	bool bCheckGuessValidity(FString);

	

	//TODO add some type of method for counting bulls and cows, increasing turn number,drawing bulls and >      cows to screen

  FBullCowCount SubmitGuess(FString);



	//error checking/handling(What if wrong word is typed, number inputted, to many letters, etc
	void Reset(); // TODO make more rich return value
	
//
// ^^ Please try and ignore this
private:

	//refer to constructor definintion for initialization.
	int32 MyCurrentTry;
	int32 MyMaxTries;
	FString My_Hidden_Word;
};
#include <iostream>
#include <string>
#include "FBullCowGame.h"

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

//Prototyping functions
void PrintIntro();
void PlayGame();
FText GetGuess();
void PrintGuess(FText Guess);
void PrintBullCowCount(int32 Bulls, int32 Cows);

bool AskToPlayAgain();


FBullCowGame BCGame; // instantiate a new game


//Main method
int main()
{
	bool bPlayAgain{ false };
	do
	{
		BCGame.Reset();
		
		PrintIntro();
		PlayGame();

		bPlayAgain = AskToPlayAgain();
	} while (bPlayAgain);

	return 0;
	
}


void PlayGame()
{
	const int32 MaxTries = BCGame.GetMaxTries();
	//for loop for looping through NUM_OF_TRIES
	//TODO change from for to while loop once we are validating tries
	for (int32 i = 1; i <= MaxTries; i++) {
		FText Guess = GetGuess(); // TODO make loop check for valid guess

		// submit valid guess to the game
		FBullCowCount  BullCowCount = BCGame.SubmitGuess(Guess);

		//print guess and number of bulls and cows
		PrintGuess(Guess);
		int32 Bulls{ BullCowCount.Bulls };
		int32 Cows{ BullCowCount.Cows };
		PrintBullCowCount(Bulls,Cows);
	}
		
}

//Game intro
void PrintIntro()
{
	
	std::cout << "Welcome to Bulls and Cows\n";
	std::cout << "Can you guess the " << BCGame.GetWORD_LENGTH();
	std::cout << " letter isogram I'm thinking of within ";
	int32 MaxTries = BCGame.GetMaxTries();
	std::cout << MaxTries;
	std::cout << " Tries? \n" << std::endl;
	return;
}

//Get guess from console
FText GetGuess()
{
	
	const int32 MaxTries = BCGame.GetMaxTries();
	int32 CurrentTry = BCGame.GetCurrentTry();
	FText Guess = "";

	std::cout << "Try " << CurrentTry << " of " << MaxTries << ".Your Guess: ";
	
	std::getline(std::cin, Guess);
	
	return Guess;
}



//print guess to console
void PrintGuess(FText Guess)
{	
	std::cout << "\nPlayer entered: " << Guess << "\n" << std::endl;
	return;
}

//print bulls and cows to console
void PrintBullCowCount(int32 Bulls,int32 Cows)
{
	std::cout << "Bulls: " << Bulls << " Cows: " << Cows << "\n" << std::endl;
	return;
}

bool AskToPlayAgain()
{
	std::cout << "Do you want to play again (Y/N)";
	FText Response;
	std::getline(std::cin, Response);

	/* TODO Refine if statement for better input handling. Things to check will be make sure correct letter has
 been selected(Y/N), make sure no int was entered,etc
	 Advise user to enter letter(Y/N) again if incorrect, repeat until correct letter is entered.
	*/
	if (Response[0] == 'y' || Response[0] == 'Y') 

	{
		std::cout << std::flush;
		system("CLS");
		return true;
	}
	else
		std::cout << "Goodbye \n";
		return false;

}

My question are:

why does the instructor use 2 for loops?

If it works now should I change it to conform to the instructors code?

If I don’t change it will it mess up the coding later on?

Thanks

Chris

I changed my for-loop to yours and got a wrong bull/cows-count on for instance abcdef as my guess.

My hidden word is planet, so guessing abcdef should have given me 1 bull for the e and 1 cow for the a. Yours gave 1 bull and 5 cows.

Doing it your way only checks the same character of the guess with the same character of the hidden word, so you would miss out on the correct cow-count when the letters are not in the same place. Your code would also always get a cow if the characters in the same place are not the same, which we don’t want.

1 Like

Like Frank said. You need to cycle through both words to get the correct cow and bull count.
Simple example:

wordA abc
wordB def

you first loop picks a from wordA and then you have to compare it with all letters of wordB (your second loop)

Hope that makes sense.

It did. I thank you for the help. I was using an incorrect algorithim to check for the bull cow count.

Once i figured out what the 2 loops were doing then i was able to correct the code.

Basically the first for loop takes the first letter of the hidden word and the second loop compares that letter with the letter of the entered word.

Am i right?

Yes, Correct.

Privacy & Terms