Program changing variables while after I've initialized them?

Discussion in 'iOS Programming' started by kierster, Dec 20, 2008.

  1. macrumors newbie

    Joined:
    Dec 20, 2008
    #1
    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.
     
  2. macrumors 65816

    italiano40

    Joined:
    Oct 7, 2007
    Location:
    NY
    #2
    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
     
  3. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #3
    Here's my ViewController header file.
    Code:
    //
    //  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
    
    
    
     
  4. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #4
    And now the implementation of the ViewController.
    Code:
    //
    //  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
    
    
     
  5. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #5
    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:
     
  6. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    Where in your appDelegate are you calling initializeProgram?
     
  7. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #7
    Right here in the implementation.
    Code:
    - (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.
     
  8. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #8
    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
     
  9. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #9
    Hmm, maybe try setting a breakpoint (in initializeGame) and stepping through and seeing what the code is doing.

    EDIT: Ah, got it! (I think)

    Code:
    	for (i=1; i<=9; i++) {
    		buttons[i] = 0;
    	}
    
    should be:
    Code:
    	for (i=0; i<9; i++) {
    		buttons[i] = 0;
    	}
    
    Arrays are zero-indexed in C / Obj-C, meaning they start at 0.
     
  10. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #10
    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:
     
  11. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
  12. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #12
    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
     
  13. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #13
    I've just updated the code to exactly what I have now.
     
  14. thread starter macrumors newbie

    Joined:
    Dec 20, 2008
    #14
    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
     

Share This Page