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-09-2009, 10:17 AM   #1 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default Tic Tac Toe Tutorial - A Walkthrough

I have noticed a lot of people asking for help on creating a game. Everyone wants everyone else to basically build the game for them or they have unrealistic goals set on a big project. I realize that everyone wants to make Halo , F.E.A.R Files or Hello Kitty’s Island Adventure, but you got start small and get the basics first. You need to have fundamental understanding of how any program language works before you can create a BIG project. But no one developer is single handedly responsible for large games.

So I have decided to create a Tic Tac Toe game walkthrough for all of us NOOBs to game development. And that is the first time I have ever written the word noob in my life. I myself am no Objective-C master or whiz kid. I am a web developer with PHP, MySQL and Java programming background. I am attempting to learn Objective-C on the iPhone for fun. I have no idea what I am doing. But apparently there are a lot of others who don’t either. So I figured we could all learn together by building a game that is “simple”. And because everyone knows the rules, we will all be on the same page for mechanics. We all have some unique experiences and I think that if we all contribute to one game, we all will learn something.

If those with greater experience sees that I am doing something wrong, or a better way of doing something, PLEASE by all means chime in. While I am not blatantly asking someone to basically do the code for me, it doesn’t hurt to have a guiding hand point us in the right direction.

On a side note, I am going to make mistakes. We may have to revisit what we have coded before and rewrite it. But that’s what learning is about. So be patient and I will TRY to answer questions if I know the answer. If you are reading this hoping to just get a copy of the finished product and don’t want to take the time to read the actual walkthrough, then that is your choice. BUT you will miss the learning aspect of what I am trying to do, and you will not benefit from it at all. I also recommend not just copying and pasting the code into XCode. Try just typing out the code. This will aid in memory. I know it may seem like a lot of code at first, but just try it. If you want to learn something, you gotta practice it over and over again.
I will try to be as clear as possible and post some images if I can along the way. If you want to add something to the tutorial that is great, and I encourage you to donate your information and I will include your code in the official tutorial. But for all intent and purposes MY posts will be the official walkthrough so anyone following along at home can skim through the forum to find my name and keep up with the tutorial. If you do put up some code for us to use in the tutorial, please comment it as much as possible about what it is doing or why something will work. This will help everyone understand the reasoning behind your code. And its just good practice. ☺
So with all that said, let’s begin! Start by downloading the zip file that contains the images.

TicTacToe

It helps to write out what we want it to do. Right now it will be as if there are two people playing the game. Later we may add an AI so the user can play against the computer. BUT lets just getting it working right now.
We want the user to touch a square on the board and place a X or an O depending on whose turn it is.

We want to check for a win after the user places their token on the board.
If there is no winner, then update the text label to say that it is the next persons turn.
We also want there to be a button that allows the user to manually reset the game.

Open XCode and create a new View based application.

I called mine tictactoe.


Unzip the files and Drag them into the resources folder.

Open up tictactoeViewController.h and put in the following information:

Code:

#import <UIKit/UIKit.h>

@interface tictactoeViewController : UIViewController {
	//the image of the X or O
	IBOutlet UIImage * oImg;
	IBOutlet UIImage * xImg;
	
	//these are the UIImageViews that will hold the X or O
	//the 's' stands for Slot
	IBOutlet UIImageView *s1;
	IBOutlet UIImageView *s2;
	IBOutlet UIImageView *s3;
	IBOutlet UIImageView *s4;
	IBOutlet UIImageView *s5;
	IBOutlet UIImageView *s6;
	IBOutlet UIImageView *s7;
	IBOutlet UIImageView *s8;
	IBOutlet UIImageView *s9;
	
	//button to manually reset the game
	IBOutlet UIButton *resetButton; 
	
	//Image view that will hold the # pattern
	IBOutlet UIImageView * board;
	
	//label to let the player know who can go or let player know who wins
	IBOutlet UILabel * whoseTurn;
	
	//integer that represents the player
	NSInteger playerToken;
}

@property (nonatomic,retain) UIImage *oImg;
@property (nonatomic,retain) UIImage *xImg;

@property (nonatomic,retain) UIButton *resetButton;

@property (nonatomic,retain) UIImageView *board;

@property (nonatomic,retain) UIImageView *s1;
@property (nonatomic,retain) UIImageView *s2;
@property (nonatomic,retain) UIImageView *s3;
@property (nonatomic,retain) UIImageView *s4;
@property (nonatomic,retain) UIImageView *s5;
@property (nonatomic,retain) UIImageView *s6;
@property (nonatomic,retain) UIImageView *s7;
@property (nonatomic,retain) UIImageView *s8;
@property (nonatomic,retain) UIImageView *s9;


@property (nonatomic,retain) UILabel * whoseTurn;

//method that will change the player and update the label and place the X or O on the board
-(void) updatePlayerInfo;

//method that will check to see if someone has won returns TRUE if someone wins
-(BOOL) checkForWin;

//button reset
-(IBAction)buttonReset;

//this will reset the game, by clearing the board and reseting the playerTurn to 1
-(void) resetBoard;

@end
Now open up the tictactoeViewController.xib by double clicking it
Drag one UIImageView to the window and resize it to be 300x300 and set its image to board.png by using the Attributes Inspector.

Then drag 1 more UIImageView to the window and resize it to 100x100 then check the box for User Interaction Enabled.

Then copy and paste that 8 more times. Move those boxes to be hovering over the spaces of the game board lining them up.

Drag a UILable to the window and position it under the board.

Drag a UIButton to the window and rename the text to RESET GAME.

Now that we have the basic layout, control click (or right click if you can) top left UIImageView starting and drag the + sign to the Files Owner and select S1.

Then go to the top middle piece and do the same selecting S2, continue on until all 9 UIImageViews have been assigned.

Then control-click the Label and click the + sign and drag to files owner and select whoseTurn.

Then control-click the Reset Button and click the + sign from the TOUCH UP INSIDE and drag to the files owner and select resetButton.

Save and close the Interface Builder

Open up the tictactoeViewController.m and type the following code.

I have tried to comment a lot of it. And this is just a skeleton.


Code:

#import "tictactoeViewController.h"


//the NSInteger holds a numerical value of the player
//X is represented by a 1 (one)
//O is represented by a 0 (zero)



@implementation tictactoeViewController

//since we created somethings in the header we need to synthesize them here.
//just to keep things clean and in order I broke up the synthesizing but you could
//have very well put them all on one line, or put everyone on its own @synthesize
@synthesize s1,s2,s3,s4,s5,s6,s7,s8,s9;
@synthesize oImg,xImg,whoseTurn,board;
@synthesize resetButton;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
	

		}
    return self;
}


//this is where we will put the touch event for the tic tac toe game
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

	
}
//this is the button that will call the resetBoard method
-(IBAction) buttonReset{
	
}



//method that will check to see if someone has won returns TRUE if someone wins
-(BOOL) checkForWin{
	//right now return 1 becuase we havn't implemented this yet
	return 1;
}

//this will reset the game, by clearing the board and reseting the playerTurn to 1
-(void) resetBoard{


}

//method that will change the player and update the label and place the X or O on the board
- (void) updatePlayerInfo{
	if(playerToken == 1){
		
		playerToken == 2; //because now its the second players turn
		whoseTurn.text = @"O can go"; //Update the label to tell who goes next
		
	}
	if(playerToken == 2){
		playerToken == 1;
		whoseTurn.text =@"X can go";
		
	}
		
}

- (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 {
	//we have to release all the stuff we created in the header for memory managment
	[s1 release];
	[s2 release];
	[s3 release];
	[s4 release];
	[s5 release];
	[s6 release];
	[s7 release];
	[s8 release];
	[s9 release];
	[resetButton release];
	[board release];
	[oImg release];
	[xImg release];
	[whoseTurn release];
    [super dealloc];
}

@end


Now you should be able to build and run the project and see the board the UILabel and the Reset Button.

This is just a skeleton of the project so far. Nothing works right now. But we will get there.

This is all for now. If anyone has any suggestions or sees a problem with how I am doing it so far PLEASE say something!

QUESTIONS? Comments?
Attached Images
File Type: jpg part1.jpg (47.8 KB, 246 views)
Attached Files
File Type: zip images.zip (46.0 KB, 850 views)
windmarble is offline   Reply With Quote
Old 03-09-2009, 03:02 PM   #2 (permalink)
New Member
 
Join Date: Jan 2009
Posts: 8
JonathanE is on a distinguished road
Default

It is amazing that as soon as I start working on something, someone else comes out with the exact same thing. I made a TTT game in C# before and just re-made it in objC, its almost done. I was thinking about making a tutorial about it.
JonathanE is offline   Reply With Quote
Old 03-09-2009, 03:05 PM   #3 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Quote:
Originally Posted by JonathanE View Post
I was thinking about making a tutorial about it.

Well you can always contribute to this thread!
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-09-2009, 03:45 PM   #4 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default Tutorial Part 2

Ok open up tictactoeViewController.m and add the following method

Code:
-(void)viewDidLoad{
    //add the images, this way all we have to call is oImg or xImg instead of writing out [UIIMage imagename:@.....
    oImg = [UIImage imageNamed:@"O.png"];
    xImg = [UIImage imageNamed:@"X.png"];
    
    //set the player token to 1 because we need to initalize the playertoken
    playerToken = 1;
    //update the text field to let player know who can go
    whoseTurn.text =@"X can go";


}
Also I need to correct the updatePlayerInfo method. Why? Because if you look at it now when the method is called if the playerToken is 1 it sets it to 2. Then it looks at the second if statment and sets the player token back to 1. And we aren't actually setting anything, I have two == which is doing a comparsion.

So here is the updated updatePlayerInfo method
Code:
//method that will change the player and update the label and place the X or O on the board
- (void) updatePlayerInfo{
    if(playerToken == 1){
        playerToken = 2; //because now its the second players turn
        whoseTurn.text = @"O can go"; //Update the label to tell who goes next
        
    } else {
        playerToken = 1;
        whoseTurn.text =@"X can go";
        
    }
        
}
I also updated the resetBoard and resetButton methods
Code:
//this is the button that will call the resetBoard method
-(IBAction) buttonReset{
    [self resetBoard];
    
}


//this will reset the game, by clearing the board and reseting the playerTurn to 1
-(void) resetBoard{
    ///clear the images stored in the UIIMageView
    
    s1.image = NULL;
    s2.image = NULL;
    s3.image = NULL;
    s4.image = NULL;
    s5.image = NULL;
    s6.image = NULL;
    s7.image = NULL;
    s8.image = NULL;
    s9.image = NULL;
    
    //reset the player token and update the label text
    playerToken= 1;
    whoseTurn.text = @"X can go";


}
Now for the fun part
The touches method will check to see which UIImageView was touched and then update its view with the correct image. There has got to be a better way to do that than the way I have created it.

Code:
//this is where we will put the touch event for the tic tac toe game
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    
    
    UITouch *touch = [[event allTouches] anyObject];
    
    //check to see if the point that was touched is in one of the UIImage views
    if(CGRectContainsPoint([s1 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s1.image = xImg; }
        if(playerToken==2){ s1.image = oImg; }
    }
    
    if(CGRectContainsPoint([s2 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s2.image = xImg; }
        if(playerToken==2){ s2.image = oImg; }
    }
    
    if(CGRectContainsPoint([s3 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s3.image = xImg; }
        if(playerToken==2){ s3.image = oImg; }
    }
    
    if(CGRectContainsPoint([s4 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s4.image = xImg; }
        if(playerToken==2){ s4.image = oImg; }
    }
    
    if(CGRectContainsPoint([s5 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s5.image = xImg; }
        if(playerToken==2){ s5.image = oImg; }
    }
    
    
    if(CGRectContainsPoint([s6 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s6.image = xImg; }
        if(playerToken==2){ s6.image = oImg; }
    }
    
    if(CGRectContainsPoint([s7 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s7.image = xImg; }
        if(playerToken==2){ s7.image = oImg; }
    }
    
    if(CGRectContainsPoint([s8 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s8.image = xImg; }
        if(playerToken==2){ s8.image = oImg; }
    }
    
    if(CGRectContainsPoint([s9 frame], [touch locationInView:self.view])){
        if(playerToken==1){ s9.image = xImg; }
        if(playerToken==2){ s9.image = oImg; }
    }
    
    
    
    [self updatePlayerInfo];
    
}
Now you should be able to come the program and touch each of the squares and see it fill it in.

Things we need to fix though: Once you place an x or O in the square you can touch the same square again and it will change the image. We need to disable that square once it has been touched.

Questions? Comments? Better ideas?
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-10-2009, 09:06 PM   #5 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

+REP! Thanks for the tutorial.

Quick question though: wouldn't it be easier to do a select case in the touchesBegan section? I'm a noob, so slap me if that's not an option for some reason.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 11:57 AM   #6 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Quote:
Originally Posted by AEDave View Post
+REP! Thanks for the tutorial.

Quick question though: wouldn't it be easier to do a select case in the touchesBegan section? I'm a noob, so slap me if that's not an option for some reason.

Dave

Hey that might work. I didn't think of using a switch case. Why don't you write it up and we can test it and see how well it works?
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 12:25 PM   #7 (permalink)
CTO Malus Pumila, LLC
 
Join Date: Feb 2009
Location: Michigan
Posts: 52
myemailisjustin is on a distinguished road
Default Thanks for doing this....

I'm glad you're doing this. I just did the same thing this past Sunday. (not a tutorial) but TicTacToe and it was extremely educational for myself. I'd love to see you're implementation of it. I came from basically the same background as you and this is all new, but I've been at it for a few weeks now and I'm starting to make some headway. So far, what I've seen I like yours better but I love learning this stuff so its ok to see better implementations of something you already struggled through personally - so THANKS AGAIN!
myemailisjustin is offline   Reply With Quote
Old 03-11-2009, 03:18 PM   #8 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Well thanks! I wouldn't call my way better than anyone else's though. There is a lot I still don't know. And since no one really has corrected me on anything i have done so far, I guess I am on the right track. I'll be posting another part of the tutorial soon.
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 04:34 PM   #9 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Quote:
Originally Posted by windmarble View Post
Hey that might work. I didn't think of using a switch case. Why don't you write it up and we can test it and see how well it works?
Alright. So, like I said, I'm still learning this beast that is Objective-C, so here's what I've whipped up:

- In tictactoeViewController.h, I've created a new UIImage called theImg (added inside @interface and below in @property declarations:
Code:
@interface tictactoeViewController : UIViewController {
...
	IBOutlet UIImage * theImg;
... 
}
...
@property (nonatomic,retain) UIImage *theImg;
...
Added it in the synthesize:
Code:
@synthesize oImg,xImg,theImg,whoseTurn,board;
*** don't forget to add a release in the dealloc routine:
Code:
	[theImg release];
And then I did a little "cleaning" (or so I figure) inside that touchesBegan routine:
Code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
	switch (playerToken){
		case 1:
			theImg = [UIImage imageNamed:@"X.png"];
			break;
		case 2:
			theImg = [UIImage imageNamed:@"O.png"];
			break;
	}

    UITouch *touch = [[event allTouches] anyObject];
    
    //check to see if the point that was touched is in one of the UIImage views
    if(CGRectContainsPoint([s1 frame], [touch locationInView:self.view])){s1.image = theImg;}
    if(CGRectContainsPoint([s2 frame], [touch locationInView:self.view])){s2.image = theImg;}
	if(CGRectContainsPoint([s3 frame], [touch locationInView:self.view])){s3.image = theImg;}
	if(CGRectContainsPoint([s4 frame], [touch locationInView:self.view])){s4.image = theImg;}
	if(CGRectContainsPoint([s5 frame], [touch locationInView:self.view])){s5.image = theImg;}
	if(CGRectContainsPoint([s6 frame], [touch locationInView:self.view])){s6.image = theImg;}
	if(CGRectContainsPoint([s7 frame], [touch locationInView:self.view])){s7.image = theImg;}
	if(CGRectContainsPoint([s8 frame], [touch locationInView:self.view])){s8.image = theImg;}
	if(CGRectContainsPoint([s9 frame], [touch locationInView:self.view])){s9.image = theImg;}
    [self updatePlayerInfo];
}
It's really not much yet, but I think it's just a notch cleaner. I tried to do a switch on the frame touches, but I can't figure out how to make that work: SWITCH statements only work on integers (which is why it works on the playerToken variable.

I'm going to switch gears for a second though and see if I can solve how to make this thing declare winners, losers, and cats games. Suggestions from others on the fastest / least complicated / best method for determining winner? My first guess would be something like this:

Horizontal wins
if 1=2=3 then winner
if 4=5=6 then winner
if 7=8=9 then winner
Diagonal wins
if 1=5=9 then winner
if 3=5=7 then winner
Vertical wins
if 1=4=7 then winner
if 2=5=8 then winner
if 3=6=9 then winner
Once you get a "winner" situation, then you look up which side won and declare it. This seems like a STUPID LONG way around the road. Help?

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 06:12 PM   #10 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Okay, running in to a problem.

How do I extract the name of the image from the image itself? (by name, I mean the file path, just so I can determine if it's x.png or o.png...)

I have the victory condition set up where I now know there is a winner, but I don't know how to evaluate the image that is being displayed to tell me who won...

Help?

Dave

Last edited by AEDave; 03-11-2009 at 06:13 PM. Reason: Clarified question.
AEDave is offline   Reply With Quote
Old 03-11-2009, 06:20 PM   #11 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: ¿La Islas Hermosas?
Posts: 2,176
Kalimba is on a distinguished road
Default

Quote:
Originally Posted by AEDave View Post
Okay, running in to a problem.

How do I extract the name of the image from the image itself? (by name, I mean the file path, just so I can determine if it's x.png or o.png...)

I have the victory condition set up where I now know there is a winner, but I don't know how to evaluate the image that is being displayed to tell me who won...

Help?

Dave
That's kind of a backwards approach. In the MVC paradigm, you're asking the view for information about the model, which should never be done. The model should know the state of the current game.

Looking at the current code, you can use the "playerToken" member to determine the winner.
Kalimba is offline   Reply With Quote
Old 03-11-2009, 06:31 PM   #12 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Ahh, gotcha! The last "playerToken" is the winner - since if we get a win condition, they were obviously the one to establish it.

DER! Too many years of lazy PHP coding has rotted me to the core. Thanks for chiming in Kalimba.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 06:45 PM   #13 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

I was thinking of a way to determine that too, maybe we could use an array to that gets updated with the playerToken.

For example

when playerToken is 1 and the player touches s3, well in the IF statement that deals with the s3 image we could put in an array [1][3], [1] being the player token and [3] being the slot touched.

and since we already have the logic AEDave provided

Horizontal wins
if 1=2=3 then winner
if 4=5=6 then winner
if 7=8=9 then winner
Diagonal wins
if 1=5=9 then winner
if 3=5=7 then winner
Vertical wins
if 1=4=7 then winner
if 2=5=8 then winner
if 3=6=9 then winner


then everytime we call checkForWin method we can easily do a FOR/IF loop that compares each of those 8 statements.

What do you all think?
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 06:55 PM   #14 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

AEDave I really like what you did with the switch statements! I am going to incorporate your style into the tutorial because it does help clean up the code a little. The only thing I am going to change is this:

Code:
  switch (playerToken){
            case 1:
                theImg = xImg;
                break;
            case 2:
                theImg = oImg;
                break;
        }
That way we are not instantiating a new image each time the screen is touched. That will save us some memory. But great way of thinking!
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 07:05 PM   #15 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

wind -

Yeah, I gave that a shot first, but unfortunately I was running in to an error where it wouldn't let me do that; so I put in the long, memory painful way.

Okay, so I added the following code to the (BOOL) checkForWin section:

Code:
//method that will check to see if someone has won returns TRUE if someone wins
-(BOOL) checkForWin{

	// HORIZONTAL WINS
	if((s1.image == s2.image) & (s2.image == s3.image) & (s1.image != NULL))
	{
		return YES;
	}
	if((s4.image == s5.image) & (s5.image == s6.image) & (s4.image != NULL))
	{
		return YES;
	}
	if((s7.image == s8.image) & (s8.image == s9.image) & (s7.image != NULL))
	{
		return YES;
	}
	// VERTICAL WINS
	if((s1.image == s4.image) & (s4.image == s7.image) & (s1.image != NULL))
	{
		return YES;
	}
	if((s2.image == s5.image) & (s5.image == s8.image) & (s2.image != NULL))
	{
		return YES;
	}
	if((s3.image == s6.image) & (s6.image == s9.image) & (s3.image != NULL))
	{
		return YES;
	}	
	// DIAGONAL WINS
	if((s1.image == s5.image) & (s5.image == s9.image) & (s1.image != NULL))
	{
		return YES;
	}
	if((s3.image == s5.image) & (s5.image == s7.image) & (s3.image != NULL))
	{
		return YES;
	}
	//right now return 1 becuase we havn't implemented this yet
	return NO;
}
I'll be honest; I'm a tad bit stuck - how do I access that BOOL value??? I know that's about as noob a question as can probably come. This is being called from -(void)touchesBegan... as [self checkForWin];

I'm probably calling this thing all wrong.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 07:07 PM   #16 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Just looking at the code it will ALWAYS return NO. because your last line of code is return NO

So it won't matter if the statement ever becomes true, once it finishes all the if statements it hits that last line and sets it to no.
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 07:14 PM   #17 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Right, but even if I get that fixed, how do I call this set of actions to return the BOOL so I can use it?

Obviously, the return = NO; needs to be moved up to the top of the method, I just don't know how to use what is being returned. Am I calling it wrong?

Thanks!

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 07:18 PM   #18 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

What we may end up doing is changing the checkForWin method from BOOL to (void) that way we can do more things in the checkForWin. IE Updating the label to say who won.

But yeah, to call the checkForWin method to be called you would use [self checkForWin];

But I now do not see how just returning a BOOL will help us. We need to probably just change it to (void).

Some ideas that I am kinda kicking around in my head.
Using an array to store the locations and identities of who placed what were.
That will give us some experience on working with an array.

Also when we finally settle on the proper way of creating the checkForWin, using an Alert pop up to display the winner. And "OK"ing the box will call the resetGame.

Another idea, just for shits and giggles is adding some sort of score counter, that keeps up with how many wins the X has, O has and Draw has. And storing that in an NSDictionary file that will remember the wins. Kinda like a leader board.

I usually get ahead of myself and think of other things I would like to add, well we WILL add as we progress through the tutorial. So here is a wish list of ideas for you all to think about and tinker with and see how to implement them.

Using the Accelerometer to clear the board by shaking the iPod/iPhone. and when the board is cleared the images kinda fall off the screen.

But those are just some ideas.

So do you any of you have any ideas you want to add to the wishlist? I am sure our collective knowledge can pull off anything we think of.
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 07:24 PM   #19 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Quote:
Originally Posted by AEDave View Post
Right, but even if I get that fixed, how do I call this set of actions to return the BOOL so I can use it?

Obviously, the return = NO; needs to be moved up to the top of the method, I just don't know how to use what is being returned. Am I calling it wrong?

Well right now we don't have anything to utilize that BOOL. It can return TRUE or FALSE anytime but we still don't have anything to do with it. We could have another method that calls the the checkForWin method, like a displayWinner method that calls the checkForWin. and from there we could go to do whatever it is we need to do.


Code:
-(void)displayWinner{
if([self checkForWin] == YES){
     if(playerToken==1){
         whoseTurn.text =@"X is the WINNER";
        } else {
         whoseTurn.text =@"O is the WINNER";
       }
}

}
__________________
------
I am not giving you my signature!

Last edited by windmarble; 03-11-2009 at 07:27 PM. Reason: Changed TRUE to YES for AEDave's Code
windmarble is offline   Reply With Quote
Old 03-11-2009, 07:26 PM   #20 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Our collective knowledge is confusing the hell out of me! Ha ha... No, this is actually really good, I'm glad you're walking me through this.

One thing that I just finished is a new touchesBegan method which now makes sure players can only play unfilled squares.

Code:
//this is where we will put the touch event for the tic tac toe game
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
	switch (playerToken){
		case 1:
			theImg = [UIImage imageNamed:@"X.png"];
			break;
		case 2:
			theImg = [UIImage imageNamed:@"O.png"];
			break;
	}

    UITouch *touch = [[event allTouches] anyObject];
    BOOL cellWasUsed;
	cellWasUsed = NO;
    //check to see if the point that was touched is in one of the UIImage views
    if(CGRectContainsPoint([s1 frame], [touch locationInView:self.view]) & (s1.image == NULL)){
		cellWasUsed = YES;
		s1.image = theImg;
	}
    if(CGRectContainsPoint([s2 frame], [touch locationInView:self.view]) & (s2.image == NULL)){
		cellWasUsed = YES;
		s2.image = theImg;
	}
	if(CGRectContainsPoint([s3 frame], [touch locationInView:self.view]) & (s3.image == NULL)){
		cellWasUsed = YES;
		s3.image = theImg;
	}
	if(CGRectContainsPoint([s4 frame], [touch locationInView:self.view]) & (s4.image == NULL)){
		cellWasUsed = YES;
		s4.image = theImg;
	}
	if(CGRectContainsPoint([s5 frame], [touch locationInView:self.view]) & (s5.image == NULL)){
		cellWasUsed = YES;
		s5.image = theImg;
	}
	if(CGRectContainsPoint([s6 frame], [touch locationInView:self.view]) & (s6.image == NULL)){
		cellWasUsed = YES;
		s6.image = theImg;
	}
	if(CGRectContainsPoint([s7 frame], [touch locationInView:self.view]) & (s7.image == NULL)){
		cellWasUsed = YES;
		s7.image = theImg;
	}
	if(CGRectContainsPoint([s8 frame], [touch locationInView:self.view]) & (s8.image == NULL)){
		cellWasUsed = YES;
		s8.image = theImg;
	}
	if(CGRectContainsPoint([s9 frame], [touch locationInView:self.view]) & (s9.image == NULL)){
		cellWasUsed = YES;
		s9.image = theImg;
	}
	if (cellWasUsed){
		[self updatePlayerInfo];
	}
	[self checkForWin];

    
}
The only thing left, just to get this thing humming, is to figure out how to get the value of that return on the BOOL (and yes, I'm about 10 seconds from changing it to a (void) function since I have at least a marginally better understanding of how those work) and declare a winner (I'm guessing an alert would be a nice way to wrap it up). Also need to add in one simple function for a "cats game" in the win function.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 07:42 PM   #21 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Okay, totally short-cut the cats game dilemma (no winner), board full...

Created an integer called numberOfPlays in the .h header file right underneath playerToken:
Code:
  NSInteger numberOfPlays;
Set its value in viewDidLoad (right below to player token):
Code:
...
   numberOfPlays = 0;
...
(also added that line to the resetBoard method!)

And then added a simple conditional in the updatePlayerInfo method (since, any time a player plays, an X or an O is added - we just care if we hit 9):

Code:
...
	numberOfPlays = numberOfPlays + 1;
	if(numberOfPlays == 9)
	{
		// Cats game.
		[self resetBoard];
	}
Alright, I'm going to go hit Starbucks for a quick pick me up. Back in 20.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 07:47 PM   #22 (permalink)
New Member
 
Join Date: Jan 2009
Location: Chattanooga, Tn
Posts: 65
windmarble is on a distinguished road
Default

Dont give up just yet! i think we can keep our bool method and just add a new method for doing the winning stuff.

Like this:

Here is what kinda a rough draft for the touches began method using what you just posted.

Code:
//this is where we will put the touch event for the tic tac toe game
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    

        switch (playerToken){
            case 1:
                theImg = xImg;
                break;
            case 2:
                theImg = oImg;
                break;
        }
        
        UITouch *touch = [[event allTouches] anyObject];
        
    BOOL cellWasUsed = NO;
    //check to see if the point that was touched is in one of the UIImage views
    if(CGRectContainsPoint([s1 frame], [touch locationInView:self.view]) & (s1.image == NULL)){
        cellWasUsed = YES;
        s1.image = theImg;
    }
    if(CGRectContainsPoint([s2 frame], [touch locationInView:self.view]) & (s2.image == NULL)){
        cellWasUsed = YES;
        s2.image = theImg;
    }
    if(CGRectContainsPoint([s3 frame], [touch locationInView:self.view]) & (s3.image == NULL)){
        cellWasUsed = YES;
        s3.image = theImg;
    }
    if(CGRectContainsPoint([s4 frame], [touch locationInView:self.view]) & (s4.image == NULL)){
        cellWasUsed = YES;
        s4.image = theImg;
    }
    if(CGRectContainsPoint([s5 frame], [touch locationInView:self.view]) & (s5.image == NULL)){
        cellWasUsed = YES;
        s5.image = theImg;
    }
    if(CGRectContainsPoint([s6 frame], [touch locationInView:self.view]) & (s6.image == NULL)){
        cellWasUsed = YES;
        s6.image = theImg;
    }
    if(CGRectContainsPoint([s7 frame], [touch locationInView:self.view]) & (s7.image == NULL)){
        cellWasUsed = YES;
        s7.image = theImg;
    }
    if(CGRectContainsPoint([s8 frame], [touch locationInView:self.view]) & (s8.image == NULL)){
        cellWasUsed = YES;
        s8.image = theImg;
    }
    if(CGRectContainsPoint([s9 frame], [touch locationInView:self.view]) & (s9.image == NULL)){
        cellWasUsed = YES;
        s9.image = theImg;
    }
    
    // Ill comment this in a minute
    if (cellWasUsed){
        
        if([self checkForWin] == NO){
            [self updatePlayerInfo];
        }else{
            [self displayWinner];
        }
    }//end if cell was used    

}
and the display winner method

Code:
-(void)displayWinner{
    if([self checkForWin] == YES){
        if(playerToken==1){
            whoseTurn.text =@"X is the WINNER";
        } else {
            whoseTurn.text =@"O is the WINNER";
        }
    }
    
}

Now its not 100% yet, i am still having problems with the BOOL return value. I am NSLoging everythign right now to see what is happening.
__________________
------
I am not giving you my signature!
windmarble is offline   Reply With Quote
Old 03-11-2009, 08:11 PM   #23 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Alright, I'm back. Yeah, still no clue how to return that value. Any experts lurking that might want to offer a hint?

I'm going to hack at this for a few minutes myself to see if I can come up with anything.

Dave
AEDave is offline   Reply With Quote
Old 03-11-2009, 08:19 PM   #24 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: ¿La Islas Hermosas?
Posts: 2,176
Kalimba is on a distinguished road
Default

Quote:
Originally Posted by windmarble View Post
Just looking at the code it will ALWAYS return NO. because your last line of code is return NO

So it won't matter if the statement ever becomes true, once it finishes all the if statements it hits that last line and sets it to no.
This is incorrect. Once a "return YES" statement is encountered in one of the checks, that's what will end the function. There is no "falling through" to the final "return NO" statement.
Kalimba is offline   Reply With Quote
Old 03-11-2009, 08:22 PM   #25 (permalink)
New Member
 
Join Date: Mar 2009
Location: Silicon Valley, CA
Posts: 135
AEDave is on a distinguished road
Default

Quote:
Originally Posted by Kalimba View Post
This is incorrect. Once a "return YES" statement is encountered in one of the checks, that's what will end the function. There is no "falling through" to the final "return NO" statement.
Dude you're 2 for 2 Kalimba!!! Just ran a little test, and sure enough, it works! Moving that return = NO was killing it!

Thanks!!! Time to clean up some code and let 'er run!

Dave
AEDave is offline   Reply With Quote
Reply

Bookmarks

Tags
game tutorial, tic tac toe

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: 412
9 members and 403 guests
13dario13, ChrisYates, fredidf, gmarro, 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