My Bool Cow project showcase

Hello everyone! It is my first post here.
So I decided to add some features:

  1. Levels of difficulty: easy, medium, hard. On easy we know first and last charachter of hidden word. On medium we have one random char from hidden word. On hard level we know nothing :smiley:
  2. One game has editable sequence of words. For example player shoud guess 10 words.
  3. General lifes. its sum of player tries to guess sequence of words.

Most difficult thing to me was adding levels of difficult. So I resolved this with adding one more logic check when the game didnt start.




Here is my .cpp and .h files

#include "BullCowCartridge.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Math/UnrealMathUtility.h"


void UBullCowCartridge::BeginPlay() // When the game starts
{
    Super::BeginPlay();
    Intro();
}

void UBullCowCartridge::OnInput(const FString& PlayerInput) // When the player hits enter
{ 
    if (bGameNotStarted)
    {
        ClearScreen();
        SetupGame(PlayerInput);
        SetHiddenWord();
        PlayGame();
    }
    else if (bGameOver)
    {
        ClearScreen();
        Intro();
        bGameNotStarted = true;
    }
    else if (bNextWord)
    {
        ClearScreen();
        SetHiddenWord();
        PlayGame();
        bNextWord = false;
    }
    else// Checking player guess
    {
        ProcessGuess(PlayerInput);     
    }
}

void UBullCowCartridge::Intro()
{
    PrintLine(TEXT("Hi and welcome to Bull Cows game!"));

    PrintLine(TEXT("Choose level difficulty:"));
    PrintLine(TEXT("1. Easy\n2. Medium\n3. Hard"));
    PrintLine(TEXT("Type in your level and press enter..."));

    bGameOver = false;
}


void UBullCowCartridge::SetupGame(const FString& PlayerInput)
{
    // Making Array of valid words from txt file
    const FString WordListPath = FPaths::ProjectContentDir() / TEXT("WordLists/HiddenWordList.txt");
    FFileHelper::LoadFileToStringArray(Words, *WordListPath);
    
    bGameNotStarted = false;
    bGameOver = false;
    bNextWord = false;
    GuessedWord = 0;
    GeneralLife = 3;
    Tries = 0;
    LimitOfPlays = 10;

    // Setting up game difficult
    
    if (PlayerInput == "Easy" || PlayerInput == "1")
    {
        DifficultyLevel = 1;
        Words = GetValidWords(Words, 2, 4);
        return;
    }

    if (PlayerInput == "Medium" || PlayerInput == "2")
    {
        DifficultyLevel = 2;
        Words = GetValidWords(Words, 3, 6);
        return;
    }

    if (PlayerInput == "Hard" || PlayerInput == "3")
    {
        DifficultyLevel = 3;
        Words = GetValidWords(Words, 4, 8);
        return;
    }

    PrintLine(TEXT("Debug: the end of function"));
}

void UBullCowCartridge::SetHiddenWord()
{
    HiddenWord = Words[FMath::RandRange(0, Words.Num()) - 1];
    Lives = HiddenWord.Len();
}


void UBullCowCartridge::PlayGame()
{
    PrintLine(TEXT("The hidden word is %s"), *HiddenWord);

    switch (DifficultyLevel)
    {
    case 1:
        PrintLine(TEXT("Guess is: \"%c..%c\""), HiddenWord[0], HiddenWord[HiddenWord.Len() - 1]);
        PrintLine(TEXT("You have %i lives."), Lives);
        PrintLine(TEXT("Type in your guess and \npress Enter to continue..."));
        break;
    case 2:
        PrintLine(TEXT("Guess has \"%c\" letter"), HiddenWord[FMath::RandRange(0, HiddenWord.Len() - 1)]);
        PrintLine(TEXT("You have %i lives."), Lives);
        PrintLine(TEXT("Type in your guess and \npress Enter to continue..."));
        break;
    case 3:
        PrintLine(TEXT("Guess the %i letter word!"), HiddenWord.Len());
        PrintLine(TEXT("You have %i lives."), Lives);
        PrintLine(TEXT("Type in your guess and \npress Enter to continue..."));
        break;
    }
}


void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    PrintLine(TEXT("\nPress Enter to play again."));
}

void UBullCowCartridge::ContinuePlaying()
{
    bNextWord = true;
    PrintLine(TEXT("You have passed %i/%i hidden words!"), ++Tries, LimitOfPlays);
    PrintLine(TEXT("You have guessed %i words!"), GuessedWord);
    PrintLine(TEXT("\nPress Enter to continue playing..."));
}

void UBullCowCartridge::ProcessGuess(const FString& Guess) 
{
    if (HiddenWord == Guess)
    {
        ++GuessedWord;
        if (GuessedWord >= LimitOfPlays)
        {
            PrintLine(TEXT("Woohoo!\nYou Won this game!"));
            EndGame();
            return;
        }
        PrintLine(TEXT("You guessed right!"));
        ContinuePlaying();
        return;
    }

    PrintLine(TEXT("You lost life!"));
    --Lives;

    if (Lives <= 0)
    {
        --GeneralLife;
        if (GeneralLife <= 0)
        {
            PrintLine(TEXT("You lost last try to guess!"));
            PrintLine(TEXT("%i guessed words \nfrom %i all hidden words!"), GuessedWord, LimitOfPlays);
            EndGame();
            return;
        }

        ClearScreen();
        PrintLine(TEXT("You have no lives to guess this hidden word"));
        PrintLine(TEXT("and %i tries remaining."), GeneralLife);
        PrintLine(TEXT("The hidden word was: %s."), *HiddenWord);
        ContinuePlaying();
        return;
    }

    if (HiddenWord.Len() != Guess.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;
    }

    if (!IsIsogram(Guess))
    {
        PrintLine(TEXT("No repeating letters, guess again"));
        PrintLine(TEXT("Sorry, try guessing again! \nYou have %i lives remaining"), Lives);
        return;
    }

    FBullCowCount Score = GetBullCows(Guess);

    PrintLine(TEXT("You have %i Bulls and %i Cows"), Score.Bulls, Score.Cows);
    PrintLine(TEXT("Guess again, you have %i lives left."), Lives);
}



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

    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;
}

TArray<FString> UBullCowCartridge::GetValidWords(const TArray<FString>& WordList, int32 min, int32 max) const
{
    TArray<FString> ValidWords;

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

FBullCowCount UBullCowCartridge::GetBullCows(const FString& Guess) const
{
    FBullCowCount Count;

    for (int32 GuessIndex = 0; GuessIndex < Guess.Len(); GuessIndex++)
    {
        if (Guess[GuessIndex] == HiddenWord[GuessIndex])
        {
            Count.Bulls++;
            continue;
        }
        
        for (int32 Index = 0; Index < HiddenWord.Len(); Index++)
        {
            if (Guess[GuessIndex] == HiddenWord[Index])
            {
                Count.Cows++;
                break;
            }
        }
    }

    return Count;
}

#pragma once

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

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

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 Intro();
	void SetupGame(const FString& PlayerInput);
	void SetHiddenWord();
	void PlayGame();
	void EndGame();
	void ContinuePlaying();
	void ProcessGuess(const FString& Guess);
	bool IsIsogram(const FString& Word) const;
	TArray<FString> GetValidWords(const TArray<FString>& WordList, int32 min, int32 max) const;
	FBullCowCount GetBullCows(const FString& Guess) const;

	// Your declarations go below!
	private:
	bool bGameNotStarted = true;
	FString HiddenWord;
	int32 Lives;
	int32 GuessedWord;
	bool bGameOver;
	bool bNextWord;
	int32 GeneralLife;
	int32 Tries;
	TArray<FString> Words;
	int32 DifficultyLevel;
	int32 LimitOfPlays;
};

1 Like

Phenomenal job and congratulations :partying_face:

Privacy & Terms