I am Stuck


I am trying to add some hints. I want to ask user that if he want hint or not but I don’t know somehow my if(Guess == “Y”) is not getting executed. When lives becomes 0 it directly clears the screen.
Help !

Guess is case sensitive. If you enter an upper case Y it will most likely work barring any other issues.

There’s a couple of ways to solve this, the easiest being to check either upper case Y or lower case y. Alternatively, convert guess to lower case (or upper, doesn’t matter) and then check for the appropriately cased y.

Confusingly FString's comparison overloads are case insensitive.

template <typename CharType>
FORCEINLINE friend bool operator==(const FString& Lhs, const CharType* Rhs)
{
    return FPlatformString::Stricmp(*Lhs, Rhs) == 0;
}

@instinct_212005 The issue is that there isn’t a moment for the user to enter anything.

Say Lives == 1, they enter their incorrect guess e.g. “plan” and then your code will

  • Subtract a life so Lives == 0
  • Print whether or not they want a hint
  • Check whether Guess == Y
  • That is false as Guess is still “plan”
  • The else branch is entered and the screen is cleared.

You would need to print whether they want a hint at the end and check at the beginning as well

if (Lives == 1 && !bHasSelected)
{
   //did they want a hint, 
   // print relevant messages
   bHasSelected = true;
   return;
}

// rest of game logic


// if the guess was incorrect
if (Lives == 1)
{
    // do they want a hint for their last guess?
}
1 Like
template <typename CharType>
FORCEINLINE friend bool operator==(const FString& Lhs, const CharType* Rhs)
{
    return FPlatformString::Stricmp(*Lhs, Rhs) == 0;
}

As I am a beginner I don’t know this kind of code blocks.
Where do I need to copy these?
Can you please elaborate it further or will I learn this in further part of course i.e Building Escape onwards? My code is still working as prior it just skips that part.
Do I have to use bHasSelected some where else also?


Below is my whole code block.

// Fill out your copyright notice in the Description page of Project Settings.
#include "BullCowCartridge.h"
#include "HiddenWordList.h"
#include <iostream>
// #include "Math/UnrealMathUtility.h" This is included in core minimal header file in BullCow Cartridge
using namespace std;

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

    Isograms = GetValidWord(HiddenWords);
    SetupGame();
    // PrintLine(TEXT("The possible number of words are: %i"), HiddenWords.Num());
    // PrintLine(TEXT("The number of ValidWords are:%i"), GetValidWord(HiddenWords).Num());
    // PrintLine(TEXT("%i"),GetValidWord(HiddenWords).Num() - 1); Debug line
    //We haven't used the FString::Printf() in above line but it will still work for this project as it is included in PrintLine function..
    //PrintLine(TEXT("The HiddenWord is: %s. \nIt is %i characters long."), *HiddenWord, HiddenWord.Len()); //Debug Line
}

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

void UBullCowCartridge::SetupGame()
{
    //Welcome message

    PrintLine(TEXT("HELLO,WELCOME TO BULLS & COWS GAME!"));
    PrintLine(TEXT("PRESS TAB TO ACCESS THE TERMINAL..."));
    PrintLine(TEXT("GAME RULES:"));

    HiddenWord = Isograms[FMath::RandRange(0,Isograms.Num() - 1)];
    Lives = (HiddenWord.Len() * 2); //Can't declare lives variable directly here because of scope issues..
    bGameOver = false;

    PrintLine(TEXT("BULL MEANS A CORRECT LETTER AT A\nCORRECT PLACE.\nCOW MEANS A CORRECT LETTER AT AN\nINCORRECT PLACE"));
    //Display Lives
    PrintLine(FString::Printf(TEXT("The HiddenWord is: %s"), *HiddenWord));
    PrintLine(TEXT("GUESS THE %i LETTER ISOGRAM\nAND PRESS ENTER.."), HiddenWord.Len());
    PrintLine(TEXT("YOU HAVE %i LIVES TO CRACK THE WORD."), Lives);
    PrintLine(TEXT("ALL THE BEST!"));
}
//Press Enter to PlayAgain
void UBullCowCartridge::EndGame()
{
    bGameOver = true;
    PrintLine(TEXT("Please Press Enter to Play Again..."));
}

void UBullCowCartridge::ProcessGuess(const FString& Guess)
{
    if (bGameOver)
    {
        ClearScreen();
        SetupGame();
    }
    // Check PlayerGuess
    else
    {
        if (Lives == 1 && !bHasSelected)
        {
            PrintLine(TEXT("Do you want some Hint? 1$ for 1 Hint.\nPress Y for Yes / N for No: "));
            if (Guess == "Y")
            {
                PrintLine(TEXT("First and Last letters are:%c, %c"), HiddenWord[0], HiddenWord[HiddenWord.Len() - 1]);
                PrintLine(TEXT("TRY AGAIN! YOU CAN DO IT."));
            }
            bHasSelected = true;
            return;
        }
        
        if (HiddenWord == Guess)
        {
            PrintLine(TEXT("FABULOUS, YOU NAILED IT!!"));
            EndGame();
            return;
        }
        //Check for correct length of word
        //Prompt to Guess Again
        else if (HiddenWord.Len()!= Guess.Len())
        {
            PrintLine(TEXT("Hidden word is %i characters long.\nPlease try again...."), HiddenWord.Len());
            PrintLine(TEXT("No lives deducted %i lives remaining"), Lives);
            return;
        }
        //Check for Isogram
        else if (!IsIsogram(Guess))
        {
            PrintLine(TEXT("CAUTION! Repetition is not allowed.\n%i lives left."), Lives);
            return;
        }
        //Deduct lives
        --Lives;
        //Check if lives > zero
        //If No, show GameOver and HiddenWord
        if (Lives == 0)
        {
            ClearScreen();
            PrintLine(TEXT("BAD LUCK! YOU HAVE LOST THE GAME.\nThe Hidden Isogram is '%s'."), *HiddenWord);
            EndGame();
            return;         
        }
        //Show the player Bulls and Cows
        FBullCowCount Score = GetBullsCows(Guess);
        PrintLine(TEXT("You have %i Bulls and %i Cows."), Score.Bulls, Score.Cows);
        //Show lives left
        PrintLine(TEXT("You have lost a life, %i lives remaining."), Lives);
        if (Lives == 1)
        {
            PrintLine(TEXT("Do you want some Hint? 1$ for 1 Hint.\nPress Y for Yes / N for No: "));
            if (Guess == "Y")
            {
                PrintLine(TEXT("First and Last letters are:%c, %c"), HiddenWord[0], HiddenWord[HiddenWord.Len() - 1]);
                PrintLine(TEXT("TRY AGAIN! YOU CAN DO IT."));
            }
        }
        
    }
}

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::GetValidWord(const TArray<FString>& WordList) const
{
    TArray<FString> ValidWords; 
    for (FString Word : WordList)
    {
        if (Word.Len() >=4 && Word.Len() <= 8 && IsIsogram(Word))
        {
            ValidWords.Emplace(Word);
        }
    }
    return ValidWords;
}

FBullCowCount UBullCowCartridge::GetBullsCows(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;

You don’t. That was directed to Brian showing that FString’s operator == is case insensitive.

Sorry I forgot to mention that you should add that as a member variable that is initially false. The code isn’t quite right.

I was suggesting you do that for printing the hint and have you have added after you subtract a life.
e.g.

void UBullCowCartridge::ProcessGuess(const FString& Guess)
{
    if (bGameOver)
    {
        // ...
    }
    else
    {
        if (Lives == 1 && !bHasSelected)
        {
            if (Guess == TEXT("Y")) // player wanted a hint
            {
            }
            else
            {
            }
            bHasSelected = true;
            return;
        }
        // rest of the game logic
        // ...
        --Lives
        if (Lives == 1)
        {
            PrintLine(TEXT("1 Life remaining, do you want a hint?"));
        }
    }
}
1 Like

Ok Finally I got it.
Thankyou very much DanM.
Below is my Process Guess Function had some errors like it was printing do you want hint?(Twice) Fixed up by adding !bHasSelected condition for both nested loops.
Also I declared bHasSelected bool in header file.
And I initialised bHasSelected to false in SetupGame function.
All this was a lot for me thank you danM once again. Learned a lot from this. I would suggest everyone to follow Mike blindly as he told to implement new function on our own it helped a lot. Thanks

void UBullCowCartridge::ProcessGuess(const FString& Guess)
{
    if (bGameOver)
    {
        ClearScreen();
        SetupGame();
    }
    // Check PlayerGuess
    else
    {
        if (Lives == 1 && !bHasSelected)
        {
            PrintLine(TEXT("Do you want some Hint? 1$ for 1 Hint.\nPress Y for Yes / N for No: "));
            if (Guess == "Y")
            {
                PrintLine(TEXT("First and Last letters are:%c,%c"), HiddenWord[0], HiddenWord[HiddenWord.Len() - 1]);
                PrintLine(TEXT("TRY AGAIN! YOU CAN DO IT."));
            }
            bHasSelected = true;
            return;
        }
        
        if (HiddenWord == Guess)
        {
            PrintLine(TEXT("FABULOUS, YOU NAILED IT!!"));
            EndGame();
            return;
        }
        //Check for correct length of word
        //Prompt to Guess Again
        else if (HiddenWord.Len()!= Guess.Len())
        {
            PrintLine(TEXT("Hidden word is %i characters long.\nPlease try again...."), HiddenWord.Len());
            PrintLine(TEXT("No lives deducted %i lives remaining"), Lives);
            return;
        }
        //Check for Isogram
        else if (!IsIsogram(Guess))
        {
            PrintLine(TEXT("CAUTION! Repetition is not allowed.\n%i lives left."), Lives);
            return;
        }
        //Deduct lives
        --Lives;
        //Show the player Bulls and Cows
        FBullCowCount Score = GetBullsCows(Guess);
        PrintLine(TEXT("You have %i Bulls and %i Cows."), Score.Bulls, Score.Cows);
        //Show lives left
        PrintLine(TEXT("You have lost a life, %i lives remaining."), Lives);
        
        if (Lives == 1 && !bHasSelected)
        {
            PrintLine(TEXT("Do you want some Hint? 1$ for 1 Hint.\nPress Y for Yes / N for No: "));
            if (Guess == "Y")
            {
                PrintLine(TEXT("First and Last letters are:%c, %c"), HiddenWord[0], HiddenWord[HiddenWord.Len() - 1]);
                PrintLine(TEXT("TRY AGAIN! YOU CAN DO IT."));
                return;
            }
        }
        //Check if lives > zero
        //If No, show GameOver and HiddenWord
        if (Lives == 0)
        {
            ClearScreen();
            PrintLine(TEXT("BAD LUCK! YOU HAVE LOST THE GAME.\nThe Hidden Isogram is '%s'."), *HiddenWord);
            EndGame();
            return;         
        }
    }
}

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms