Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Game Development

Reply
 
LinkBack Thread Tools Display Modes
Old 03-30-2009, 01:52 PM   #1 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Unhappy 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. :)

main.mm:

#import <UIKit/UIKit.h>
#include<iostream>
#include<cstdlib>
#include<ctime>

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;
}

cout << endl << "Congrats!! You got it" //<<tries<< "guesses."
<< endl;
return 0;
}

RandomnumberViewController.m:

#import "Randomnumber6ViewController.h"

@implementation Randomnumber6ViewController

@synthesize txtNumber,lblPleaseguess;

-(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
}


- (void)dealloc {
[super dealloc];
}

@end

RandomnumberViewController.h:

#import <UIKit/UIKit.h>

@interface Randomnumber6ViewController : UIViewController {
IBOutlet UITextField *txtNumber;
IBOutlet UILabel *lblPleaseguess;

}

@property(nonatomic,retain) IBOutlet UITextField *txtNumber;
@property(nonatomic,retain) IBOutlet UILabel *lblPleaseguess;
- (IBAction) updateText: (id) sender;

@end
cocoa is offline   Reply With Quote
Old 03-30-2009, 02:47 PM   #2 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

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
AEDave is offline   Reply With Quote
Old 03-30-2009, 03:47 PM   #3 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

Quote:
Originally Posted by AEDave View Post
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.
cocoa is offline   Reply With Quote
Old 03-30-2009, 11:06 PM   #4 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 29
rhfb is on a distinguished road
Default

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.

Here is what I came up with in 5 mins.


Code:
#import <UIKit/UIKit.h>

@interface RandomGuessViewController : UIViewController {
	IBOutlet UITextField *guess;
	IBOutlet UILabel *info;
	int answer;
}

@property (nonatomic, retain) UITextField *guess;
@property (nonatomic, retain) UILabel *info;

- (IBAction)doneGuessing:(id)sender;

@end
and

Code:
#import "RandomGuessViewController.h"

@implementation RandomGuessViewController

@synthesize guess;
@synthesize info;

- (IBAction)doneGuessing:(id)sender {
	[guess resignFirstResponder];
	NSInteger curGuess = [guess.text intValue];
	if(curGuess == 0) {
		info.text = @"Enter a guess silly!";
	}	
	else if(curGuess < answer) {
		info.text = @"TOO LOW!";
	}
	else if(curGuess > answer) {
		info.text = @"TOO HIGH!!!";
	}
	else if(curGuess == answer) {
		info.text = @"We have a winner!";
	}
}

- (void)viewDidLoad {
	answer = arc4random()%100 + 1;
	NSLog(@"%i", answer);
}

- (void)didReceiveMemoryWarning {
	[super didReceiveMemoryWarning];
}

- (void)dealloc {
	[guess release];
	[info release];
	[super dealloc];
}

@end
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.
rhfb is offline   Reply With Quote
Old 03-31-2009, 09:52 AM   #5 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

Quote:
Originally Posted by rhfb View Post
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.

Here is what I came up with in 5 mins.


Code:
#import <UIKit/UIKit.h>

@interface RandomGuessViewController : UIViewController {
	IBOutlet UITextField *guess;
	IBOutlet UILabel *info;
	int answer;
}

@property (nonatomic, retain) UITextField *guess;
@property (nonatomic, retain) UILabel *info;

- (IBAction)doneGuessing:(id)sender;

@end
and

Code:
#import "RandomGuessViewController.h"

@implementation RandomGuessViewController

@synthesize guess;
@synthesize info;

- (IBAction)doneGuessing:(id)sender {
	[guess resignFirstResponder];
	NSInteger curGuess = [guess.text intValue];
	if(curGuess == 0) {
		info.text = @"Enter a guess silly!";
	}	
	else if(curGuess < answer) {
		info.text = @"TOO LOW!";
	}
	else if(curGuess > answer) {
		info.text = @"TOO HIGH!!!";
	}
	else if(curGuess == answer) {
		info.text = @"We have a winner!";
	}
}

- (void)viewDidLoad {
	answer = arc4random()%100 + 1;
	NSLog(@"%i", answer);
}

- (void)didReceiveMemoryWarning {
	[super didReceiveMemoryWarning];
}

- (void)dealloc {
	[guess release];
	[info release];
	[super dealloc];
}

@end
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!
cocoa is offline   Reply With Quote
Old 03-31-2009, 01:50 PM   #6 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 29
rhfb is on a distinguished road
Default

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 is offline   Reply With Quote
Old 04-01-2009, 02:27 PM   #7 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

Quote:
Originally Posted by rhfb View Post
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!
cocoa is offline   Reply With Quote
Old 04-01-2009, 05:20 PM   #8 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 29
rhfb is on a distinguished road
Default

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.

http://i43.tinypic.com/13z7thi.png
http://i44.tinypic.com/33bfsc7.png
http://i43.tinypic.com/1zm1esh.png
http://i40.tinypic.com/15mo709.png

Last edited by rhfb; 04-01-2009 at 05:33 PM.
rhfb is offline   Reply With Quote
Old 04-02-2009, 05:59 AM   #9 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

Ok a couple of questions arose this morning when we tried to implement the code per your instructions.

1. We entered this piece of code into ViewController.h

Quote:
#import <UIKit/UIKit.h>

@interface RandomGuessViewController : UIViewController {
IBOutlet UITextField *guess;
IBOutlet UILabel *info;
int answer;
}

@property (nonatomic, retain) UITextField *guess;
@property (nonatomic, retain) UILabel *info;

- (IBAction)doneGuessing:(id)sender;

@end
2. We entered the following piece of code into ViewController.m

Quote:
#import "RandomGuessViewController.h"

@implementation RandomGuessViewController

@synthesize guess;
@synthesize info;

- (IBAction)doneGuessing:(id)sender {
[guess resignFirstResponder];
NSInteger curGuess = [guess.text intValue];
if(curGuess == 0) {
info.text = @"Enter a guess silly!";
}
else if(curGuess < answer) {
info.text = @"TOO LOW!";
}
else if(curGuess > answer) {
info.text = @"TOO HIGH!!!";
}
else if(curGuess == answer) {
info.text = @"We have a winner!";
}
}

- (void)viewDidLoad {
answer = arc4random()%100 + 1;
NSLog(@"%i", answer);
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

- (void)dealloc {
[guess release];
[info release];
[super dealloc];
}

@end
3. The AppDelegate.h file then has the following code in it:
Quote:
#import <UIKit/UIKit.h>

@class Randomnumber7ViewController;

@interface Randomnumber7AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
Randomnumber7ViewController *viewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet Randomnumber7ViewController *viewController;

@end
4. The only error we have received occurs in the AppDelegate.m file:

Quote:
#import "Randomnumber7AppDelegate.h"
#import "Randomnumber7ViewController.h"

@implementation Randomnumber7AppDelegate

@synthesize window;
@synthesize viewController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {

// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}


- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}


@end
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 :(

Last edited by cocoa; 04-02-2009 at 06:05 AM.
cocoa is offline   Reply With Quote
Old 04-02-2009, 06:02 AM   #10 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

Our main.m file looks like this btw:

#import <UIKit/UIKit.h>

@interface RandomGuessViewController : UIViewController {
IBOutlet UITextField *guess;
IBOutlet UILabel *info;
int answer;
}

@property (nonatomic, retain) UITextField *guess;
@property (nonatomic, retain) UILabel *info;

- (IBAction)doneGuessing:(id)sender;

@end
cocoa is offline   Reply With Quote
Old 04-02-2009, 06:25 AM   #11 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 11
cocoa is on a distinguished road
Default

rhfb

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
cocoa is offline   Reply With Quote
Old 04-02-2009, 12:49 PM   #12 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 29
rhfb is on a distinguished road
Default

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.
rhfb is offline   Reply With Quote
Reply

Bookmarks

Tags
error, game, generate, number, random

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 407
8 members and 399 guests
13dario13, ChrisYates, fredidf, iOS.Lover, Leslie80, Meoz, Wikiboo, Yosh_K
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,670
Threads: 94,121
Posts: 402,903
Top Poster: BrianSlick (7,990)
Welcome to our newest member, Yosh_K
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 04:38 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0