PDA

View Full Version : Program changing variables while after I've initialized them?




kierster
Dec 20, 2008, 12:44 PM
Hi I know this sounds weird but I made a function that initializes many of my program variables.
I'm new to Objective-C and iPhone programming and am just trying to make a simple Tic-Tac-Toe game. I have experience in C and Visual Basic, but I'm finding this language confusing :confused:. Help is very much appreciated!! I'll post my code if you need it.
Thanks for helping the newb :D.



italiano40
Dec 20, 2008, 12:47 PM
can post the code, because i am getting confused by your wording
but i think it is a simple of writing the wrong code in the function, but i would need to see this code to be 100% correct

kierster
Dec 20, 2008, 12:48 PM
Here's my ViewController header file.

//
// TouchTacToeViewController.h
// TouchTacToe
//

#import <UIKit/UIKit.h>

@interface TouchTacToeViewController : UIViewController {
IBOutlet UIButton *button1;
IBOutlet UIButton *button2;
IBOutlet UIButton *button3;
IBOutlet UIButton *button4;
IBOutlet UIButton *button5;
IBOutlet UIButton *button6;
IBOutlet UIButton *button7;
IBOutlet UIButton *button8;
IBOutlet UIButton *button9;
IBOutlet UIButton *newGameButton;
IBOutlet UILabel *displayLabel;

//Variables
@public
int buttons[9];
bool player1Turn, player2Turn;
bool player1IsComp, player2IsComp, buttonsClickable;
}

@property(nonatomic, retain) IBOutlet UIButton *button1, *button2, *button3, *button4, *button5, *button6, *button7, *button8, *button9;
@property(nonatomic, retain) IBOutlet UIButton *newGameButton;
@property(nonatomic, retain) IBOutlet UILabel *displayLabel;

- (void) initializeProgram;
- (void) initializeGame;
- (void) initializeTurn;
- (void) endTurn;
- (void) updateGameBoard;
- (IBAction) buttonClick:(id) sender;
- (IBAction) newGame:(id) sender;
- (void) setTicTacToeBox:(int)number state:(NSString *)state;
- (void) doComputerTurn;
- (int) isWin;

@end

kierster
Dec 20, 2008, 12:50 PM
And now the implementation of the ViewController.

//
// TouchTacToeViewController.m
// TouchTacToe
//

#import "TouchTacToeViewController.h"
#import "TouchTacToeAppDelegate.h"

@implementation TouchTacToeViewController

@synthesize button1, button2, button3, button4, button5, button6, button7, button8, button9, newGameButton, displayLabel;

//Game loop functions

//Initialize the program
- (void)initializeProgram {
player1Turn = true;
player2Turn = false;
player1IsComp = false;
player2IsComp = true;
buttonsClickable = false;

[self initializeGame];
}

//Initialize the game
- (void)initializeGame {
//Initialize Game
int i = 0;
for (i=0; i<9; i++) {
buttons[i] = 0;
}

player1Turn = true;
player2Turn = false;

[self updateGameBoard];
[self initializeTurn];
}

//Initialize the turn
- (void)initializeTurn {

if (player1Turn) {
//Player 1's Turn? (X)
[displayLabel setText:[NSString stringWithFormat:@"X's turn"]];
if (player1IsComp) {
//Computer
buttonsClickable = false;
[self doComputerTurn];
}
else {
//Human
buttonsClickable = true;
}
}
else if (player2Turn) {
//Player 2's Turn? (O)
[displayLabel setText:[NSString stringWithFormat:@"X's turn"]];
if (player2IsComp) {
//Computer
buttonsClickable = false;
[self doComputerTurn];
}
else {
//Human
buttonsClickable = true;
}
}
}

//End the turn
- (void)endTurn {
int winner = [self isWin];
//we have a winner!
if (winner == 1) {
[displayLabel setText:[NSString stringWithFormat:@"X wins!"]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Good Job" message:@"Press new game to play again!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
[alert release];
buttonsClickable = false;
}
if (winner == 2) {
[displayLabel setText:[NSString stringWithFormat:@"O wins!"]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Good Job" message:@"Press new game to play again!" delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
[alert release];
buttonsClickable = false;
}
if (winner == 0) {
//next player's turn!
if (player1Turn) {
player2Turn = true;
player1Turn = false;
}
else if (player2Turn) {
player1Turn = true;
player2Turn = false;
}
[self initializeTurn];
}
}

//Update the buttons to match data stored by the computer
- (void)updateGameBoard {
int i = 0;
for (i=0; i<9; i++) {
if (buttons[i] == 0) {
[self setTicTacToeBox:i state:@"blank"];
}
else if (buttons[i] == 1) {
[self setTicTacToeBox:i state:@"X"];
}
else if (buttons[i] == 2) {
[self setTicTacToeBox:i state:@"O"];
}
else {
buttons[i] = 0;
[self setTicTacToeBox:i state:@"blank"];
}
}
}

-(IBAction) newGame:(id) sender {
[self initializeGame];
}

-(IBAction) buttonClick:(id) sender {
NSString *title = [sender currentTitle];
int buttonNumber = title.intValue-1;

//is this person human?
if (buttonsClickable) {
//[displayLabel setText:[NSString stringWithFormat:@"You need to click on a blank!"]];
//if button is blank
if (buttons[buttonNumber] == 0) {
//set it to X
//[displayLabel setText:[NSString stringWithFormat:@"Button %d was pressed!", buttonNumber]];

if (player1Turn) {
[self setTicTacToeBox:buttonNumber state:@"X"];
}
else if (player2Turn) {
[self setTicTacToeBox:buttonNumber state:@"O"];
}

[self endTurn];
}
}
}
- (void)setTicTacToeBox:(int)number state:(NSString *)state {

//find img
UIImage *img;
if ([state isEqualToString:@"blank"]) {
img = [UIImage imageNamed:@"blank.png"];
buttons[number] = 0;
}
else if ([state isEqualToString:@"X"]) {
img = [UIImage imageNamed:@"X.png"];
buttons[number] = 1;
}
else if ([state isEqualToString:@"O"]) {
img = [UIImage imageNamed:@"O.png"];
buttons[number] = 2;
}

if (number == 0) {
[button1 setImage:img forState:UIControlStateNormal];
}
else if (number == 1) {
[button2 setImage:img forState:UIControlStateNormal];
}
else if (number == 2) {
[button3 setImage:img forState:UIControlStateNormal];
}
else if (number == 3) {
[button4 setImage:img forState:UIControlStateNormal];
}
else if (number == 4) {
[button5 setImage:img forState:UIControlStateNormal];
}
else if (number == 5) {
[button6 setImage:img forState:UIControlStateNormal];
}
else if (number == 6) {
[button7 setImage:img forState:UIControlStateNormal];
}
else if (number == 7) {
[button8 setImage:img forState:UIControlStateNormal];
}
else if (number == 8) {
[button9 setImage:img forState:UIControlStateNormal];
}
}


- (void)doComputerTurn {

//EASY STRATEGY
int random = 0;
bool foundBlank = false;

//test if board is full
for (random=0; random<9; random++) {
if (buttons[random] == 0) {
foundBlank = true;
}
}

if (foundBlank == true) {
foundBlank = false;
//randomly pick an empty spot
while (foundBlank == false) {
random = arc4random() % 10;
//generate random number between 1 and 9
if (buttons[random] == 0 && random >= 0 && random < 9) {
if (player1Turn) {
[self setTicTacToeBox:random state:@"X"];
}
else if (player2Turn) {
[self setTicTacToeBox:random state:@"O"];
}
foundBlank = true;
break;
}
}
}
return;
}

- (int)isWin {
int winner = 0;
//win conditions
//HORIZONTAL
if (buttons[0] == buttons[1] && buttons[1] == buttons[2] && buttons[0] > 0 ) {
winner = buttons[0];
}
if (buttons[3] == buttons[4] && buttons[4] == buttons[5] && buttons[3] > 0 ) {
winner = buttons[3];
}
if (buttons[6] == buttons[7] && buttons[7] == buttons[8] && buttons[6] > 0 ) {
winner = buttons[6];
}
//VERTICAL
if (buttons[0] == buttons[3] && buttons[3] == buttons[6] && buttons[0] > 0 ) {
winner = buttons[0];
}
if (buttons[1] == buttons[4] && buttons[4] == buttons[7] && buttons[1] > 0 ) {
winner = buttons[1];
}
if (buttons[2] == buttons[5] && buttons[5] == buttons[8] && buttons[2] > 0 ) {
winner = buttons[2];
}
//DIAGONAL
if (buttons[0] == buttons[4] && buttons[4] == buttons[8] && buttons[0] > 0 ) {
winner = buttons[0];
}
if (buttons[2] == buttons[4] && buttons[4] == buttons[6] && buttons[2] > 0 ) {
winner = buttons[2];
}

return winner;
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/



// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}



/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/


- (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 {
[button1 dealloc];
[button2 dealloc];
[button3 dealloc];
[button4 dealloc];
[button5 dealloc];
[button6 dealloc];
[button7 dealloc];
[button8 dealloc];
[button9 dealloc];
[newGameButton dealloc];
[displayLabel dealloc];
[super dealloc];
}

@end

kierster
Dec 20, 2008, 12:53 PM
Maybe I'm just approaching the language wrong because of being used to Visual Basic, but here's what happens.
When I run the program for some reason the button in the bottom right corner(button[9]) will always have an X(1), even if i initialize it to a blank(0).
It's almost like the program re-initializes it on it's own :confused:. And the player1Turn and player1IsComp boolean variables don't seem to hold their initialization either :confused:
In my appDelegate I call initializeProgram to set it to player 1's turn and make the 2nd player a computer and clear the board, but still all the booleans values remain false and the board only gets partially cleared.
And if you need to know, when a player touches/clicks a button buttonClick gets called.
Thanks for your time! :cool:

dejo
Dec 20, 2008, 01:05 PM
Where in your appDelegate are you calling initializeProgram?

kierster
Dec 20, 2008, 01:08 PM
Right here in the implementation.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];

[viewController initializeProgram];
}

Like I said I come from a Visual Basic background so perhaps I'm not declaring the variables in the right location? or? Thanks for the help.

kierster
Dec 20, 2008, 01:36 PM
yea this problem is very confusing and frustrating :confused: something so simple as setting a variable should work lol. Do any of you have code for a simple tic-tac-toe game or something simple? I have an idea for a game that will go on the app store eventually and having a game like tic-tac-toe under my belt would be a great start to getting on my way :rolleyes:. :D

dejo
Dec 20, 2008, 01:37 PM
Hmm, maybe try setting a breakpoint (in initializeGame) and stepping through and seeing what the code is doing.

EDIT: Ah, got it! (I think)

for (i=1; i<=9; i++) {
buttons[i] = 0;
}


should be:
for (i=0; i<9; i++) {
buttons[i] = 0;
}


Arrays are zero-indexed in C / Obj-C, meaning they start at 0.

kierster
Dec 20, 2008, 01:45 PM
ok put a break point inside initializeGame and found something very weird.
I store the game board in an int array(buttons[9]) and for some reason, when i move my mouse onto it in the debugger it says that buttons[] only goes up to 8!(buttons[1] to buttons[8] get set to blank but buttons[9] doesn't even exist! :confused:

kierster
Dec 20, 2008, 01:46 PM
OK! thank you! I'll try it!

kierster
Dec 20, 2008, 01:55 PM
I changed all my code to use spaces 0-8 in the buttons[] array, but I'm still having problems :confused: some buttons will not press while others will :confused: oh and the 9th button in the bottom right corner is still initialized to an X although i specificially set it to blank :s

kierster
Dec 20, 2008, 02:03 PM
I've just updated the code to exactly what I have now.

kierster
Dec 20, 2008, 02:13 PM
ok changing everything in my program to use only slots 0-8 in the array fixed my initializing problem! Thank you! and I just noticed my other problem, I forgot to call endTurn at the end of the doComputerTurn function.. But now that this is solved my game works! thanks everyone :D