8 Replies - 3039 Views - Last Post: 14 July 2012 - 08:06 AM Rate Topic: -----

#1 handres  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 13-July 12

Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 06:55 PM

I am making a tic tac toe game in which I want to check whether 3 in a row has been achieved or not.
For some reason, inside of my checkWin function, when I do my switch statement, the program never goes into the cases. I've run this program with debugging multiple times and the char values ARE equal. Can someone explain to me why the program does not go into the case statement? Help would be appreciated. I type casted the chars to ints to see if they had the same int value and they are equal. BTW I am very new to C++ so if I'm making a stupid mistake I apologize.

Global Variables:

char Board[3][3] = {{'1','2','3'},
                    {'4','5','6'},
                    {'7','8','9'}};
string Message;
string Winner;
Comp *AI;



Where I manipulate Board:
void takeMove(char c){
	char index;
    if(c=='X'){
		string input;
		cin >> input;
		index = input[0]; // This is so that if the user enters more than 1 character there are no errors
    }
    else{
        index = AI->decide();
    }
    if(index!='X' && index!='O'){
        for(int x=0;x<3;x++){
            for(int y=0;y<3;y++){
                if(index==Board[x][y]){
                    Board[x][y] = c;
                }
            }
        }
    }
}



Where the problem is:

bool checkWin(){
    int x1 = 0;
    int o1 = 0;
    int x2 = 0;
    int o2 = 0;
    int x3 = 0;
    int o3 = 0;
    int x4 = 0;
    int o4 = 0;
    for(int x=0;x<3;x++){ // check columns
		int x1 = 0;
		int o1 = 0;
        for(int y=0;y<3;y++){
            switch(Board[x][y]){ // <-- PROBLEM Board is equal to 'X', but does not go into case statement
                case 'X':
                    x1++;
                    break;
                case 'O':
                    o1++;
                    break;
                default:
                    break;
            }
        }
        switch(Board[x][x]){ // Checking Diagonal
            case 'X':
                x3++;
                break;
            case 'O':
                o3++;
                break;
            default:
                break;
        }
        switch(Board[0+x][2-x]){ // Check Diagonal/ What's weird is that this switch statement does go into the cases?
            case 'X':
                x4++;
                break;
            case 'O':
                o4++;
                break;
            default:
                break;
        }
    }
	for(int x=0;x<3;x++){ // <-- PROBLEM Board is equal to 'X', but does not go into case statement
		int x2=0;
		int o2=0;
		for(int y=0;y<3;y++){
			 switch(Board[y][x]){ // check rows
                case 'X':
                    x2++;
                    break;
                case 'O':
                    o2++;
                    break;
                default:
                    break;
            }
		}
	}
    if(x1>=2){
        Winner = "X";
        return true;
    }
    else if(o1>=3){
        Winner = "O";
        return true;
    }
    else if(x2>=3){
        Winner = "X";
        return true;
    }
    else if(o2>=3){
        Winner = "O";
        return true;
    }
    else if(x3>=3){
        Winner = "X";
        return true;
    }
    else if(o3>=3){
        Winner = "O";
        return true;
    }
    else if(x4>=3){
        Winner = "X";
        return true;
    }
    else if(o4>=3){
        Winner = "O";
        return true;
    }
	int count=0;
	for(int x=0;x<3;x++){
		for(int y=0;y<3;y++){
			if(Board[x][y]=='X' || Board[x][y]=='O'){
				count++;
			}
		}
	}
	if(count>=9){
		Winner = "NO ONE";
		return true;
	}
    return false;
}



Main:

int main(){
    AI = new Comp();
    string s;
    int games=0;
    int moves=0;
    cout << "Welcome to Tic Tac Toe by Hunter Vallejos!" << endl;
    cout << "Type the number of the space you want to choose"<< endl;
    do {
        cout << "WARNING: This AI never loses.  You will only be able to tie this AI" << endl;
        system("PAUSE");
        Message = " Type the number you want to choose and press enter. You are X and the AI is O";
        do {
			DisplayBoard();
			switch(moves % 2){
				case 0:
					takeMove('X');
					break;
				case 1:
					AI->setBoard(Board);
					takeMove('O');
					break;
			}
			moves++;
        } while(!checkWin());
        DisplayBoard();
        cout << endl << "\t\t\t\tThe winner is " << Winner << endl;
    } while(checkRepeat());
    return 0;
}



Is This A Good Question/Topic? 0
  • +

Replies To: Why is the program acting as if 'X' is not equal to 'X

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3650
  • View blog
  • Posts: 11,419
  • Joined: 05-May 12

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 07:56 PM

What compiler are you using? What debugger? Are you compiling with optimizations turned on?
Was This Post Helpful? 0
  • +
  • -

#3 jimblumberg  Icon User is offline

  • member icon


Reputation: 4232
  • View blog
  • Posts: 13,281
  • Joined: 25-December 09

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 08:02 PM

My first suggestion would be to eliminate your global variables and pass the required variables into your functions.

Next you have several problems in your checkWin() function:

Quote

main.cpp||In function ‘bool checkWin()’:|
main.cpp|24|warning: declaration of ‘x1’ shadows a previous local [-Wshadow]|
main.cpp|15|warning: shadowed declaration is here [-Wshadow]|
main.cpp|25|warning: declaration of ‘o1’ shadows a previous local [-Wshadow]|
main.cpp|16|warning: shadowed declaration is here [-Wshadow]|
main.cpp|63|warning: declaration of ‘x2’ shadows a previous local [-Wshadow]|
main.cpp|17|warning: shadowed declaration is here [-Wshadow]|
main.cpp|64|warning: declaration of ‘o2’ shadows a previous local [-Wshadow]|
main.cpp|18|warning: shadowed declaration is here [-Wshadow]|

What this means is that you have defined a variable with the same name twice. The first instance is being hidden by the second instance.

Quote

For some reason, inside of my checkWin function, when I do my switch statement, the program never goes into the cases.

When I tested the function by assigning 'X' to every element in your board array, the case statements are executed. The first case is executed 3 times followed by the second case being executed once followed by the third case being executed once. This is repeated three times.

Jim
Was This Post Helpful? 2
  • +
  • -

#4 snoopy11  Icon User is offline

  • Engineering ● Software
  • member icon

Reputation: 836
  • View blog
  • Posts: 2,459
  • Joined: 20-March 10

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 08:02 PM

View PostSkydiver, on 14 July 2012 - 02:56 AM, said:

What compiler are you using? What debugger? Are you compiling with optimizations turned on?


Dude,

You're like a machine ... do you ever sleep ?
Anyway it's 4:00 am here see #define is still up too...

I'm away back to bed...

Have fun

Snoopy.
Was This Post Helpful? 0
  • +
  • -

#5 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1396
  • View blog
  • Posts: 4,872
  • Joined: 19-February 09

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 08:03 PM

It appears you reset x1 and o1 at the start of every row, so only the last row would register.

010	    for(int x=0;x<3;x++){ // check columns
011	        int x1 = 0;
012	        int o1 = 0;




The function could maybe simpler with some sub-functions such as checking a row.
Was This Post Helpful? 1
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3650
  • View blog
  • Posts: 11,419
  • Joined: 05-May 12

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 13 July 2012 - 08:07 PM

View Postsnoopy11, on 13 July 2012 - 08:02 PM, said:

View PostSkydiver, on 14 July 2012 - 02:56 AM, said:

What compiler are you using? What debugger? Are you compiling with optimizations turned on?


Dude,

You're like a machine ... do you ever sleep ?
Anyway it's 4:00 am here see #define is still up too...

I'm away back to bed...

Have fun

Snoopy.


Only 20:00 over here. But I really should be thinking about dinner instead of trying to get MPIR's C++ wrapper to work with streams...

View Post#define, on 13 July 2012 - 08:03 PM, said:

It appears you reset x1 and o1 at the start of every row, so only the last row would register.

010	    for(int x=0;x<3;x++){ // check columns
011	        int x1 = 0;
012	        int o1 = 0;




The function could maybe simpler with some sub-functions such as checking a row.


Or even better write the code once where you pass in 'X' or 'O' and let it determine if there is a win condition for that symbol. That way there is no need for switch statements at the counting level.
Was This Post Helpful? 1
  • +
  • -

#7 handres  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 13-July 12

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 14 July 2012 - 07:29 AM

Thank you so much for your replies! I will make functions to test one row or one column. Also, I am using Code blocks compiler.
I did not realize that once the program checked the first two rows/columns only the data from the last row/column would be tested.
I will eliminate my global variables.
One question: Why is it better to not have global variables and pass each function the same information over and over?
Does it have to do with switching to a different place in memory or is it better organized?
I appreciate all suggestions.
Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is offline

  • member icon


Reputation: 4232
  • View blog
  • Posts: 13,281
  • Joined: 25-December 09

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 14 July 2012 - 07:56 AM

As your program grow in size you will find using global variables will make following the program logic and troubleshooting much more difficult. When using small functions that are passed all the necessary information you will also be able to separately test each function to insure proper operation of that function.

Jim

This post has been edited by jimblumberg: 14 July 2012 - 07:56 AM

Was This Post Helpful? 1
  • +
  • -

#9 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3650
  • View blog
  • Posts: 11,419
  • Joined: 05-May 12

Re: Why is the program acting as if 'X' is not equal to 'X

Posted 14 July 2012 - 08:06 AM

If those globals happen to be classes with code in their constructors, figuring out which one runs first gets to be an exercise in frustration.

Additionally, once you start writing code with multiple threads, you'll have to write extra code to protect your globals to make sure only one thread is updating them at a time. Often times this protection code uses a global critical section or mutex. Now instead of dealing with N globals, now you have to deal with N+1 globals. And the question comes up: who deals with protecting the critical section or mutex when they are being initialized or shutdown?

If you can avoid the issue completely by not declaring a global, do so.

This post has been edited by Skydiver: 14 July 2012 - 08:12 AM

Was This Post Helpful? 1
  • +
  • -

Page 1 of 1