Hi everyone

I am trying to write a program that will allow to people to play tic tac toe. My constraints are that this must be accomplished mainly through the use of functions and that the default cell field for the displayed game board must be stars.

I am having difficulty with my getplayer() and winner() functions not working as I had expected. The program compiles with no errors, but does not register any change in the player, and, therefore, does not correctly alternate between X and O characters. It continues to fill the cells, but it will only use X's. Finally, even when the victory conditions are met (as specified in the win() function), the program continues to loop.

These issues are inexplicable to me, but I feel that it must be something blatantly obvious, since I am so new to C++. I am sorry if I seem dense.

#include <iostream>
#include <cmath>
#include <iomanip>
#include <string>


using namespace std;

int player=0;

void display(char [][3]);
char arraytest[3][3] = {{'*','*','*'}, {'*','*','*'}, {'*','*','*'}};
void win(char [][3], int &);
void move(char [][3], int);
void getplayer(int &);

int main() {

    int winner;
    do {
    
    display(arraytest);
    getplayer(player);
    move(arraytest, player);
    win(arraytest, winner);

    }//end of do statement
    while(winner != 1);
    cout << "Player has won the game!!" << endl;
    return 0;
}

void display(char board[][3]) {
    for (int i=0;i<3;i++) {
        for(int j=0;j<3;j++) {
            cout << board[i][j];
            cout << "  ";
        }
        cout << endl;
        if(i!=2) {
            cout << "-------------------------" << endl;
        }
    }
}

void win(char board[][3], int &winner) {

    int n;
    for(n=0;n<3;n++) {
        if(board[n][0]==board[n][1] && board[n][0]==board[n][2]) {
            if(board[n][0]=='O' || board[n][0]=='X') {
                winner=1;
            }
        }
    }
    for(n=0;n<3;n++) {
        if(board[0][n]==board[1][n]&&board[0][n]==board[2][n]) {
            if(board[0][n]=='O' || board[0][n]=='X') {
                winner=1;
            }
        }
    }
    if(board[0][0]==board[1][1]&&board[0][0]==board[2][2]) {
        if(board[0][0]=='O' || board[0][0]=='X') {
            winner=1;
        }
    }
    if(board[0][2]==board[1][1]&&board[1][1]==board[2][2]) {

        if(board[0][2]=='O' || board[0][2]=='X') {
            winner=1;
        }
    }
    else {
        winner=0;
    }
}

void move(char board[][3], int player) {
    int x,y, input;
    cout << "Please enter the row number for the place you wish to mark: " << endl;
    cin >> x;
    cout << "Please enter the column number for the place you wish to mark" << endl;
    cin >> y;

    if(player == 1) {
        board[x][y]='X';
    }
    else {
        board[x][y]='O';
    }

}

void getplayer(int &previous) {
    //previous will be the number of the previous player
    switch(previous) {

    case 0: if(previous == 0) {
        previous = 1;
    }

    case 1: if(previous == 1) {
        previous++;
    }

    case 2: if(previous==2) {
        previous--;
        }
    }
}

Any input on this would be greatly appreciated.

It seems to me that making a function call to determine who the current player is in a game of tic-tac-toe is overkill. It is safe to assume that there will always be two players. It is also safe to assume that if player 1 went, then it will be player 2's turn and vice-versa.

However, if ye' wish to make a function call to determine the current state of playerness, try making a function that will return the current player:

bool getplayer()
{
     return is_player_1;
}

It is likely that your win() function is being adversly affected by the incorrect drawing of X's and O's to the game board (board[][]). Upon cleanup of your getplayer() function I believe you will see better results.

I think see the problem with your player switching. when it reaches 2, it will just subtract 1. So zero is O and 1 is X, then when you reach 2, instead of going back down to zero, you go to 1, so O will have one turn, then it will be X's turn forever. Simply make it so that when previous = 2, set it to zero. that should fix it! :D

What do you do now to change from player 0 to player 1? I see no attempt to switch.

All your winner function does is look for a winner. It doesn't return who the winner is. If that's enough, OK. Otherwise, you might want to think about it a little more. Also, if your first loop finds a winner is it necessary to go through all the other loops?

Change the getPlayer function...your version is overdone and redundant. Try this one liner

previous = 1 - previous;

The above will toggle between 0 and 1 until you get a winner. But, I see that also needs to be fixed....I will reply to that in a minute or two...

I have tried to remove my getplayer function and added a switch statement inside of the do loop after the function calls:

player=1;

int main() {

    int winner;
    do {


    display(arraytest);
    //getplayer(player);
    move(arraytest, player);
    win(arraytest, winner);

    switch(player) {
        case 1: player++;
        case 2: player--;
    }


    }//end of do statement
    while(winner != 1);
    cout << "Player has won the game!!" << endl;
    return 0;
}

However, my problems persist. I'll admit to being fairly clueless at this point. When I go over the code, it seems to me that it should run. The only thing that I can think of is player being outside the scope of the move() function, but this is not possible, since it is a global variable.

OK, I see the function.

If you want to return the player, why is it a void function? Let it return the player:

int getplayer(int thisplayer) 
{
    if (thisplayer == 0) 
    {
        thisplayer = 1;
    }
    else
    {
        thisplayer = 0;
    }
    return thisplayer;
}

Now you have either player 0 or player 1.

i apologize for posting without checking for further replies. I have followed Lafigueroa's advice and the program now does correctly alternate between Xs and Os. The only issue now is with the win() function not functioning correctly. Thanks!

I see a couple of problems with the winner function
1. remove the last else.
2. initialize the (before any of the for loops)
winner = 0; // assume the game contines
3. the last if statement checking for a win down the last diagonal (0,2), (1,1) and (2,0)....needs to be cleaned up

oh...and by the way....you should probably check that someone has not selected an already selected grid....

Thanks guys! You have helped me immeasurably.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.