Early Returns

With a Isogram check as well. Getting there. I called it IsAnIsogram.

// Fill out your copyright notice in the Description page of Project Settings.
#include "BullCowCartridge.h"

void UBullCowCartridge::BeginPlay() // When the game 
{
    Super::BeginPlay();
	
	IntiateGame();

	/*	
		Welcome Message Instructions

		Intiate game (lives Levels hidden word)

		While (guess)
			
			Get input
			If (play)
				Display Win
				Level ++
			else	
				Display Bulls and Cows
				if(Life > 0)
					Life --
				else
					if(PlayAgain)
						Intiate new game
					else
						break
		Quit
				
	*/
}

void UBullCowCartridge::OnInput(const FString& Input) // When the player hits enter
{
	ClearScreen();
	ProcessInput(Input);
}

void UBullCowCartridge::DisplayWelcomeMessage()
{
	PrintLine(TEXT("Velcro's Bulls and Cows"));
	PrintLine(TEXT("Please click on board and press 'Tab' to start"));
	//PrintLine(TEXT("Enter a ") + FString::FromInt(GameLevel + 3) + TEXT(" letter word...")); // what you would normally do if it wasn't defined elsewhere
	PrintLine(TEXT("Enter a %i letter word."), HiddenWord.Len());
}

void UBullCowCartridge::ProcessInput(FString Input)
{
	if (bEndPrompt) {
		if (Input.Len() == 1 && Input == "P" && bEndPrompt) {
			bResetGame = true;
			bEndPrompt = false;
		}
		if (Input.Len() == 1 && Input == "Q" && bEndPrompt) {
			bResetGame = false;
			bEndPrompt = false;
			PrintLine(TEXT("Bye."));
		}
	}

	if (!IsAnIsogram(Input)) 
	{
		PrintLine(TEXT("%s is not an Isogram"), *Input);
	}

	if (bResetGame) 
	{
		ClearScreen();
		IntiateGame();
	}
	else {
		if (HiddenWord == Input)
		{
			PrintLine(TEXT("Nailed it."));
			PrintLine(TEXT("The Hidden word was %s"), *HiddenWord);
			EndGame();
		}
		else
		{
			if (Input.Len() != HiddenWord.Len())
			{
				PrintLine(TEXT("Enter a %i letter word."), HiddenWord.Len());
			}
			Lives--;
			if (Lives <= 0) {
				PrintLine(TEXT("You have lost dude."), Lives);
				EndGame();
			}
			else
			{
				PrintLine(TEXT("Try again. You have %i lives left."), Lives);
			}
		}
	}
}


void UBullCowCartridge::IntiateGame()
{
	//Intiate game(lives Levels hidden word)
	bResetGame = false;
	bEndPrompt = false;
	GameLevel = 1;
	Lives = GameLevel * LivesMultiplier;
	HiddenWord = GetHiddenWord();
	DisplayWelcomeMessage();
	if (bIsItDebugTime) { PrintLine(TEXT("The Hidden word is %s"), *HiddenWord); }
}

FString UBullCowCartridge::GetHiddenWord()
{
	HiddenWord = TEXT("asdf");
	return HiddenWord;
}

void UBullCowCartridge::EndGame()
{
	ContinueGamePrompt();
}

void UBullCowCartridge::ContinueGamePrompt()
{
	bEndPrompt = true;
	PrintLine(TEXT("'P'lay Again? or 'Q'uit?, then Enter"));
}

bool UBullCowCartridge::IsAnIsogram(FString str)
{
	for (int i = 0; i < str.Len(); i++)
	{
		for (int j = 0; j < str.Len(); j++)
		{
			if (i != j)
			{
				if (str[i] == str[j])
				{
					return false;
				}
			}
		}
	}
	return true;
}

1 Like

Here’s my ProcessGuess function, but without pseudocode for Isogram check

1 Like

My process guess function

The IsIsogram code which Mike showed in the course has nested for loops. Two nested for loops make the algorithm an O(n^2) algorithm. Here is my proposed alternative which is a O(n) algorithm. It makes use of the STL container bit-set. Perhaps it was too early to introduce STL containers, but for those who are familiar with STL containers here is my implementation with only one for loop. Though for small strings an O(n^2) algorithm is not perceptibly slower than an O(n) algorithm if the IsIsogram function is going to be called on the entire Webster dictionary the difference will be quite noticeable.

bool UBullCowCartridge::IsIsogram(FString Word)
{
std::bitset<26> AlphabetUsed;
for (int32 WordIndex = 0; WordIndex < Word.Len(); WordIndex++)
{
char C = Word[WordIndex];
PrintLine(TEXT(“checking for %c”),C);
if (AlphabetUsed.test(C - ‘a’))
{
PrintLine(TEXT("%c is repeated"),C);
return false;
}
else
{
AlphabetUsed.set(C - ‘a’);
PrintLine(TEXT(“setting bit number %i”),C - ‘a’);
}
}
return true;
}

Why did my identations vanish from my first post?

Just look at this beauty.
Code:

// Fill out your copyright notice in the Description page of Project Settings.
#include "BullCowCartridge.h"

void UBullCowCartridge::BeginPlay() // When the game starts
{
    Super::BeginPlay();
    // PrintLine(TEXT("Begin.")); // Debug line
    // PrintLine(TEXT("The hidden word is: %s.\nIt is %i characters long."), *HiddenWord, HiddenWord.Len()); // Debug line
    SetupGame(); // setting up a first game - word, lives, points, instructions for player and asking for word
}

void UBullCowCartridge::OnInput(const FString& Input) // When the player hits enter
{
    if (bGameOver) // if (true), the player guess was correct, set up a new word
    {  
        ClearScreen();
        SetupGame(); // set up a new game    
    }
    else // Comparing answer
    {  
        ProcessGuess(Input); 
    }
}

void UBullCowCartridge::SetupGame()
{
    //PrintLine(TEXT("The hidden word is: %s.\nIt is %i characters long."), *HiddenWord, HiddenWord.Len()); // Debug line
    
    HiddenWord = TEXT("above");
    Lives = HiddenWord.Len();
    // Points = 0;
    bGameOver = false;

    // Welcome player, explaining rules
    PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
    PrintLine(TEXT(""));
    PrintLine(TEXT("This is a Bull Cows game."));
    PrintLine(TEXT("Letter in the right place = Bull."));
    PrintLine(TEXT("Letter in the wrong place = Cow."));
    PrintLine(TEXT(""));

    // Asking player for guess, show lives, letters, points
    PrintLine(TEXT("Guess the %i letter isogram and press ENTER"), HiddenWord.Len());
    PrintLine(TEXT(""));
}

void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    PrintLine(TEXT(""));
    PrintLine(TEXT("Press Enter to play agin."));
}

void UBullCowCartridge::ProcessGuess(FString Guess)
{   
    if (Lives == 1) // player dont have lives
    {
        --Lives; // this is for showing player that its 0 lives

        ClearScreen();
        PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
        PrintLine(TEXT(""));
        PrintLine(TEXT(""));
        PrintLine(TEXT("Wrong answer. All lives lost!"));
        PrintLine(TEXT("The hidden word was: %s"), *HiddenWord);
        Points = 0;
        EndGame();
        return;
    }

    // if (!Isogram()) // when the word is not an isogram
    // {
    //     --Lives; // decreasing lives for wrong answer

    //     ClearScreen();
    //     PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
    //     PrintLine(TEXT(""));
    //     PrintLine(TEXT(""));
    //     PrintLine(TEXT("This is not an isogram. You lost 1 life."));
    //     PrintLine(TEXT("No repeating letters!"));
    //     PrintLine(TEXT("Type your guess agin."));
    //     PrintLine(TEXT(""));
    //     return;
    // }

    if (HiddenWord.Len() != Guess.Len()) // when player inputs incorrect word length
    {
        --Lives; // decreasing lives for wrong answer

        ClearScreen();
        PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
        PrintLine(TEXT(""));
        PrintLine(TEXT(""));
        PrintLine(TEXT("Incorrect word length. You lost 1 life."));
        PrintLine(TEXT("Type your guess agin."));
        PrintLine(TEXT(""));
        return;
    }

    if (Guess != HiddenWord) // when word dont match
    {
        --Lives; // decreasing lives for wrong answer

        ClearScreen();
        PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
        PrintLine(TEXT("Bulls = X.  Cows   = X")); // show bulls and cows
        PrintLine(TEXT(""));
        PrintLine(TEXT("Wrong asnwer. You lost 1 life."));
        PrintLine(TEXT("Type your guess agin."));
        PrintLine(TEXT(""));
        return;
    }

    // if the answer is correct
    ClearScreen();
    ++Points; // awarded for correct answer
    PrintLine(TEXT("Lives = %i. Points = %i"), Lives, Points); // show lives and points
    PrintLine(TEXT(""));
    PrintLine(TEXT(""));
    PrintLine(TEXT("That is 100% correct!"));
    PrintLine(TEXT("You get 1 point."));
    EndGame();
}

And the game screens:

Hello everybody. This is my first post here. Just wanted to share some of my code after completing this video.

1 Like

Hello. I used both early returns and nested if statement to retain readability of code:

void UBullCowCartridge::ProcessGusess(FString Guess)
{
    if (Guess == HiddenWord)
    {
        PrintLine(TEXT("You've won!"));
        EndGame();
        return;
    }
    PrintLine(TEXT("You have %i guesses left."), --Lives);
    // Check if Isogram if not then prompt to Guess again  
    if (Lives>0)
    {
        if (HiddenWord.Len()!=Guess.Len())
        { 
            PrintLine(TEXT("Wrong!\nHidden word is %i characters long."),HiddenWord.Len()); 
        }
        PrintLine(TEXT("Try again."));
        return;
    }
    
    PrintLine(TEXT("It was a last, but wrong try."));
    PrintLine(TEXT("\nThe hidden word was:%s"), *HiddenWord);
    EndGame();   
}

with the EndGame() lik this:

void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    PrintLine(TEXT("Press ENTER to play again.."));
}
1 Like

Privacy & Terms