My BullCow Game with Hint, Stage, and Level

Hi, in my BullCow Game i added some feature:

  1. Stage, for every Stage there are 3 Level and for each stage will affect Lives, Max HiddenWord Length, and Hint where in Stage 1 the Hint will showed and else will not showed
  2. Level, will affect the Length of HiddenWord
  3. Hint, we can see where the Bull position but the Hint will only show in Stage 1, also i add Hint for show the first letter of HiddenWord

BullCowCartridge.cpp

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

void UBullCowCartridge::BeginPlay() // When the game starts
{
    Super::BeginPlay();
    const FString WordListPath = FPaths::ProjectContentDir() / TEXT("WordLists/HiddenWordList.txt");
    FFileHelper::LoadFileToStringArray(Words, *WordListPath);
    SetupGame();
}

void UBullCowCartridge::SetupGame()
{
    //Set the Level
    Level.LevelNow = 1;
    Level.MaxLevel = 3;
    Stage.StageNow = 1;

    bGameOver = false;

    NewLevel();
}

void UBullCowCartridge::OnInput(const FString &PlayerInput) // When the player hits enter
{
    if (bGameOver)
    {
        ClearScreen();
        SetupGame();
    }
    else
    {
        ProcessGuess(PlayerInput);
    }
}

void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    PrintLine(TEXT("Congaratulations you finish the game"));
    PrintLine(TEXT("Press Enter, to play again!"));
}

void UBullCowCartridge::NewLevel()
{
    ClearScreen();

    if (Level.LevelNow > Level.MaxLevel)
    {
        Stage.StageNow++;
        Level.LevelNow = 1;
    }

    if (Stage.StageNow > Stage.MaxStage)
    {
        EndGame();
        return;
    }

    ValidWords = GetValidWords(Words);

    HiddenWord = ValidWords[FMath::RandRange(0, ValidWords.Num() - 1)];
    Lives = FMath::RoundToInt(HiddenWord.Len() * 1.5) - Stage.StageNow;

    // Welcoming Player
    PrintLine(TEXT("Welcome to Stage %i, Level %i"), Stage.StageNow, Level.LevelNow);
    PrintLine(TEXT("The HiddenWord is: %s"), *HiddenWord);
    PrintLine(TEXT("Guess the %i letter word!"), HiddenWord.Len());
    PrintLine(TEXT("The first letter is '%c'"), HiddenWord[0]);
    PrintLine(TEXT("You have %i Lives."), Lives);
    PrintLine(TEXT("Type in your guess and, \npress enter to continue...")); // Prompt Player For Guess
}

void UBullCowCartridge::ProcessGuess(const FString &Guess)
{
    // If the guess is true
    if (Guess == HiddenWord)
    {
        Level.LevelNow++;
        NewLevel();
        return;
    }

    // Check Right Number Of Characters
    if (Guess.Len() != HiddenWord.Len())
    {
        PrintLine(TEXT("The hidden word is %i letters long"), HiddenWord.Len());
        PrintLine(TEXT("Sorry, try guessing again! \nYou have %i lives remaining"), Lives);
        return;
    }

    // Check if Isogram
    if (!IsIsogram(Guess))
    {
        PrintLine(TEXT("No repeating letters, guess again!"));
        return;
    }

    // Remove Live
    PrintLine(TEXT("Lost a life!"));
    --Lives;

    if (Lives <= 0)
    {
        ClearScreen();
        PrintLine(TEXT("You have no lives left!"));
        PrintLine(TEXT("The HiddenWord was: %s"), *HiddenWord);
        EndGame();
        return;
    }

    // Show the player Bulls and Cows

    FBullCowCount Score = GetBullCows(Guess);

    PrintLine(TEXT("Guess again, you have %i lives left"), Lives);
}

bool UBullCowCartridge::IsIsogram(const FString &Word)
{

    for (int32 Index = 0; Index <= Word.Len(); Index++)
    {
        for (int32 Comparison = Index + 1; Comparison < Word.Len(); Comparison++)
        {
            if (Word[Index] == Word[Comparison])
            {
                return false;
            }
        }
    }

    return true;
}

FBullCowCount UBullCowCartridge::GetBullCows(const FString &Guess) const
{
    FBullCowCount Count;
    TArray<char> Hint;
    for (int32 GuessIndex = 0; GuessIndex < Guess.Len(); GuessIndex++)
    {
        if (Guess[GuessIndex] == HiddenWord[GuessIndex])
        {
            Count.Bulls++;
            Hint.Emplace(Guess[GuessIndex]);
            continue;
        }
        else
        {
            Hint.Emplace('-');
        }

        for (int32 HiddenIndex = 0; HiddenIndex < HiddenWord.Len(); HiddenIndex++)
        {

            if (HiddenWord[HiddenIndex] == Guess[GuessIndex])
            {
                Count.Cows++;
                break;
            }
        }
    }
    PrintLine(TEXT("You have %i Bulls and %i Cows"), Count.Bulls, Count.Cows);

    if (Stage.StageNow == 1)
    {
        for (int IndexHint = 0; IndexHint < Hint.Num(); IndexHint++)
        {
            PrintLine(TEXT("=> %c"), Hint[IndexHint]);
        }
    }
    return Count;
}

TArray<FString> UBullCowCartridge::GetValidWords(TArray<FString> WordList)
{
    TArray<FString> ValidWords;

    int32 MinLength = FMath::RoundToInt(Level.LevelNow * 1.5);

    int32 MaxLength = Level.LevelNow * 3 + Stage.StageNow;

    for (FString Word : WordList)
    {
        if (Word.Len() >= MinLength && Word.Len() <= MaxLength && IsIsogram(Word))
        {
            ValidWords.Emplace(Word);
        }
    }

    return ValidWords;
}

BullCowCartridge.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Console/Cartridge.h"
#include "BullCowCartridge.generated.h"

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

struct FLevel
{
	int32 LevelNow = 1;
	int32 MaxLevel = 5;
};

struct FStage
{
	int32 StageNow = 1;
	int32 MaxStage = 3;
};

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 SetupGame();
	void EndGame();
	void NewLevel();
	void ProcessGuess(const FString &Guess);
	static bool IsIsogram(const FString &Word);
	FBullCowCount GetBullCows(const FString &Guess) const;
	TArray<FString> GetValidWords(TArray<FString> WordList);

	// Your declarations go below!
private:
	FString HiddenWord;
	int32 Lives;
	FLevel Level;
	FStage Stage;
	bool bGameOver;
	TArray<FString> Words;
	TArray<FString> ValidWords;
};
3 Likes

You are doing a great job :100:

Thank you :grin:

1 Like

You’re welcome!

Privacy & Terms