Finished Bull Cow Game

My finished Bull Cow game! Featuring mean cows, a scoring system, and finite lives.

I would love to be able to add a leaderboard, but that’s a bit beyond me at the moment :sweat_smile:

I tried to structure my code in a similar manner to my flow charts, so it should all flow from beginning to end logically and clearly. What do you think?

Looking forward to continuing on this fantastic course.

//Copyright Jiterry Game 2021

#include "BullCowCartridge.h"
#include "HiddenWordList.h"

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

    Isograms = GetValidWords(Words);

    SetupGame();
}

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

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

    for (FString WordCheck : WordList)
    {
        if (WordCheck.Len() >= 4 && WordCheck.Len() <= 8 && IsIsogram(WordCheck))
        {
            ValidWords.Emplace(WordCheck);
        }
    }
    return ValidWords;
}

void UBullCowCartridge::CreateHiddenWord()
{    
    HiddenWord = Isograms[FMath::RandRange(0, Isograms.Num() - 1)]; //Set the hidden word
    PrintLine(TEXT("Can you guess the %i letter word?"), HiddenWord.Len());
    PrintLine(TEXT("This word has no repeating letters."));
    PrintLine(TEXT("Type your guess & press 'Enter'."));
    // PrintLine(TEXT("The hidden word is: %s."), *HiddenWord); //Debug Line
    // PrintLine(TEXT("The number of valid words is %i."), GetValidWords(Words).Num()); //Debug
}

void UBullCowCartridge::SetupGame()
{
    PrintLine(TEXT("Welcome to Bull Cows!"));   
    Lives = 10;
    Score = 0;
    bGameOver = false;
    CreateHiddenWord();  
}

void UBullCowCartridge::ProcessGuess(const FString& Guess)
{
   if (Guess==HiddenWord) //Correct Guess
    {    
        Score = Score + HiddenWord.Len();
        RoundWon();
        return;
    }

    if (HiddenWord.Len()!=Guess.Len()) //Wrong length
    {
        ClearScreen();
        PrintLine(TEXT("Can't you count? \nThe word is %i characters long, haybrain!"), HiddenWord.Len()); //Incorrect word length
        PrintLine(TEXT("Try again..."));
        return;
    }

    if (!IsIsogram(Guess)) //If isn't Isogram
    {
        PrintLine(TEXT("Got cowpat in your ears?"));
        PrintLine(TEXT("There are NO repeating letters!"));
        PrintLine(TEXT("Guess again."));
        return;
    }

    //Remove life
    ClearScreen();
    
    FBullCowCount Value = GetBullCows(Guess);
    PrintLine(TEXT("Wrong! Wrong! SO WRONG!"));
    PrintLine(TEXT("You have %i Bulls and %i Cows"), Value.Bulls, Value.Cows);
    PrintLine(TEXT("Lives Remaining: %i"), --Lives);
    PrintLine(TEXT("Get it right this time!"));

    if (Lives == 0)
    {
    EndGame();
    return;
    }
}

bool UBullCowCartridge::IsIsogram(const FString& Word) const //Is a word an isogram?
{
    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;

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

void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    ClearScreen();
    PrintLine(TEXT("The word was %s"), *HiddenWord);
    PrintLine(TEXT("Final Score: %i"), Score);
    PrintLine(TEXT("Even Scarecrow did better!"));
    PrintLine(TEXT("Press Enter to try again..."));
}

void UBullCowCartridge::RoundWon()
{
    bRoundWon = true;
    bGameOver = false;
    ClearScreen();
    PrintLine(TEXT("Score: %i"), Score);
    PrintLine(TEXT("So you're not udderly useless."));
    PrintLine(TEXT("Round 2:\n"));
    CreateHiddenWord();
}
1 Like

I challenge you to make a leaderboard :slight_smile:

Oh god! I threw myself into this and got sucked into a C++ rabbit hole.

This is the code I’ve got but it’s wrong!

Leaderboard
FPaths::ProjectContentDir() / TEXT("WordLists/Leaderboard.txt")
{    

    for(i = 0, i < 10, i++)
    {    if (Score > TArray(Leaderboard)[i])
            ofstream myfile;
            myfile.open ("Leaderboard.txt", ios::out | ios::app);
            FFileHelper::LoadFileToStringArray(Leaderboard)
            PrintLine(TEXT("Not bad! Type initials and press enter...");
            cin >> Name
            Leaderboard.Emplace(FToken, int32(Name, Score));
            Leaderboard.Sort(Score);
            Leaderboard.Remove(TArray(Leaderboard[10])
            myfile << TArray(Leaderboard)
            myfile.close()
    }
PrintLine(Text("1. %s, &i"), TArray(Leaderboard(Name)[0]), TArray(Leaderboard(Score)[0])
PrintLine(Text("2. %s, &i"), TArray(Leaderboard(Name)[1]), TArray(Leaderboard(Score)[1])
}
1 Like

Awesome job! :smiley:

Privacy & Terms