I’ve completed my Bull Cow project.
In the end i’ve added a scoring system and a Lives system. If you fail at guessing after the set attempts you lose a live and get to guess a new word.
In the end it shows you the total score.
My only challenge that I decided not to implement was a system to stop the game while on a winning streak. So far the only way to quit is to lose.
// Fill out your copyright notice in the Description page of Project Settings.
#include "BullCowCartridge.h"
#include "HiddenWordList.h"
void UBullCowCartridge::BeginPlay() // When the game starts
{
Super::BeginPlay();
Isograms = GetValidWords(Words);
PrintLine(TEXT("Welcome to Bulls Cows."));
SetupGame();
}
void UBullCowCartridge::OnInput(const FString& PlayerInput) // When the player hits enter
{
if(bGameOver)
{
ClearScreen();
SetupGame();
}
else if (Attempts == 0 || Lives == 0 || bWon == true)
{
Continue(PlayerInput, Attempts, Lives, bWon);
}
else
{
ProcessGuess(PlayerInput);
}
}
void UBullCowCartridge::SetupGame()
{
bGameOver = false;
bWon = false;
HiddenWord = Isograms[FMath::RandRange(0, Isograms.Num()-1)];
Lives = 3;
Score = 0;
Attempts = HiddenWord.Len();
PrintLine(TEXT("Please guess the %i letter Secret word"),HiddenWord.Len());
PrintLine(TEXT("Please type in your guess and \nPress Enter to Continue."));
PrintLine(TEXT("You have %i attempts to guess"), Attempts);
}
void UBullCowCartridge::EndGame()
{
bGameOver = true;
PrintLine(TEXT("Thank you for playing Bull Cows"));
PrintLine(TEXT("You got a total of %i points"), Score);
PrintLine(TEXT("Press Enter to play again."));
}
void UBullCowCartridge::ProcessGuess(const FString& Guess)
{
if (Guess == HiddenWord)
{
PrintLine(TEXT("Congratulations, you guessed correct!"));
SetScore(GuessMade);
bWon= true;
PrintLine(TEXT("You have a score of %i points!"),Score);
PrintLine(TEXT("Do you wish to continue playing and guess a new word?"));
return;
}
if(Guess.Len() != HiddenWord.Len())
{
if(Guess.Len() < HiddenWord.Len() )
{
PrintLine(TEXT("The word you chose is to short."));
}
else
{
PrintLine(TEXT("The word you chose is to long."));
}
PrintLine(TEXT("The Secret word contains %i letters"), HiddenWord.Len());
PrintLine(TEXT("You have %i attempts left"), Attempts);
return;
//this doesn't count as an attempt.
}
if(!IsIsogram(Guess))
{
PrintLine(TEXT("Your guess needs to be an isogram.\nThe Secret word contains %i letters"), HiddenWord.Len());
return;
}
if(Guess != HiddenWord)
{
FBullCowCount Score = GetBullCows(Guess);
PrintLine(TEXT("Your guess is incorrect"));
--Attempts;
++GuessMade;
if(Attempts > 0)
{
PrintLine(TEXT("But, you have %i Bulls and %i Cows"), Score.Bulls, Score.Cows);
PrintLine(TEXT("Try Again"));
PrintLine(TEXT("You have %i attempts left"), Attempts);
return;
}
else if( Attempts == 0 && Lives > 1)
{
PrintLine(TEXT("No more attempts left."));
PrintLine(TEXT("The Secret word was %s."),*HiddenWord);
PrintLine(TEXT(""));
PrintLine(TEXT("Do you wish to continue to play?"));
return;
}
else
{
PrintLine(TEXT("You have no more attempts or lives left."));
PrintLine(TEXT(""));
PrintLine(TEXT("GAME OVER"));
PrintLine(TEXT(""));
EndGame();
}
}
}
bool UBullCowCartridge::IsIsogram(const FString& Word) const
{
for (int32 LetterToCompare = 0; LetterToCompare < Word.Len(); LetterToCompare++)
{
for (int32 ToCompareWith = LetterToCompare+1; ToCompareWith < Word.Len(); ToCompareWith++)
{
if (Word[LetterToCompare] == Word[ToCompareWith])
{
return false;
}
}
}
return true;
}
TArray<FString> UBullCowCartridge::GetValidWords(const TArray<FString>& WordList) const
{
TArray<FString>ValidWords;
for (FString Word : WordList)
{
if(Word.Len() >= 4 && Word.Len() <= 8 && IsIsogram(Word) == true)
{
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 HiddenIndex = 0; HiddenIndex < HiddenWord.Len(); HiddenIndex++)
{
if(Guess[GuessIndex] == HiddenWord[HiddenIndex])
{
Count.Cows++;
break;
}
}
}
return Count;
}
void UBullCowCartridge::Continue(const FString& PlayerInput, int32& Attempts, int32& Lives, bool& bWon)
{
if(bWon == true && Attempts > 0 && (PlayerInput.ToUpper() == "Y" || PlayerInput.ToUpper()== "YES"))
{
HiddenWord = Isograms[FMath::RandRange(0, Isograms.Num()-1)];
Attempts = HiddenWord.Len();
bWon = false;
PrintLine(TEXT("I've set a new %i letter Secret word.\nYou have %i attempts to guess the new word."), HiddenWord.Len(), Attempts);
return;
}
else if (bWon == false && Attempts == 0 && Lives > 0 && (PlayerInput.ToUpper() == "Y" || PlayerInput.ToUpper()== "YES"))
{
--Lives;
GuessMade = 0;
HiddenWord = Isograms[FMath::RandRange(0, Isograms.Num()-1)];
Attempts = HiddenWord.Len();
PrintLine(TEXT("You have lost 1 live.\nYou have %i lives left"), Lives);
PrintLine(TEXT("I've set a new %i letter Secret word.\nYou have %i attempts to guess the new word."), HiddenWord.Len(), Attempts);
return;
}
else
{
PrintLine(TEXT("TEst to see when this line is executed Am I now game over?"));
EndGame();
}
}
void UBullCowCartridge::SetScore(int32& GuessMade)
{
if(GuessMade == 0)
{
Score += 3;
GuessMade = 0;
}
else if(GuessMade == 1)
{
Score += 2;
GuessMade = 0;
}
else
{
Score += 1;
GuessMade = 0;
}
}