iPhone random number game error=newbies need help!
This is some code which is supposed to program a simple iPhone application which generates a random number, the user must guess the correct number and the program will give it the appropriate feedback. The main code itself seems to compile succesfully in C++ (we changed the file extension to main.mm because of this) however, we only started working on the GUI after we had finished the main code.
The only error we have received is the one indicated in red text regarding the randomly generated number in the ViewController.h file. Any suggestions as to how to solve this problem? Is there anything else which would prohibit the code from functioning seamlessy together in a working iPhone application?
We are honestly beginners and would appreciate any help whatsoever. :)
using namespace std;
int main()
{
//Seed random number generator
srand(time(0));
//Creates the random number between 1 and 10
int theNumber = rand() % 10 + 1;
int guess;
//Guessing loop
int tries;
while (guess != theNumber)
{
cout<<"Please guess the number!: ";
cin>>guess;
++tries;
if (guess > theNumber)
cout<<"Too high,Guess again:"<< endl << endl;
if (guess < theNumber)
cout << "Too low,Guess again: "<< endl << endl;
}
-(IBAction) updateText: (id) sender {
NSString *text;
if([srand(time(0)] == int guess)
{
text = @"Congrats!! You got it";
}
else
{
if (guess > theNumber) text = [[NSString alloc] initWithFormat:@"Too high,Guess again:"
if (guess < theNumber) text = [[NSString alloc] initWithFormat:@"Too low,Guess again:"
}
lblPleaseguess.text = text;
[text release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
Uhm, only took a quick glance at your code, but where are you deriving the value for the guess variable? I'm assuming that the IBAction is a series of buttons or something, each with a number on it? In that case, you would want to set guess kinda like this:
Code:
int guess;
guess = ([sender titleForState:UIControlStateNormal], intValue);
if (randomnumber == guess)
{
// right answer
}
else
{
// wrong answer
}
Like I said, I didn't look at everything and I'm not sure how you're getting the answer that the user specifies, but if it's a series of buttons with a number on them all connected to the same IBAction, this'll do the trick.
Also, please put code in [ code ] and [/ code ] brackets, thanks!
Uhm, only took a quick glance at your code, but where are you deriving the value for the guess variable? I'm assuming that the IBAction is a series of buttons or something, each with a number on it? In that case, you would want to set guess kinda like this:
Code:
int guess;
guess = ([sender titleForState:UIControlStateNormal], intValue);
if (randomnumber == guess)
{
// right answer
}
else
{
// wrong answer
}
Like I said, I didn't look at everything and I'm not sure how you're getting the answer that the user specifies, but if it's a series of buttons with a number on them all connected to the same IBAction, this'll do the trick.
Also, please put code in [ code ] and [/ code ] brackets, thanks!
Dave
First of all thank you Dave for responding, it means a lot especially because we're (there are two of us) pretty young and inexperienced with coding on any platform let alone the iPhone. Secondly, sorry about not putting the code in brackets (we had no idea that's what you're supposed to do! :( ).
The idea for the app is just a labelUI where we write something like "Please guess a number" and a textfieldUI below it. The user then enters a number or a guess into the text field and presses done on the generic iPhone keyboard (i.e no additional button necessary) and the program tells the user whether it's right or wrong based on the randomly generated number it produces every time the app is launched.That's why we have this:
[code]
if([srand(time(0)] == int guess)
{
text = @"Congrats!! You got it";
}
[/ code ]
If the user guesses the same number as the one the program generated then it should display the congrats message otherwise it should tell the user whether the number they entered was too high/low.
Our teacher suggested replacing this srand(time(0) line of code with a set integer (eg.the number 5) to see whether the code + interface would compile successfully but we haven't tried it yet.
Is there a conflict with the definition of the variables between the main.mm, ViewController.h and ViewController.m files? Does the code even make sense honestly? We seem to be working with a mixture of C++ & objective-C here and there but we don't even know if this has a chance at compiling in a functioning application! The main code itself seemed to compile correctly but what's an iPhone app without an interface right?!
Ps. We have tried to use Interface builder to create the basic visual outline of the app and we think we've connected the different parts (textfield,label etc) with the appropriate outlets but we can never be sure.
a) Use arc4random and not rand
b) Don't use a main method. If you need to set a variable (like the number to be guessed) override the - (void)viewDidLoad method.
Put that code together with a very simple job in IB (just take the vc's xib and through in a UITextField, Label, and Button(send to back and change to custom), link the text field and label, and make the button link to the doneGuessing method.
a) Use arc4random and not rand
b) Don't use a main method. If you need to set a variable (like the number to be guessed) override the - (void)viewDidLoad method.
Put that code together with a very simple job in IB (just take the vc's xib and through in a UITextField, Label, and Button(send to back and change to custom), link the text field and label, and make the button link to the doneGuessing method.
Thanks for the help! We'll try to make the necessary changes and let you know how it goes. You'll have to excuse our ignorance, we're really new at this but we are interested to learn all the time so your help definitely means a lot to us!
No problem, if anything pops up let me know. The only thing I wasn't too clear on was the fact that the Number keypad has no done button, so to clear the screen you have to tap off the keypad to close it (hence the button the size of the screen, sent to the back, and custom). That is why I had to add in the check for a 0, because when the text field is empty, the intValue of it is 0. You could also just remove the last else if check, because if the text isn't above or below it has to be equal right? (I'd still leave it in to make sure 100% that the text in the field matches the answer)
No problem, if anything pops up let me know. The only thing I wasn't too clear on was the fact that the Number keypad has no done button, so to clear the screen you have to tap off the keypad to close it (hence the button the size of the screen, sent to the back, and custom). That is why I had to add in the check for a 0, because when the text field is empty, the intValue of it is 0. You could also just remove the last else if check, because if the text isn't above or below it has to be equal right? (I'd still leave it in to make sure 100% that the text in the field matches the answer)
rhfb
We thought that the Number keypad automatically provides a done button although we didn't even give it much thought to be honest. But do we need an additional button? Doesn't the keypad have an "OK" button on it which triggers the action?? Or does this button only trigger the action of the inputed text field if there is a preexisting button whose action it imitates?
Just to get things straight: Are you saying that we can't just have a text field with no button for the user to press where the code is instead run when the user presses the "OK" button on the generic Keypad? Or are you only talking about the done button which is supposed to appear on the Keypad, that this needs to connect to the code and that we need to add a visual button? Just a bit confused.
Is there a done button in the Interface Builder Library or what did you mean when you said "Button(send to back and change to custom)"? I'm not currently on the Mac we're using to program the app and that's why it's harder to follow along as quickly because I don't have 24hr access to the computer and can't simply check these things.
How many buttons do we need? One done button or a done button and another button next to the text field (which says "press to guess" or smth)?
Hope you understand the many questions, it's hard to articulate exactly what one means...
PS.Thank you for explaining 0 means the text field is empty,we would have assumed it meant when the guess is equal to zero!
I was saying if you are using the numeric keypad (0-9) there isn't a done button, just a button to go back. If you use a regular keyboard there is a done button, but why would you want the user to have the chance of entering text in a numeric guessing game?
In interface builder just drag a Round Rect Button to your view, change its size so it covers the entire screen, change its type (bring up the inspector and go to the first tab) to custom, and then send the button to the back. You also want to link the Touch Up Inside event to the IBAction method.
In my example there actually isn't a single "visible" button. The game starts with an empty text field and label. Depending on what is typed into the text field, the label changes. I guess you could do the same thing I've done with the button in the background effect with a regular button, I was just following an example I had seen in a book I'm using.
edit: Well if the guess IS 0 then that is what the response would be. You could do some extra work on the text value of the text field to see if it is empty before converting it to an int value, but if the answer can never be 0, I figured this would be ok for an example at least.
edit2: here are some pics I took of the app running. The single button in the entire app is like I said, the size of the entire screen and hidden behind everything else. When the user is done typing a number in the keypad, they tap anywhere NOT on the keypad, and the keypad closes, and the logic checking to see if the answer is correct kicks in. Didn't know if the pics were too large, so I linked them as URLs instead of images.
The error indicated above in red states; "error: request for member 'view' in something not a structure or union"
Our question then is: What are we doing wrong? You didn't mention anything about the AppDelegate files but this is where the error occurs. We haven't added the button/text field and label yet because of this error. We are not quite sure what you meant with your instructions on how to do that either. We tried to ignore the error momentarily and went ahead with Interface Builder but got stuck after changing the button type to custom "custom, and then send the button to the back. You also want to link the Touch Up Inside event to the IBAction method." How exactly do you send the button back and how do you link the IBAction method to the Touch Up Inside event. We have located the Button Connections and found the Touch Up Inside event but should we create an IBAction inside the Identity Inspector as a Class Action?
If you could explain these steps (in Interface Builder especially) step by step we would be very grateful. We just don't understand why it doesn't work for us and we're desperate at this point :(
Ok, we tried it again and it compiled succesfully! The problem was actually in the naming of the files anyway...thank you so much.
However, we would still appreciate it if you could clarify the Interface Builder steps
Your main.m file should usually be left alone, and look something like this
Code:
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
For interface builder, double click on the ViewController.xib and once in interface builder, add in the label, connect it to the outlet, add the text field, connect it to the outlet, and finally add in the button and connect the TouchUpInside to the method. You shouldn't have to link the file owner to the view's view, but if you have an error, try that.