My code so far

Ok, well I got a bit carried away here and expanded the code considerably regarding functions . I moved all the display items into their own functions and also moved the bulk of the input processing into a function called ProcessUserInput.

So the game now allows 5 guesses and decrements the lives each time the user gets the word wrong (still just a simple equality check on this for now). The player’s guess, result and life count are all displayed following each guess and once you either guess correctly or run out of lives the program then prompts for input to restart or quit and implements that.

Not sure if setting GIsRequestingExit to true is the correct way of exiting the Unreal Engine as it closed my Editor too the first time I tried it!!! However, when running the game standalone it seems fine … I know, I probably should have waited as I’m sure you’ll be covering that later :sunglasses:

My header file additions:

	// Your declarations go below!
	private:
		FString HiddenWord;
		FString CurrentWordGuess;
		bool bHelpCalled;
		bool bNewWord;
		bool bHasGuessed;
		bool bInitGame;
		bool bContinuePlay;
		int32 LivesLeft;

		void DisplayWelcome();
		void DisplayHelp();
		void InitGame();
		void ProcessUserInput(const FString& Input);
		void DisplayInstruction();
		void DisplayGuess(const FString& Guess);
		void DisplayLivesRemaining(int32 Lives);
		void DisplayContinueGamePrompt();

and my code:

#include "BullCowCartridge.h"

void UBullCowCartridge::BeginPlay() // Called by Unreal Engine when the game starts
{
	Super::BeginPlay();
	InitGame();
}

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

void UBullCowCartridge::InitGame()
{
	// Initialise variables
	HiddenWord = TEXT("Place"); // Always encose literal strings in a TEXT macro to ensure native Unicode encoding.
	bHelpCalled = false;		// Flag to indicate if DisplayHelp had previously been called
	bNewWord = false;			// Flag to indicate its a new word
	bHasGuessed = false;		// Flag to indicate the user has provided a guess
	bInitGame = false;			// Flag to indicate start of a new game
	bContinuePlay = true;		// Flag to indicate play should continue
	LivesLeft = 5;

	DisplayWelcome();
}

void UBullCowCartridge::ProcessUserInput(const FString& Input)
{
	// Handle the ContinueGamePrompt user input
	if (!bContinuePlay)
	{
		if (Input == TEXT("r"))
		{
			InitGame();
			bContinuePlay = true;
			return;
		}
		else if (Input == TEXT("q"))
		{
			// Quit game
			GIsRequestingExit = true;
		}
		else
		{
			DisplayContinueGamePrompt();
			return;
		}

	}
	
	DisplayInstruction();

	// If user previously called help then display the previously stored word guess
	if (bHelpCalled)
	{
		if (CurrentWordGuess != "")
		{
			DisplayGuess(CurrentWordGuess);
			DisplayLivesRemaining(LivesLeft);
		}

		// Reset our help called flag
		bHelpCalled = false;

		return;
	}

	// So long as something has been typed
	if (Input != "")
	{
		// If user requested help
		if (Input == TEXT("help"))
		{
			DisplayHelp();

			// Set our help called flag 
			bHelpCalled = true;
		}
		else
		{
			// Store the current word guess incase the user subsequently requests help or just hits enter and we need to restore the guess
			CurrentWordGuess = Input;
			bHasGuessed = true;

			// Test to see if the guess is correct or not
			if (Input == HiddenWord)
			{
				// Display the users latest guess
				DisplayGuess(Input);
				PrintLine(TEXT("Correct.  You Win!"));
				DisplayContinueGamePrompt();
				bContinuePlay = false;
				CurrentWordGuess = "";
				bNewWord = true;
				bHasGuessed = false;
			}
			else
			{
				// Decrement the number of lives left
				--LivesLeft;

				DisplayGuess(Input);

				if (LivesLeft == 0)
				{
					PrintLine(TEXT("You have no lives left"));
					DisplayContinueGamePrompt();
					bContinuePlay = false;
				}
				else
				{
					PrintLine(TEXT("Incorrect.  You lose a life"));
					PrintLine(TEXT("Please try again"));
					DisplayLivesRemaining(LivesLeft);
				}
			}
		}
	}
	else if (bHasGuessed)
	{
		// If the user has previously guessed but has just pressed Enter then print previous guess
		DisplayGuess(CurrentWordGuess);
		DisplayLivesRemaining(LivesLeft);
	}
}
	
void UBullCowCartridge::DisplayWelcome()
{
	PrintLine(TEXT("Welcome to the Bulls and Cows game\n"));
	PrintLine(TEXT("Press Enter to continue"));
}

void UBullCowCartridge::DisplayHelp()
{
	ClearScreen();
	PrintLine(TEXT("The game is a guess the hidden word game."));
	PrintLine(TEXT("The hidden word will always be an ISOGRAM,"));
	PrintLine(TEXT("that is a word with no repeating letters."));
	PrintLine(TEXT("Any correct letters in the right position"));
	PrintLine(TEXT("will score you BULLS, any correct letters"));
	PrintLine(TEXT("in the wrong position will score you COWS"));
	PrintLine(TEXT("and any wrong letters score nothing."));
	PrintLine(TEXT("You will have so many tries in order to "));
	PrintLine(TEXT("guess the word correctly and win the game."));
	PrintLine(TEXT("Press Enter to return to the game."));
}

void UBullCowCartridge::DisplayInstruction()
{
	PrintLine(TEXT("Type help and press Enter for a basic"));
	PrintLine(TEXT("description of the game and rules.\n"));
	PrintLine(TEXT("Otherwise guess the 5 letter word ...\n"));
}

void UBullCowCartridge::DisplayGuess(const FString& Guess)
{
	PrintLine("You guessed: " + Guess);
}

void UBullCowCartridge::DisplayLivesRemaining(int32 Lives)
{
	PrintLine(TEXT("You have " + FString::FromInt(LivesLeft) + TEXT(" lives remaining")));
}

void UBullCowCartridge::DisplayContinueGamePrompt()
{
	PrintLine(TEXT("To restart type 'r' and Enter"));
	PrintLine(TEXT("To quit type 'q' and Enter"));
}
2 Likes

It looks like you have done the entire project. Awesome.

yeah um, I… I did a function. I guess?

#pragma once

#include “CoreMinimal.h”

#include “Console/Cartridge.h”

#include “BullCowCartridge.generated.h”

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))

class BULLCOWGAME_API UBullCowCartridge : public UCartridge

{

  • GENERATED_BODY()*

  • public:*

  • virtual void BeginPlay() override;*

  • virtual void OnInput(const FString& Input) override;*

  • void InitGame();*

  • // Your declarations go below!*

  • private:*

  • FString HiddenWord;*

  • // declare amount of lives(can it be declared globally??)*

  • int32 Lives;//why did we declare this here??*

};
// 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(“Hello Fellow puzzel solver!”));*

  • PrintLine(TEXT(“write a line and press enter”));*

  • InitGame();//setting up the game*

  •   *
    

}

void UBullCowCartridge::OnInput(const FString& Input) // When the player hits enter

{

// move outside this function(move what??)

  • ClearScreen();*

  • PrintLine(Input);*

if (Input == TEXT(“Gerek”))//comparing the input to the hidden word

{

  • PrintLine(TEXT(“YOU Win !”)); /*if player wins, this gets prompted /

}

  • else*

  • {*

  • PrintLine(TEXT(“Youre an Idiot, The Word is write in front of you!”)); /* see if the amount of livesd are more then 0/change line completely /

  • }*

  • //check if isogram *

  • //prompt to geuss agian*

  • //checkthe right number of characters*

  • //prompt to geuss agian*

  • //if lives > 0, prompt player to guess again*

  • //if player decines, curse player, then take a life*

  • //if lives > 0, prompt player to guess again*

  • //if yes geuss again*

  • //show lives left*

  • //if no show game over and hidden word*

  • //prompt to play agian*

  • //check input*

  • //playagin or quit*

}

void UBullCowCartridge::InitGame()

{

  • HiddenWord == TEXT(“Gerek”);*

  • Lives = 3;*

Here’s what I put in the header file within the main class:

void InitGame();

Here’s what I put in the .cpp file

In the beginPlay() function

InitGame();

Lower in the .cpp file, added these ‘guts’ to the InitGame function

void UBullCowCartridge::InitGame()

{

    HiddenWord = TEXT("isogram");

    Lives = 5;

}

Pretty much stuck with the ‘script’!

Great that you expanded like this, this early in the chapter, however you’re naming convention for your bools are not consistent with what is recommended by Unreal, they should be capitalised, no need to specify it’s a bool by prefixing with b.

Thanks Jamie and well spotted, looks like old habits die hard!

1 Like

I was wrong! Unreal prefix bools with a b.

So it would appear, I just looked it up following your post. Strange that its only bools that require this. I do so more out of habit than strict adherence to any convention and I always prefix pointers with a lowercase p, which obviously goes against Epics coding convention.

To be honest, as I’m no longer coding professionally having retired, I will probably stick with my own naming convention as it’s not a big issue to swap to any convention if required to do so if working with a team or anyone else that requires that. I currently use several game engines and conventions differ.

Privacy & Terms