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