Code for completed BullCowGame

Since I have now completed Section 2 of the BullCowGame I hereby submit my code for inspection! :smile:

main.cpp
/*
* This is the console executable that makes use of the BullCow class
* This acts as the view in a MVC pattern, and is responsible for all
* user interaction. For game logic see the FBullCowGame class.
*/

#pragma once

#include <iostream>
#include <string>
#include "FBullCowGame.h"

// To make syntax Unreal friendly
using FText = std::string;
using int32 = int;

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

FBullCowGame BCGame;    // instantiate a new game, which we reuse across plays

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

	return 0;
}

/*
* Introduce game and ask player for word length
*/
void PrintIntro()
{
	std::cout << "\n\nWelcome to Bulls and Cows, a fun word game.\n";
	std::cout << std::endl;
	std::cout << "          }   {         ___ " << std::endl;
	std::cout << "         '(o o)'      '(o o)' " << std::endl;
	std::cout << "   /-------\\ /          \\ /-------\\ " << std::endl;
	std::cout << "  / | BULL |O            O| COW  | \\ " << std::endl;
	std::cout << " *  |-,--- |              |------|  * " << std::endl;
	std::cout << "    ^      ^              ^      ^ " << std::endl;

	// Get word length from player
	QueryWordLength();

	std::cout << "\nCan you guess the " << BCGame.GetHiddenWordLength();
	std::cout << " letter isogram I'm thinking of?\n";
	std::cout << std::endl;
	return;
};

/*
* Ask player for word length
*/
void QueryWordLength()
{
	FText LengthString = "";
	int32 WordLength;

	do
	{
		std::cout << "Choose a hidden word length between 3 and 7: ";
		std::getline(std::cin, LengthString);
		WordLength = std::stoi(LengthString);
		BCGame.SetHiddenWord(WordLength);
	} while (WordLength < 3 || WordLength > 7);
}

/*
* Plays a single game to completion
*/
void PlayGame()
{
	BCGame.Reset();
	int32 MaxTries = BCGame.GetMaxTries();

	// loop asking for guesses while the game
	// is NOT won and there are still tries remaining
	while (!BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries)
	{
		FText Guess = GetValidGuess();

		// Submit valid guess to the game, and receive counts
		FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess);

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

	PrintGameSummary();
}

/*
* continually loop until user gives a valid guess
*/
FText GetValidGuess()
{
	FText Guess = "";
	EGuessStatus Status = EGuessStatus::Invalid_Status;
	do
	{
		// get a guess from the player
		int32 CurrentTry = BCGame.GetCurrentTry();
		std::cout << "Try " << CurrentTry << " of " << BCGame.GetMaxTries();
		std::cout << ". 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\n";
			break;
		case EGuessStatus::Not_Lower_Case:
			std::cout << "Please enter your word with all lower case letters.\n\n";
			break;
		case EGuessStatus::Not_Isogram:
			std::cout << "Please do not repeat any letters in your word.\n\n";
			break;
		default:
			// assuming the guess is valid
			break;
		}
	} while (Status != EGuessStatus::OK);   // Keep looping until we get no errors
	return Guess;
}

/*
* Get players choice for another game
*/
bool AskToPlayAgain()
{
	std::cout << "Do you want to play again with the same hidden word? (y/n)";
	FText Response = "";
	std::getline(std::cin, Response);

	return ((Response[0] == 'y') || (Response[0] == 'Y'));
}

/*
* Print result of the game
*/
void PrintGameSummary()
{
	if (BCGame.IsGameWon())
	{
		std::cout << "You won!\n";
	}
	else
	{
		std::cout << "You lost!\n";
	}
}

FBullCowGame.h

/*
* The game logic (no view code or user interaction)
* The game is a simple guess the word game based on Mastermind
*/

#pragma once

#include <string>

// To make the syntax Unreal friendly
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_Lower_Case
};

class FBullCowGame
{
public:
	FBullCowGame();

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

	void SetHiddenWord(int32);
	void Reset();
	FBullCowCount SubmitValidGuess(FString);


private:
	// See constructor for initialisation.
	int32 MyCurrentTry;

	FString MyHiddenWord;

	bool bGameIsWon;

	bool IsIsogram(FString) const;
	bool IsLowerCase(FString) const;
};

FBullCowGame.cpp

//
// Created by Gary on 13/06/2016.
//

#pragma once

#include "FBullCowGame.h"
#include <map>

// To make the syntax Unreal friendly
#define TMap std::map
using int32 = int;

// The words in the TMap must be isograms!
TMap <int32, FString> WordList{ { 3, "cat" },{ 4, "boat" },{ 5, "zebra" },{ 6, "planet" },{ 7, "changes" } };

FBullCowGame::FBullCowGame() { Reset(); }   // Default constructor

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

/*
* Get the maximum amount of tries based on the word length
*/
int32 FBullCowGame::GetMaxTries() const
{
	TMap <int32, int32> WordLengthToMaxTries{ { 3, 5 },{ 4, 6 },{ 5, 10 },{ 6, 15 },{ 7, 21 } };
	return WordLengthToMaxTries[MyHiddenWord.length()];
}

/*
* Reset game variables
*/
void FBullCowGame::Reset()
{
	MyCurrentTry = 1;
	bGameIsWon = false;
}

/*
* Check the validity of the entered word
*/
EGuessStatus FBullCowGame::CheckGuessValidity(FString Guess) const
{
	if (!IsIsogram(Guess))  // if the guess isn't an isogram
	{
		return EGuessStatus::Not_Isogram;
	}
	else if (!IsLowerCase(Guess)) // if the guess isn't all lowercase
	{
		return EGuessStatus::Not_Lower_Case;
	}
	else if (Guess.length() != GetHiddenWordLength()) // if the guess length is wrong
	{
		return EGuessStatus::Wrong_Length;
	}
	else
	{
		return EGuessStatus::OK;
	}
}

/*
* receives a VALID guess, increments turn and returns count
*/
FBullCowCount FBullCowGame::SubmitValidGuess(FString Guess)
{
	MyCurrentTry++;
	FBullCowCount BullCowCount;
	int32 WordLength = MyHiddenWord.length();   // assuming the same length as guess

												// loop through all the letters in the hidden word
	for (int32 MHWChar = 0; MHWChar < WordLength; MHWChar++)
	{
		// Compare letters against the guess
		for (int32 GChar = 0; GChar < WordLength; GChar++)
		{
			// if they match then
			if (Guess[GChar] == MyHiddenWord[MHWChar])
			{
				if (MHWChar == GChar)
				{               // if they are in the same place
					BullCowCount.Bulls++;   // increment bulls
				}
				else
				{
					BullCowCount.Cows++;    // must be a cow
				}

			}
		}
	}
	if (BullCowCount.Bulls == WordLength)
	{
		bGameIsWon = true;
	}
	else
	{
		bGameIsWon = false;
	}

	return BullCowCount;
}
1 Like

Just finished Bull Cow game section. Here is the link to my completed files.

Done with Section 2!
Added a few of my own extra features to the game.
Relies on Windows functionality for console color changes (apologies to mac users).
Has a 60 word list divided into 3 difficulties.
Gives the player additional color coded based hints for Bulls and Cows.
Has a win screen with a score and a loss screen that lets the user know what the word was.
Also has replaces the ascii Bull and Cow with a large ascii cow face.

main.cpp

/* This is the console executable that makes use of the FBullCowGame class.
This acts as the view in a MVC pattern, and is responsible for all user interactions.
For game logic see the FBullCowGame class.
-Zaptruder
*/

#include <iostream>
#include <string>
#include "FBullCowGame.h"
#include <windows.h>

// to make syntax Unreal Engine 4 friendly
using FText = std::string;
using int32 = int;

// Prototyping above main to make all functions available.
void PrintIntro();
void PlayGame();
FText GetValidGuess();
bool AskToPlayAgain();
void GameSummary();
void GetGameDifficulty();
void SetColor(int32);
void BullCowPositionHint(FText);

//instantiate (make instance of) FBullCowGame
FBullCowGame BCGame; 

//entry point for our application
int main ()
{
	bool bPlayAgain = false;
	do {
		PrintIntro();
		GetGameDifficulty();
		PlayGame();
		bPlayAgain = AskToPlayAgain();
	} while (bPlayAgain == true);
	return 0; // exit application
}

// Introduce the game
void PrintIntro()
{
	std::cout << "\nWelcome to 'BULLS AND COWS' - A Fun Word Game\n";
	std::cout << "This is a game about guessing isograms, which are words without repeating letters.\n";
	std::cout << std::endl;
	SetColor(240);
	std::cout << "                                                 " << std::endl;
	std::cout << "              /~~~~~\\        /~~~~~\\             " << std::endl;
	std::cout << "             |    (~'        ~~~)   |            " << std::endl;
	std::cout << "              \\    \__________/    /              " << std::endl;
	std::cout << "              /~::::::::         ~\\              " << std::endl;
	std::cout << "   /~~~~~~~-_| ::::::::             |_-~~~~~~~\\  " << std::endl;
	std::cout << "  \\ ======= /|  ::A::;      A     :|\\ ====== /   " << std::endl;
	std::cout << "   ~-_____-~ |  _----------------_::| ~-____-~   " << std::endl;
	std::cout << "             |/~                  ~\\|            " << std::endl;
	std::cout << "             /                      \\            " << std::endl;
	std::cout << "            (        ()    ()        )           " << std::endl;
	std::cout << "             `\\                   ./'            " << std::endl;
	std::cout << "               ~-_______________-~               " << std::endl;
	std::cout << "                     /~~~~\\                      " << std::endl;
	std::cout << "                    |      |                     " << std::endl;
	std::cout << "                    |      |                     " << std::endl;
	std::cout << "                   (________)                    " << std::endl;
	std::cout << "                       ()                        " << std::endl;
	std::cout << "                                                 " << std::endl;
	SetColor(7);
	return;
}

//Call the necessary functions to get the player guessing.
void PlayGame()
{
	BCGame.Reset(); //reset to initialize with requested game difficulty.
	
	// The isogram that you're guessing has [ X letters ] in it. Good Luck! (where [ X letters ] has a white background)
	std::cout << "\nThe isogram that you're guessing has ";
	SetColor(240);
	std::cout << " " << BCGame.GetWordLength() << " letters ";
	SetColor(7);
	std::cout << " in it. Good luck!\n";
	
	int32 MaxTries = BCGame.GetMaxTries();
	FBullCowCount BullCowCount;
	
	// loop to allow the player to take a number of guesses
	while(!BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries)
	{
		FText Guess = GetValidGuess(); 
		BullCowCount = BCGame.SubmitValidGuess(Guess);
	
		std::cout << " ";

		//Show the player the Bull and Cow positions via background color changes.
		BullCowPositionHint(Guess);
		SetColor(160);
		std::cout << "Bulls = " << BullCowCount.Bulls << " (CORRECT letters in CORRECT places). \n";
		SetColor(79);
		std::cout << "Cows = " << BullCowCount.Cows << " (CORRECT letters in WRONG places). \n";
		SetColor(7);
		std::cout << "Misses = " << Guess.length() - BullCowCount.Bulls - BullCowCount.Cows << " (WRONG letters). \n\n";
	}
	//once game finishes, summarize the game.
	GameSummary();
	return;
}

//designed to set the game difficulty, which determines which isogram list the game chooses.
void GetGameDifficulty()
{
	FText PlayerDifficulty ="";
	int32 GameDifficulty;
	
	//Prompt for difficulty 1=Easy, 2=Medium, 3=Hard
	do {
		std::cout << "\nSet the difficulty of the game.\n";
		//EASY
		std::cout << "1 = ";
		SetColor(160);
		std::cout << "Easy (5 to 6 letter words)\n";
		SetColor(7);
		//MEDIUM
		std::cout << "2 = ";
		SetColor(224);
		std::cout << "Medium (7 to 8 letter words)\n";
		SetColor(7);
		//HARD
		std::cout << "3 = ";
		SetColor(192);
		std::cout << "Hard (9 to 12 letter words)\n";
		SetColor(7);
		
		std::cout << "\n";

		//get and consume input and set difficulty to input.
		std::getline(std::cin, PlayerDifficulty);	//Get console input	for difficulty.
		GameDifficulty = std::stoi(PlayerDifficulty); //turn console input string into a sanitized integer
	} while (GameDifficulty < 1 || GameDifficulty > 3); //while first character value != 1, 2, 3

	BCGame.SetDifficulty((int)GameDifficulty);	//set difficulty to requested.
}

//Prompts the user for a Guess and returns that FText
FText GetValidGuess()
{
	EGuessStatus Status = EGuessStatus::Invalid;
	FText GuessInput;
	do {
		// get a guess from the player
		std::cout << "\nATTEMPT " << BCGame.GetCurrentTry() << "/" << BCGame.GetMaxTries() << ".\nPlease enter a guess: "; // "ATTEMPT #/#.\nPlease enter a guess: "
		std::getline(std::cin, GuessInput);

		//Ensure guess is valid
		Status = BCGame.CheckGuessValid(GuessInput);
		switch (Status)
		{
		case EGuessStatus::Not_Isogram:
			std::cout << "Please enter an isogram (a word with all different letters).\n";
			break;
		case EGuessStatus::Incorrect_Length:
			std::cout << "Please enter a " << BCGame.GetWordLength() << " letter word.\n";
			break;
		case EGuessStatus::Not_Alphabetical:
			std::cout << "Please enter a word with only alphabetical characters.\n";
			break;
		case EGuessStatus::Already_Attempted:
			std::cout << "This guess has already been attempted. Try a different word.\n";
			break;
		default:
			break;
		}
		std::cout << std::endl;
	} while (Status != EGuessStatus::OK);
	return GuessInput;
}

// Asks the player to play again.
bool AskToPlayAgain()
{
	FText PlayAgainAnswer;
	std::cout << "Do you want to play again? Y/N: ";
	std::getline(std::cin, PlayAgainAnswer);
	std::cout << std::endl;
	return (PlayAgainAnswer[0] == 'y') || (PlayAgainAnswer[0] == 'Y');
}

//Summarizes the game, giving the player win/lose messages.
void GameSummary()
{
	if (BCGame.IsGameWon()) { //On Win: Display Message and Give score.
		SetColor(47);
		std::cout << "CONGRATULATIONS! You've guessed correctly and WON THE GAME!\n";
		std::cout << "                                                           " << std::endl;
		std::cout << "                   /~~~~~\\        /~~~~~\\                  " << std::endl;
		std::cout << "                  |    (~'        ~~~)   |                 " << std::endl;
		std::cout << "                   \\    \__________/    /                   " << std::endl;
		std::cout << "                   /~::::::::         ~\\                   " << std::endl;
		std::cout << "        /~~~~~~~-_| ::::::::             |_-~~~~~~~\\       " << std::endl;
		std::cout << "       \\ ======= /|  ::A::;      A     :|\\ ====== /        " << std::endl;
		std::cout << "        ~-_____-~ |  _----------------_::| ~-____-~        " << std::endl;
		std::cout << "                  |/~                  ~\\|                 " << std::endl;
		std::cout << "                  /                      \\                 " << std::endl;
		std::cout << "                 (        ()    ()        )                " << std::endl;
		std::cout << "                  `\\                   ./'                 " << std::endl;
		std::cout << "                    ~-_______________-~                    " << std::endl;
		std::cout << "                          /~~~~\\                           " << std::endl;
		std::cout << "                         |      |                          " << std::endl;
		std::cout << "                         |      |                          " << std::endl;
		std::cout << "                        (________)                         " << std::endl;
		std::cout << "                            ()                             " << std::endl;
		std::cout << "                                                           " << std::endl;
		SetColor(7);
		std::cout << "You won in ";
		std::cout << BCGame.GetCurrentTry()-1;
		std::cout << " out of ";
		std::cout << BCGame.GetMaxTries();
		std::cout << " Attempts!   Your final score is: ";
		std::cout << ((BCGame.GetGameDifficulty() * (BCGame.GetMaxTries() - BCGame.GetCurrentTry() + 2)) * 10);
		std::cout << " " << std::endl;
		std::cout << "\n";
	}
	else { //On Loss: Commiserate the player and reveal isogram
		std::cout << "Unfortunately you haven't guessed in the required number of attempts.\nThe isogram was \"";
		SetColor(160); //set Isogram reveal to bright green
		std::cout << BCGame.GetHiddenWord();
		SetColor(7); //set back to default colors
		std::cout << ".\"\nBetter luck next time!\n\n";
	}
}

//Return the player guess with color coded position hints for Bulls and Cows
void BullCowPositionHint(FText Guess){
	for (int32 i = 0; i < (int32)Guess.length(); i++)	
	{	// Bright Green for Bulls			
		if (BCGame.BullCowPosition[i] == 1) {
			SetColor(160);
			char c = toupper(Guess[i]);
			std::cout << c;
		} // Red for Cows
		else if (BCGame.BullCowPosition[i] == 2) {
			SetColor(79);
			char c = toupper(Guess[i]);
			std::cout << c;
		} // Black for Misses
		else {
			SetColor(7);
			char c = toupper(Guess[i]);
			std::cout << c;
		}
	}
	std::cout << "\n\n";
}

// Sets console color
void SetColor(int32 value) {
/*
	0: Black
	1: Blue
	2: Green
	3: Cyan
	4: Red
	5: Purple
	6: Yellow (Dark)
	7: Default white
	8: Gray/Grey
	9: Bright blue
	10: Brigth green
	11: Bright cyan
	12: Bright red
	13: Pink/Magenta
	14: Yellow
	15: Bright white
	
	+
	
	16: blue background
	32: green background
	48: Cyan
	64: Red
	80: Purple
	96: Yellow (Dark)
	112: Default white
	128: Gray/Grey
	144: Bright blue
	160: Brigth green
	176: Bright cyan
	192: Bright red
	208: Pink/Magenta
	224: Yellow
	240: Bright white
*/
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), value);
}

FBullCowGame.cpp

#include "FBullCowGame.h"
#include <time.h>

FBullCowGame::FBullCowGame() {Reset();} //see rest for constructor initialization values
int32 FBullCowGame::GetCurrentTry() const {return MyCurrentTry;}
int32 FBullCowGame::GetWordLength() const { return MyHiddenWord.length(); }
int32 FBullCowGame::GetGameDifficulty() const { return GameDifficulty; }
bool FBullCowGame::IsGameWon() const {return bGameWon;}
FString FBullCowGame::GetHiddenWord() const { return MyHiddenWord; }

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

//Set the difficulty value
void FBullCowGame::SetDifficulty(int Difficulty)
{
	GameDifficulty = Difficulty;
}

// Returns a random isogram from a list, accounting for difficulty choice.
FString FBullCowGame::GetNewHiddenWord() 
{
	//Get random integer based on time
	srand(time(NULL));
	int32 Random = std::rand() % 20;

	// Give word based on difficulty.
	if (GameDifficulty == 1) { // Easy
		MyMaxTries = 10;
		return EasyIsogramList[Random];
	} else if (GameDifficulty == 2) { // Medium 
		MyMaxTries = 15;
		return MediumIsogramList[Random];
	} else {  // Hard
		MyMaxTries = 20;
		return HardIsogramList[Random];
	}
}

// Checks to ensure that the player's guess input can be used.
EGuessStatus FBullCowGame::CheckGuessValid(FString Guess)
{
	if (Guess.length() != GetWordLength()) {// if the guess isn't an isogram
		return EGuessStatus::Incorrect_Length;
	} else if (!IsAlphabetical(Guess)) {//// if the guess has non-alphabet characters
		return EGuessStatus::Not_Alphabetical;
	} else if (!IsIsogram(Guess)) { // if the guess is shorter than word length
		return EGuessStatus::Not_Isogram;
	} else if (AlreadyAttempted(Guess)) { // if the guess has already been attempted
		return EGuessStatus::Already_Attempted;
	} else {
		return EGuessStatus::OK;
	}
}

bool FBullCowGame::IsIsogram(FString Guess)  
{ 		
	// treat 0 and 1 letter words as isograms
	if (Guess.length() <= 1) { return true; }
	
	/*Take each character of 'Guess' and add them to the map table.
	Before doing so, check to see if this value is already in place. Return false if so.*/
	TMap <char, int32> LetterSeen; //setup the map
	for (auto Letter : Guess) //For each Guess character
	{
		Letter = tolower(Letter);
		if (LetterSeen[Letter] == 0) //if the guess character count is 0
		{
			//add guess character to map
			LetterSeen[Letter] = 1;
		}
		else { return false; }
	}
	return true;
}

bool FBullCowGame::IsAlphabetical(FString Guess)  
{
	for (int32 GuessCNo = 0; GuessCNo < (int32)Guess.length(); GuessCNo++)
	{ //Alphabetical if guess is upper case A to Z or lower case A to Z.
		if ((Guess[GuessCNo] >= 'A' && Guess[GuessCNo] <= 'Z') || (Guess[GuessCNo] >= 'a' && Guess[GuessCNo] <= 'z')) {
			return true;
		}
	}
	return false;
}

bool FBullCowGame::IsLowerCase(FString Guess) 
{
	if (Guess.length() <= 1) { return true; }
	for (auto Letter : Guess) 
	{ 
		if (!islower(Letter)) { return false; }
	} 
	return true;
}

bool FBullCowGame::AlreadyAttempted(FString Attempt) 
{
	for (int i = 0; i < GetMaxTries(); i++) {
		// Check to see if the attempt is already on the list
		if (Attempt == AlreadyAttemptedList[i]) return true;
		// Otherwise add the attempt to the list.
		else AlreadyAttemptedList[i] = Attempt;
	}
	return false;
}

// initialize all the values in the game.
void FBullCowGame::Reset()
{
	MyCurrentTry = 1;
	MyHiddenWord = GetNewHiddenWord(); //Accept Difficulty change
	bGameWon = false;

	std::vector<int32> bullcowpositioninit(GetWordLength(), 0);
	BullCowPosition = bullcowpositioninit;

	std::vector<FString> attemptlistinit(GetMaxTries(), "");
	AlreadyAttemptedList = attemptlistinit;
	return;
}

//receives a VALID guess, increments turn and returns count
//Enter each letter into a BullCowPosition as Guess is read, and marks them as 0(nothing) 1(bull), 2(cow).
FBullCowCount FBullCowGame::SubmitValidGuess(FString Guess)
{
	MyCurrentTry++;
	FBullCowCount BullCowCount;
	int32 WordLength = MyHiddenWord.length();

	//for each letter of Guess
	for (int32 GuessCNo = 0; GuessCNo < WordLength; GuessCNo++) 
	{
		//Guess Character defaults to 0 (black).
		BullCowPosition[GuessCNo] = 0;
		//compare letters against the hidden word
		for (int32 HiddenCNo = 0; HiddenCNo < WordLength; HiddenCNo++) {
			//if GuessCharacterNumber matches HiddenCharacterNumber either lower or UPPER case
			if (Guess[GuessCNo] == MyHiddenWord[HiddenCNo] || (Guess[GuessCNo] == MyHiddenWord[HiddenCNo] - 32)) {
				//and if they're in the same place.
				if (GuessCNo == HiddenCNo) {
					//increment bulls
					BullCowCount.Bulls++;
					BullCowPosition[GuessCNo] = 1; //set the guess character position to 1 (green).
				} else {
					//increment cows if not.
					BullCowCount.Cows++;
					BullCowPosition[GuessCNo] = 2;//set the guess character position to 2 (red).
				}
			}
		}
	}
	if (BullCowCount.Bulls == GetWordLength()) {
		bGameWon = true;
	}
	return BullCowCount;
}

FBullCowGame.h

/*	The game logic (no view code or direct interaction).
	the game is a simple guess the word game based on Mastermind
        -Zaptruder
*/

#pragma once
#include <string>
#include <map>
#include <vector>
#define TMap std::map

// to make syntax Unreal Engine 4 friendly
using FString = std::string;
using int32 = int;

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

enum class EGuessStatus
{
	Invalid,
	OK,
	Not_Isogram,
	Incorrect_Length,
	Not_Alphabetical,
	Not_Lower_Case,
	Already_Attempted
};

class FBullCowGame {
public:
	
	std::vector<int32> BullCowPosition; //<LetterPosition, Bull/Cowtype> Used to provide bulls/cows with colour.

	// constructor
	FBullCowGame(); 

	//Getters
	int32 GetMaxTries() const;
	int32 GetCurrentTry() const;
	int32 GetWordLength() const; //Lets the player know how long the word length setting is.
	bool IsGameWon() const; 
	EGuessStatus CheckGuessValid(FString); //Ensures that the player enters a valid guess
	FString GetHiddenWord() const;
	int32 GetGameDifficulty() const;

	//Setters
	void Reset();
	FBullCowCount SubmitValidGuess(FString); //Allows the player to input their guess.
	void SetDifficulty(int);

// Ignore this for now
private:
	int32 MyCurrentTry; //see Constructor > Reset();
	int32 MyMaxTries; //see Constructor > Reset();
	FString MyHiddenWord;
	int GameDifficulty = 1;
	bool bGameWon;
	bool IsIsogram(FString);
	bool IsAlphabetical(FString);
	bool IsLowerCase(FString);
	bool AlreadyAttempted(FString);
	FString GetNewHiddenWord();
	std::vector<FString> AlreadyAttemptedList; //<LetterPosition, Bull/Cowtype> Used to provide bulls/cows with colour.

//ISOGRAM WORD LISTS
	TMap <int32, FString> EasyIsogramList{ // 5 - 6 letter words
		{ 0, "after" },
		{ 1, "chokes" },
		{ 2, "author" },
		{ 3, "ground" },
		{ 4, "black" },
		{ 5, "horse" },
		{ 6, "guild" },
		{ 7, "faces" },
		{ 8, "facet" },
		{ 9, "cards" },
		{ 10, "olden" },
		{ 11, "plants" },
		{ 12, "planet" },
		{ 13, "dunce" },
		{ 14, "stream" },
		{ 15, "waiter" },
		{ 16, "twice" },
		{ 17, "thrice" },
		{ 18, "sights" },
		{ 19, "formed" },
		{ 20, "parent" },
	};

	TMap <int32, FString> MediumIsogramList{ // 7 - 8
		{ 0, "shocked" },
		{ 1, "choking" },
		{ 2, "playing" },
		{ 3, "personal" },
		{ 4, "bankrupt" },
		{ 5, "disturb" },
		{ 6, "document" },
		{ 7, "republic" },
		{ 8, "disgrace" },
		{ 9, "hospital" },
		{ 10, "destroy" },
		{ 11, "flouride" },
		{ 12, "trample" },
		{ 13, "infamous" },
		{ 14, "complain" },
		{ 15, "farsight" },
		{ 16, "judgment" },
		{ 17, "mistake" },
		{ 18, "consider" },
		{ 19, "vouched" },
		{ 20, "parents" },
	};

	TMap <int32, FString> HardIsogramList  { // 9 - 10 letter words
		{ 0, "conjugate" },
		{ 1, "artichokes" },
		{ 2, "authorizes" },
		{ 3, "background" },
		{ 4, "bankruptcy" },
		{ 5, "binoculars" },
		{ 6, "blackhorse" },
		{ 7, "atmosphere" },
		{ 8, "boyfriends" },
		{ 9, "campground" },
		{ 10, "clothespin" },
		{ 11, "complaints" },
		{ 12, "conjugated" },
		{ 13, "despicably" },
		{ 14, "desirably" },
		{ 15, "downstream" },
		{ 16, "dumbwaiter" },
		{ 17, "duplicates" },
		{ 18, "farsighted" },
		{ 19, "formidable" },
		{ 20, "godparents" },
	};
};

Hello! Here is my code for the section 02 Bull & Cow game.

I’ve added :

  • A list of word of diferent length
  • Player can choose the hidden word length
  • Player can get a hint (First letter of the word) when he is at half his max try.

main.cpp

/* This is a console executable. It makes use of the BullCow Executable.
It’s responsible for all interaction with the user :
Display text/feedback, take input from player*/

#pragma once
#include <iostream>
#include <string>
#include "FBullCowGame.h"
#include <ctime>

// To make syntax unreal friendly
using FText = std::string;
using int32 = int;

// function outside a class
void PrintIntro();
void PlayGame();
int32 UserChooseWordLength();
FText GetValidGuess();
void PrintGameSummary();
bool AskIfHint();
void PrintHint();
bool AskToPlayAgain();

FBullCowGame BCGame; // instantiate a new game

// Entry point for the application
int main()
{
	bool bPlayAgain = false;
	PrintIntro();
	do {
		PlayGame();
		bPlayAgain = AskToPlayAgain();
		std::cout << std::endl;
	} while (bPlayAgain);

	return 0; //ends the application
	
}

void PrintIntro() {
	// ART
	std::cout << std::endl;
	std::cout << std::endl;
	std::cout << "	B" << std::endl;
	std::cout << "	B U" << std::endl;
	std::cout << "	B U L" << std::endl;
	std::cout << "	B U L L" << std::endl;
	std::cout << "	B U L L &" << std::endl;
	std::cout << "	B U L L & C" << std::endl;
	std::cout << "	B U L L & C O" << std::endl;
	std::cout << std::endl;
	std::cout << "	B U L L & C O W" << std::endl;
	std::cout << std::endl;
	std::cout << "	  U L L & C O W" << std::endl;
	std::cout << "	    L L & C O W" << std::endl;
	std::cout << "	      L & C O W" << std::endl;
	std::cout << "	        & C O W" << std::endl;
	std::cout << "	          C O W" << std::endl;
	std::cout << "	            O W" << std::endl;
	std::cout << "	              W" << std::endl;

	// Introducing the game to user
	std::cout << "\n\nWelcome to Bulls and Cows, a word and mind game.\n";
	// Question
	std::cout << "Can you guess the isogram word I'm thinking of?\n";
	std::cout << std::endl;
	return;
}

void PlayGame() {
	srand(time(NULL)); // For random

	BCGame.Reset(); // Reset game
	BCGame.SetMyWordLength(UserChooseWordLength()); // Ask the user for the length of the hidden word he wants to play with
	BCGame.SetHiddenWord(); // Sets a hidden word of the given length
	std::cout << std::endl;

	// Tells the player how many tries he has to guess the hidden word
	int32 MaxTries = BCGame.GetMaxTries();
	std::cout << "OK! Let's play!!\n";
	std::cout << "You have " << MaxTries << " tries to guess the " << BCGame.GetHiddenWordLenght();
	std::cout << " letter hidden word. Good Luck!\n\n";

	// Loop asking for guesses while
	// The game is NOT won and there are still tries remaining
	bool bHintGiven = false;
	while ( !BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries) {

		// Asks the player if he wants a hint and gives it to him
		if (BCGame.GetCurrentTry() > MaxTries / 2 && !bHintGiven) {
			if (AskIfHint()) {
				PrintHint();
				bHintGiven = AskIfHint;
			}
		}

		FText Guess = GetValidGuess();
		// Submit valid guess to the game
		FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess);

		// Tells the player how many bull and cows his guess got him
		std::cout << "Bulls = " << BullCowCount.Bulls << std::endl;
		std::cout << "Cows = " << BullCowCount.Cows << "\n\n";
	}

	PrintGameSummary();

	return;
}

// Asks the player the length of the hidden word he wants to play with
int32 UserChooseWordLength()
{
	int32 WordLength;
	std::cout << "Please choose the hidden word's length (" << BCGame.GetWordLengthMin() << " to " << BCGame.GetWordLengthMax() << ") : ";
	
	do
	{
		std::cin >> WordLength;
		if (!std::cin) // Ignores the user input if not a number
		{
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			std::cout << "What the **** did you just input??\n";
		}
		if (WordLength < BCGame.GetWordLengthMin() || WordLength > BCGame.GetWordLengthMax()) // Asks the user another input if the one entered was not valid
		{
			std::cout << "Word length has to be in the range " << BCGame.GetWordLengthMin() << " to " << BCGame.GetWordLengthMax() << " :\n";
		}
	} while (WordLength < BCGame.GetWordLengthMin() || WordLength > BCGame.GetWordLengthMax());

	BCGame.SetMyWordLength(WordLength);

	return WordLength;
};

// loops continually until user enters valid guess
FText GetValidGuess() {
	
	FText Guess = "";
	EGuessStatus Status = EGuessStatus::Invalid_Status;

	do {
		// Getting an input from the user
		int32 CurrentTry = BCGame.GetCurrentTry();

		std::cout << "Try " << CurrentTry << " of " << BCGame.GetMaxTries() << " : Enter your guess : ";
		std::cin >> Guess;

		Status = BCGame.CheckGuessValidity(Guess);

		switch (Status) {
		case EGuessStatus::Wrong_Lenght:
			std::cout << "\nPlease enter a " << BCGame.GetHiddenWordLenght() << " letter word.\n";
			break;
		case EGuessStatus::Not_Lowercase:
			std::cout << "\nPlease only use lowercase.\n";
			break;
		case EGuessStatus::Not_Isogram:
			std::cout << "\nPlease enter a word without any repeating letters.\n";
			break;
		default:
			// assume the guess is valid
			break;
		}
		std::cout << std::endl;
	} while (Status != EGuessStatus::OK); //keep looping until valid guess
	return Guess;
}

// Ask the player if he wants a hint
bool AskIfHint() {
	std::cout << "Do you want a hint? (y/n) : ";
	FText Response = "";
	std::cin >> Response;
	std::cout << std::endl;

	return (Response[0] == 'y' || Response[0] == 'Y');
}
void PrintHint() {
	std::cout << "Hint : The first letter of the word is \"" << BCGame.GetHint() << "\"\n\n";
}

bool AskToPlayAgain()
{
	std::cout << "Do you want to play again? (y/n) : ";
	FText Response = "";
	std::cin >> Response;
	std::cout << std::endl;

	return (Response[0] == 'y' || Response[0] == 'Y');
}

void PrintGameSummary()
{
	if (BCGame.IsGameWon()) {
		std::cout << "CONGRADULATIONS!! YOU WON!\n\n";
	}
	else {
		std::cout << "SORRY! YOU LOSE...\n\n";
	}
}/* This is a console executable. It makes use of the BullCow Executable.
It's responsible for all interaction with the user :
Display text/feedback, take input from player*/

#pragma once
#include <iostream>
#include <string>
#include "FBullCowGame.h"
#include <ctime>

// To make syntax unreal friendly
using FText = std::string;
using int32 = int;

// function outside a class
void PrintIntro();
void PlayGame();
int32 UserChooseWordLength();
FText GetValidGuess();
void PrintGameSummary();
bool AskIfHint();
void PrintHint();
bool AskToPlayAgain();

FBullCowGame BCGame; // instantiate a new game

// Entry point for the application
int main()
{
	bool bPlayAgain = false;
	PrintIntro();
	do {
		PlayGame();
		bPlayAgain = AskToPlayAgain();
		std::cout << std::endl;
	} while (bPlayAgain);

	return 0; //ends the application
	
}

void PrintIntro() {
	// ART
	std::cout << std::endl;
	std::cout << std::endl;
	std::cout << "	B" << std::endl;
	std::cout << "	B U" << std::endl;
	std::cout << "	B U L" << std::endl;
	std::cout << "	B U L L" << std::endl;
	std::cout << "	B U L L &" << std::endl;
	std::cout << "	B U L L & C" << std::endl;
	std::cout << "	B U L L & C O" << std::endl;
	std::cout << std::endl;
	std::cout << "	B U L L & C O W" << std::endl;
	std::cout << std::endl;
	std::cout << "	  U L L & C O W" << std::endl;
	std::cout << "	    L L & C O W" << std::endl;
	std::cout << "	      L & C O W" << std::endl;
	std::cout << "	        & C O W" << std::endl;
	std::cout << "	          C O W" << std::endl;
	std::cout << "	            O W" << std::endl;
	std::cout << "	              W" << std::endl;

	// Introducing the game to user
	std::cout << "\n\nWelcome to Bulls and Cows, a word and mind game.\n";
	// Question
	std::cout << "Can you guess the isogram word I'm thinking of?\n";
	std::cout << std::endl;
	return;
}

void PlayGame() {
	srand(time(NULL)); // For random

	BCGame.Reset(); // Reset game
	BCGame.SetMyWordLength(UserChooseWordLength()); // Ask the user for the length of the hidden word he wants to play with
	BCGame.SetHiddenWord(); // Sets a hidden word of the given length
	std::cout << std::endl;

	// Tells the player how many tries he has to guess the hidden word
	int32 MaxTries = BCGame.GetMaxTries();
	std::cout << "OK! Let's play!!\n";
	std::cout << "You have " << MaxTries << " tries to guess the " << BCGame.GetHiddenWordLenght();
	std::cout << " letter hidden word. Good Luck!\n\n";

	// Loop asking for guesses while
	// The game is NOT won and there are still tries remaining
	bool bHintGiven = false;
	while ( !BCGame.IsGameWon() && BCGame.GetCurrentTry() <= MaxTries) {

		// Asks the player if he wants a hint and gives it to him
		if (BCGame.GetCurrentTry() > MaxTries / 2 && !bHintGiven) {
			if (AskIfHint()) {
				PrintHint();
				bHintGiven = AskIfHint;
			}
		}

		FText Guess = GetValidGuess();
		// Submit valid guess to the game
		FBullCowCount BullCowCount = BCGame.SubmitValidGuess(Guess);

		// Tells the player how many bull and cows his guess got him
		std::cout << "Bulls = " << BullCowCount.Bulls << std::endl;
		std::cout << "Cows = " << BullCowCount.Cows << "\n\n";
	}

	PrintGameSummary();

	return;
}

// Asks the player the length of the hidden word he wants to play with
int32 UserChooseWordLength()
{
	int32 WordLength;
	std::cout << "Please choose the hidden word's length (" << BCGame.GetWordLengthMin() << " to " << BCGame.GetWordLengthMax() << ") : ";
	
	do
	{
		std::cin >> WordLength;
		if (!std::cin) // Ignores the user input if not a number
		{
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			std::cout << "What the **** did you just input??\n";
		}
		if (WordLength < BCGame.GetWordLengthMin() || WordLength > BCGame.GetWordLengthMax()) // Asks the user another input if the one entered was not valid
		{
			std::cout << "Word length has to be in the range " << BCGame.GetWordLengthMin() << " to " << BCGame.GetWordLengthMax() << " :\n";
		}
	} while (WordLength < BCGame.GetWordLengthMin() || WordLength > BCGame.GetWordLengthMax());

	BCGame.SetMyWordLength(WordLength);

	return WordLength;
};

// loops continually until user enters valid guess
FText GetValidGuess() {
	
	FText Guess = "";
	EGuessStatus Status = EGuessStatus::Invalid_Status;

	do {
		// Getting an input from the user
		int32 CurrentTry = BCGame.GetCurrentTry();

		std::cout << "Try " << CurrentTry << " of " << BCGame.GetMaxTries() << " : Enter your guess : ";
		std::cin >> Guess;

		Status = BCGame.CheckGuessValidity(Guess);

		switch (Status) {
		case EGuessStatus::Wrong_Lenght:
			std::cout << "\nPlease enter a " << BCGame.GetHiddenWordLenght() << " letter word.\n";
			break;
		case EGuessStatus::Not_Lowercase:
			std::cout << "\nPlease only use lowercase.\n";
			break;
		case EGuessStatus::Not_Isogram:
			std::cout << "\nPlease enter a word without any repeating letters.\n";
			break;
		default:
			// assume the guess is valid
			break;
		}
		std::cout << std::endl;
	} while (Status != EGuessStatus::OK); //keep looping until valid guess
	return Guess;
}

// Ask the player if he wants a hint
bool AskIfHint() {
	std::cout << "Do you want a hint? (y/n) : ";
	FText Response = "";
	std::cin >> Response;
	std::cout << std::endl;

	return (Response[0] == 'y' || Response[0] == 'Y');
}
void PrintHint() {
	std::cout << "Hint : The first letter of the word is \"" << BCGame.GetHint() << "\"\n\n";
}

bool AskToPlayAgain()
{
	std::cout << "Do you want to play again? (y/n) : ";
	FText Response = "";
	std::cin >> Response;
	std::cout << std::endl;

	return (Response[0] == 'y' || Response[0] == 'Y');
}

void PrintGameSummary()
{
	if (BCGame.IsGameWon()) {
		std::cout << "CONGRADULATIONS!! YOU WON!\n\n";
	}
	else {
		std::cout << "SORRY! YOU LOSE...\n\n";
	}
}

FBullCowGame.cpp

/* All methods in the BullCow game are defined here. */

#pragma once
#include "FBullCowGame.h"
#include <map>

// To make syntax unreal friendly
#define TMap std::map
using int32 = int;

FBullCowGame::FBullCowGame() { Reset(); } // default constructor

int32 FBullCowGame::GetCurrentTry() const { return MyCurrentTry; }
int32 FBullCowGame::GetWordLengthMin() const { return WordLengthMin; }
int32 FBullCowGame::GetWordLengthMax() const { return WordLengthMax; }
int32 FBullCowGame::GetHiddenWordLenght() const { return MyHiddenWord.length(); }
int32 FBullCowGame::GetMaxTries() const {
	TMap<int32, int32> WordLenghtToMaxTries{ { 3,6 },{ 4,8 },{ 5,9 },{ 6,10 },{ 7, 12 } };
	return WordLenghtToMaxTries[MyHiddenWord.length()];
}
char FBullCowGame::GetHint() const
{
	return MyHiddenWord[0];
}
void FBullCowGame::SetMyWordLength(int32 WordLength)
{
	MyWordLength = WordLength;
	return;
}
void FBullCowGame::SetHiddenWord()
{
	FString HIDDEN_WORD;
	switch (MyWordLength)
	{
	case 3: {
		FString LengthThree[] = {
			"age",
			"arm",
			"art",
			"ate",
			"bat",
			"bag",
			"bed",
			"bet",
			"big",
			"cue",
			"cat",
			"god",
			"hug",
			"mug",
			"one",
			"toe",
			"two"
		};

		int32 num = (rand() % (sizeof(LengthThree) / sizeof(LengthThree[0]))); // Picks a random word in array
		HIDDEN_WORD = LengthThree[num];
		break;
	}
	case 4: {
		FString LengthFour[] = {
			"bath",
			"cake",
			"dark",
			"echo",
			"fact",
			"fart",
			"five",
			"four",
			"hate",
			"hole",
			"jack",
			"math",
			"life",
			"lion",
			"page",
			"part",
			"raid",
			"wave"
		};

		int32 num = (rand() % (sizeof(LengthFour) / sizeof(LengthFour[0]))); // Picks a random word in array
		HIDDEN_WORD = LengthFour[num];
		break;
	}
	case 5: {
		FString LengthFive[] = {
			"basic",
			"black",
			"blast",
			"brave",
			"broke",
			"brick",
			"curse",
			"dwarf",
			"house",
			"magic",
			"mouse",
			"party",
			"place",
			"prick",
			"raven",
			"throw",
			"tiger",
			"trade",
			"train",
			"width",
			"wagon"
		};

		int32 num = (rand() % (sizeof(LengthFive) / sizeof(LengthFive[0]))); // Picks a random word in array
		HIDDEN_WORD = LengthFive[num];
		break;
	}
	case 6: {
		FString LengthSix[] = {
			"binder",
			"cartel",
			"denial",
			"diaper",
			"double",
			"fabric",
			"hijack",
			"ignore",
			"inhale",
			"joking",
			"pickle",
			"praise",
			"volume",
			"walker"
		};

		int32 num = (rand() % (sizeof(LengthSix) / sizeof(LengthSix[0]))); // Picks a random word in array
		HIDDEN_WORD = LengthSix[num];
		break;
	}
	case 7: {
		FString LengthSeven[] = {
			"advisor",
			"aerobic",
			"amplify",
			"bastile",
			"bitches",
			"brioche",
			"choking",
			"dauphin",
			"defocus",
			"ethical",
			"exactly",
			"hacking",
			"harvest",
			"hipster",
			"impulse",
			"intrude",
			"isogram",
			"trading",
			"version"

		};

		int32 num = (rand() % (sizeof(LengthSeven) / sizeof(LengthSeven[0]))); // Picks a random word in array
		HIDDEN_WORD = LengthSeven[num];
		break;
		}
	}
	MyHiddenWord = HIDDEN_WORD;
}

bool FBullCowGame::IsGameWon() const { return bGameIsWon; }

void FBullCowGame::Reset()
{
	MyWordLength = 0;
	MyCurrentTry = 1;
	WordLengthMin = 3;
	WordLengthMax = 7;

	bGameIsWon = false;
	
	return;
}

EGuessStatus FBullCowGame::CheckGuessValidity(FString Guess) const
{
	if (Guess.length() != GetHiddenWordLenght()) // If guess lenght is wrong 
	{
		return EGuessStatus::Wrong_Lenght;
	}
	else if (!IsIsogram(Guess)) // If Guess isn't isogram
	{
		return EGuessStatus::Not_Isogram;
	}
	else if (!IsLowerCase(Guess)) // If Guess isn't lowercase
	{
		return EGuessStatus::Not_Lowercase;
	}
	else
	{
		return EGuessStatus::OK;
	}
}

// receives a valid guess, increments turn  and returns count
FBullCowCount FBullCowGame::SubmitValidGuess(FString UserGuess)
{
	MyCurrentTry++;
	FBullCowCount BullCowCount;
	int32 WordLength = MyHiddenWord.length();

	// loop through all letters in the hidden word

	for (int32 i = 0; i < WordLength; i++) {

		// compare letters with the guess
		for (int32 j = 0; j < WordLength; j++) {
			
			if (UserGuess[i] == MyHiddenWord[j]) {
				if (i == j) { //if they are in the same place
					BullCowCount.Bulls++; // increment bulls
				}
				else {
					BullCowCount.Cows++; // increment Cows
				}

			}
		}

	}
	// Check if game is won
	if (BullCowCount.Bulls == WordLength){
		bGameIsWon = true;
	}
	else {
		bGameIsWon = false;
	}
	return BullCowCount;
}

bool FBullCowGame::IsIsogram(FString Word) const
{
	// 0 or 1 letter input won't be checker for isogram
	if (Word.length() <= 1) { return true; }

	TMap<char, bool> SeenLetter;
	for (auto Letter : Word)
	{
		Letter = tolower(Letter);
		if (SeenLetter[Letter]) { // If the letter is already mapped
			return false; // Word is not Isogram
		}
		else {
			SeenLetter[Letter] = true; // Map it
		}
	}
	return true;
}
bool FBullCowGame::IsLowerCase(FString Word) const
{
	// 0 or 1 letter input won't be checker for isogram
	if (Word.length() <= 1) { return true; }

	for (auto Letter : Word)
	{
		if (!islower(Letter)) {
			return false;
		}
	}
	return true;
}

FBullCowGame.h

/* This Class contains all the methods and variables needed to play a game of bull and cow.
It is responsible for all the fame logics.*/

#pragma once
#include <string>

// To make syntax unreal friendly
using FString = std::string;
using int32 = int;

// Structure for bull and cow count
struct FBullCowCount
{
	int32 Bulls = 0;
	int32 Cows = 0;
};

// Enum of possible status for a user guess
enum class EGuessStatus
{
	Invalid_Status,
	OK,
	Not_Isogram,
	Wrong_Lenght,
	Not_Lowercase,
};

class FBullCowGame {
public:
	FBullCowGame();

	int32  GetCurrentTry() const;
	int32 GetWordLengthMin() const;
	int32 GetWordLengthMax() const;
	int32  GetMaxTries() const;
	int32 GetHiddenWordLenght() const;
	char GetHint() const;
	void SetMyWordLength(int32);
	void SetHiddenWord();

	bool IsGameWon() const;

	void Reset();
	EGuessStatus CheckGuessValidity(FString) const;

	// counts bulls & cows, and increases try # assuming valid guess
	FBullCowCount SubmitValidGuess(FString);

	// Please try and ignore and focus on the interface above ^^
private:
	bool IsIsogram(FString) const;
	bool IsLowerCase(FString) const;

	// Initialized in the constructor
	int32  MyCurrentTry;
	int32 MyWordLength;
	int32 WordLengthMin;
	int32 WordLengthMax;
	FString MyHiddenWord;

	bool bGameIsWon;
};