So the task is relatively simple; create a program that will generate a random number, and then prompt the user to input a number. If the is lower or greater than the generated number, a message will display whether you're lower or higher than the number. The program also records how many attempts you've made. Every task of the program is to be made as a function.

This is what i've made so far. And it compiles fine.

/* Magic's Number game */
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main ()
{
    const int MAX_RANGE = 100; //Setting the max range
    //Intializing the Input, answer, and the number of guesses

    int answer, guess; 
    int tryCount = 0;

    /* initialize random seed: */
    srand ( time(NULL) );

    /* generate secret number: */
    answer = rand() % MAX_RANGE + 1;
    cout << answer << endl; //Comment out this line for a serious game.
    do 
    {
        //If the answer is lower or higher than the guess, the tryCount goes up
        cout << "Guess the number (1 to 100): " << endl;
        cin >> guess;
        if (answer<guess) 
        {
        cout <<   "The secret number is lower" << endl;

        tryCount += 1;
        }
        else if (answer>guess)
        {
        cout << "The secret number is higher" << endl;
        tryCount += 1;
        } 
    }
    //If the answer equals the guess, the number of guesses is outputted
    while (answer!=guess);
    cout << "The number of wrong attempts is: " << tryCount << endl;
    //Congratulates the user and exits the program.
    cout << "Congratulations!" << endl;
    return 0;
}

Theres nothing wrong with it. Everything compiles fine, but each task of the program has to be written as a function. And i'm not exactly sure what they mean by that.

Can anyone help? I think i need separate functions that probably replace the If statements.

You commented your code with some steps. You could say your program does the following:

  1. Intialize random seed.
  2. Generate secret number.
  3. Play guessing game. (keeps starting guess attempts until guessed, tracks amount of tries)
  4. Do guess attempt. (either right or wrong, involves asking the user for a number)
  5. Obtain number from user.

You might be able to find more subtasks or create a different list but the aim is to find subtasks and place their logic in seperate functions that call eachother.

Well probably. What you can do is to make functions of everything inside:
if, for example, you have a comparison answer<guess, you could do a function that compares two numbers, if the first one is lower than the 2nd, it will return -1, if they are equal it will return 0, and if the 1st is greather than the 2nd it will return 1.
Also, the number you're generating is to be generated just one time, so you could put it into a function, that will generate the random number.
You could make another function that increments a number, passing the number by its reference, and not a copy of the number, for the tryCount++ part.
If to be taken at extreme, you could do a print fuction which takes as argument one int:
if int is -1 print number is lower, if int is 0 print you are correct, and if int is 1 print number is higher.
You could think of all sort of mini-functions to play with.

So, what you're saying is; instead of having;

if (answer < guess) 
    {
    cout <<   "The secret number is lower" << endl;
    }

I should take out the Cout, and make it Return -1. And then later down in the code, put the Cout, referencing it by the -1?
No clue how to do that, but is that what you mean?

While I don't necessarily agree with creating a function to compare integers his suggestion is that you have a string-like compare. You get two numbers and if the first is smaller than the second the function returns -1, if they are equal it returns 0 and otherwise it returns 1.

I wouldn't create a function for that personally though as it doesn't really add anything in my opinion. You're not adding the result to something directly so you'd still have to branch on it's result. I'd go for creating functions of which you can convince yourself it makes sense to have them as functions in the first place and/or because it can be identified as an individual process in the entire application's workings.

Edited 4 Years Ago by Gonbe

Im pretty noobish when it comes to functions.

Can someone explain what it actually retuns when i type return -1 and i assume i have to reference it somewhere to state that the Return -1 means output "the number is lower".

The only experience i have with the return command is that it exits the program... And when i put Return -1 inside the if (answer < guess), it exits the program if the number is lower than the inputted number.

Making parts of your program into function calls is easy:

// Function prototype/declaration
// * Needs to be before the function call.
// * Ends in a semi-colon
// * The 'int' at the start is the "return-type", it can be any type
// * the things in the brackets are the "arguments", any number and type can
//   be specified. Only the types are needed by the compiler, the names (like
//   'x', in this case) are for people
int MyFunction( int x );

int main()
{
    int x = 2;
    int y = MyFunction( x );   // Function call
    std::cout << "x = " << x << " y = " << y << std::endl;
    return 0;
}

// Function definition
// * Contains the details of what the function actually does.
// * The return-type and argument number and types MUST match the prototype
// * The argument names must be present, but need not match the names in the
//   prototype
int MyFunction( int x )
{
    // The body of the function can contain anything that you would normally
    // see in main() - since main() is also a fucntion :)
    return 2*x;
}

What things to make into functions is your call. In general, functions are a kind of abstraction - they remove the details of how something is done from the user. This is generally good, since the user is mainly concerned with what the function does, not how it does it. Having logic in well-named functions also allows you to alter what that logic does without affecting the rest of the program and allows a piece of logic to be repeated at multiple points in the program without actually re-typing the code.

So, in your case, you could break the program into a bunch of logical bits, as suggested above. One might be "Generate a random number". This could contain details about how the range of the number is specified, what type of random-number generator is used, what user-input is required etc:

int GenerateRandom();

/* initialize random seed: */
srand ( time(NULL) );

int main()
{
    int random = GenerateRandom();

    std::cout << "Random = " << random << std::endl;

    return 0;
}

// The actual details of the function
int GenerateRandom()
{
    const int MAX_RANGE = 100; //Setting the max range

    /* generate secret number: */
    int random = rand() % MAX_RANGE + 1;

    return random;
}

Now, you might want a bit more flexibility, but you don't want to duplicate any of the code, if you can avoid it. So, I would consider making a series of random number generating functions (note how the second one calls the first):

int GenerateRandomInRange( int min, int max )
{
    return rand() % (max - min) + min;
}

int GenerateRandomWithUserRange()
{
    int userMin, userMax;
    std::cout << "Enter min" << std::endl;
    std::cin >> userMin;

    std::cout << "Enter max" << std::endl;
    std::cin >> userMax;

    return GenerateRandomInRange( userMin, userMax );
}

Hope that helps a little :)

Edited 4 Years Ago by ravenous

This question has already been answered. Start a new discussion instead.