why isnt this c++ code working?

Started by
7 comments, last by All8Up 12 years, 9 months ago
[font=arial, verdana, tahoma, sans-serif][size=2]I'm guessing you'll notice i'm new at this.

Two things,



// generate new number
if (g_numb > c_numb)
{g_numb = (g_numb % 100) + 1;}
if (g_numb < c_numb)
{g_numb = (100 % g_numb) +1;}


this portion I don't know if it will work, i'm trying to get a high and low to a random number, though if I take out the half that I don't know about I still get the same problem.

That problem being asked to a number, completing \n, and pausing indefinitely.

Plz help!

// Computer, guess my number!


#include <iostream.h>
#include <cstdlib>
#include <ctime>

int cal();
//int chk();

int c_numb;
int g_numb;
char temp;

int main()
{
// get the correct number (c_numb)
cin >> c_numb;
cout << "\n";

do // Game Loop
{
// call number calculation
int cal();

// call number checking
int chk();
} while (g_numb != c_numb);

// Exit
cout << "enter a keystroke to exit";
cin >> temp;
return(0);
}

int cal()
{
// generate a base number
if (g_numb == NULL)
{srand(time(0));
int g_numb = rand();}

// generate new number
if (g_numb > c_numb)
{g_numb = (g_numb % 100) + 1;}
if (g_numb < c_numb)
{g_numb = (100 % g_numb) +1;}

// exit function
return(0);
}

int chk()
{
// print current guess
cout << g_numb;

// print corrective statement
if (g_numb != c_numb)
{cout << "Incorrect\n";}
if (g_numb == c_numb)
{cout << "Correct! Keystroke exit.";
cin >> temp;}

// exit function
return 0;
}
[/font]
Advertisement
Your problem is right here...
[color=#1C2837][font=CourierNew, monospace][size=2][color=#000088]while[color=#000000] [color=#666600]([color=#000000]g_numb [color=#666600]!=[color=#000000] c_numb[color=#666600]); [/font]
[color=#1C2837][font=CourierNew, monospace][size=2][color=#666600]
[/font]
[font="CourierNew, monospace"][color="#666600"]When you get to that line of code you have nothing to do while in that loop so the loop carry's on infinently [/font]
shouldn't the program continue calling the functions?

if not, care to provide some guidance?

I am using Visual Studio as IDE and I can't even debug your code.

First of all it can't find cin and cout, because it is std::cin and std::cout.

Secondly in the do-while loop, you should write "cal()" and not "int cal()".

Another problem is "int g_numb = rand();".
You are declaring g_numb in this scope and you don't change the g_numb that was declared globally.
You should change it to: "g_numb = rand();"

After these changes the program worked and kept printing "Incorrect". (I was using the number 50)
TGUI, a C++ GUI for SFML
texus.me
1. g_numb and c_numb are dreadful names. I know they're numbers - I can see they're ints. Even if I couldn't, my IDE would tell me. Just go with 'guess' and 'correct' or similar. This also goes for 'cal' and 'chk'.

2. lines like 'int chk();' don't call a function, they declare one - they're saying that a function with that prototype exists somewhere. They don't get turned into executable code at all. You want something like 'int returnedValue = function();' (Except with better names, of course!)

3. you call srand every time you go into cal; don't do this - as a general rule, you want to call srand exactly once, probably at the start of main for convenience. You can think of srand as choosing the sequence of 'random' (psuedo-random) numbers you'll get. One problem with what you're doing is that if you're calling it in a tight loop, then you get onto the next iteration, the next call to srand, before the time you're using as a seed has advanced (because the time between these iterations could be measured in microseconds or less). One exception to this is if you're doing something like generating random worlds, then you can just save the seed and then regenerate the world when you load the game again.

4. don't have functions return meaningless values - cal only ever returns 0?

5. If you're trying to generate a number in a range, then you want (rand() % (1 + max - min)) + min. So if you know you guessed too high, you want to guess between, say, 1 and the number you just guessed: (rand() % last_guess) + 1. It's a side note here that this actually can be pretty dreadful in terms of an uneven distribution (some numbers will be much more likely to be guessed than others) but that's probably not of interest at this stage.

6. Don't write loads of code and then try to compile when you're done. Compile as you go. When you're learning, I'd be compiling every 2 or 3 lines - it won't take long with projects this small.
[TheUnbeliever]
Thanks, i'll keep it all in mind in the future
There are all sorts of little gotcha's in this code, here are the most obvious:
[font="arial, verdana, tahoma, sans-serif"]
// Computer, guess my number!
int c_numb;
int g_numb;
char temp;

int main()
{
// get the correct number (c_numb)
cin >> c_numb;
cout << "\n";

do // Game Loop
{
// call number calculation
int cal();

[/font][font="arial, verdana, tahoma, sans-serif"]That will end up making a new int in the scope of main named "cal" and default initializing it, it won't call the "function" as intended because you are changing the meaning within the local scope. Remove the "int" in order to actually call the function. (I'm fairly sure this will not simply forward declare the function since it is in scope of another function.)[/font]
[font="arial, verdana, tahoma, sans-serif"] [/font]

int cal()
{
// generate a base number
if (g_numb == NULL)
{srand(time(0));
int g_numb = rand();

Again, the "int" here changes the meaning of the code. You are not assigning to the global "g_numb" but instead creating a new local scope variable which is assigned to then destroyed. In other words, this does absolutely nothing. Remove the int and it will actually assign to the global variable as desired.
Gotta give the newbie some credit... pweese? :-)

ok I fixed what I was told, if theres any more sticking out please let me know so I can learn from them. The program works now, although it picks a random number and counts up from it.



// Computer, guess my number!

#include <iostream.h>
#include <cstdlib>
#include <ctime>

int cal();
int chk();

int c_numb;
int g_numb;
char temp;

int main()
{
// get the correct number (c_numb)
std::cin >> c_numb;
std::cout << "\n";

do // Game Loop
{
// call number calculation
cal();

// call number checking
chk();
} while (g_numb != c_numb);

// Exit
return(0);
}

int cal()
{
// generate a base number
if (g_numb == NULL)
{srand(time(0));
g_numb = rand();}

// generate new number
if (g_numb > c_numb)
g_numb = (g_numb % 100) + 1;
if (g_numb < c_numb)
g_numb = (g_numb % 100) + 1;

// exit function
return(0);
}

int chk()
{
// print current guess
std::cout << g_numb;

// print corrective statement
if (g_numb != c_numb)
{std::cout << "Incorrect\n";}
if (g_numb == c_numb)
{std::cout << "Correct! Keystroke exit.";
std::cin >> temp;}

// exit function
return 0;
}


I know these two lines are the same, I was just trying to get it to be random before attempting a reverse ordered random, which I would like some explanation with aswell :)



// generate new number
if (g_numb > c_numb)
g_numb = (g_numb % 100) + 1;
if (g_numb < c_numb)
g_numb = (g_numb % 100) + 1;


GO NEWBIES!
We can easily eliminate the unnecessary globals by making use of parameters and the return values of the function. Functions with no meaningful return value should be declared "void", to clarify your intent. The entry point, main(), is an exception. We should declare it returning int, but we are allowed omit the return statement. If you return no value from main(), the compiler makes it as if you had returned "0", which indicates success when returned from main().

We can also eliminate the redundant function declarations by moving the function definitions higher in the source file. This reduces the maintenance burden, it is one less thing we need to change if we want to modify the function signature.

Writing good variable/function names is very important. I recommend you get out of the habit of using an encoded shorthand for them.

Error checking is equally important. I've included basic error checking for reading in the answer here.

#include <iostream>
#include <cstdlib>
#include <ctime>

int generateGuess()
{
int i = std::rand() % 100;
return i + 1;
}

int main()
{
// Seed the random number generator
std::srand(std::time(NULL));

int answer;
if(std::cout << "Enter your number: " && std::cin >> answer)
{
std::cout << "You have selected: " << answer << '\n';
}
else
{
std::cerr << "You did not enter a number\n";
return 1;
}

// Game loop
boolean running = true;
while(running)
{
int guess = generateGuess();

if(guess == answer)
{
std::cout << "The computer guessed correctly: " << guess << '\n';
running = false;
}
else
{
std::cout << "The computer guessed incorrectly: " << guess << '\n';
}
}
}

Some other points:

  • Standard header files do not have .h extensions. Use #include <iostream> instead of <iostream.h>
  • Comparing a number with NULL is wrong. NULL should be reserved for interacting with pointers. NULL is really just the integer constant 0, which means that your comparison is not checking if g_numb had been set. In fact, global variables are zero initialised (complex types excepted), so you're really just checking if g_numb is zero. This could result in std::srand() being called multiple times.
  • As others have mentioned, the easiest way to seed the random sequence is to call std::srand() once at the start of main, and never again.
  • Try to keep I/O away from the actual game logic. In such a simple game, this isn't obvious, but it makes the code much easier to read and test if these things are separated. Here, the game logic is mainly in the generateGuess() function. I didn't move the game winning condition to a new function as it is trivial here. For a complex game you should.
  • I've avoided checking the winning condition twice. For a more complex game like chess, this is a good idea, and it ensures the logic is consistent (you don't have any chance of accidentally modifying the game state to revert to a non-finished state).

Future improvements:

  • Use a loop until the user enters a valid number. Remember valid doesn't just mean a number, it appears to mean a number between 1 and 100.
  • Make the computer smarter. It is traditional in such games to let the guesser know if they need to go higher or lower. The computer's guess function should take just enough input that will allow it to make the decision the same way a human might.

Gotta give the newbie some credit... pweese? :-)

Sorry, didn't mean to come across badly, I just wanted to post the fixes and explanations.

Unfortunately I don't understand what you mean by "reverse ordered random", so I can't really help further without a little more explanation.

This topic is closed to new replies.

Advertisement