How to keep the turn the same

closed account (3vX4LyTq)
I have a tic tac toe game but whenever someone makes an invalid move, they lose their turn.

This is my game loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  while(o<9) {
  play(t, turn);
  board(t);
  if (checkwin(t)){
    break;
  }
  if(turn=='x'){
    cout << "\nPlayer 2:\t";
    turn='o';
  }
  else{
    cout << "\nPlayer 1:\t";
    turn='x';
  }

  o++;

}
if(o==9){
cout << "It's been nine turns! Game over.";
}

And here is the play function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void play(char t[], char turn){
  //decides where to put the "x" or "o"
  int pos;
  cin >> pos;
  if(t[pos-1] =='x' || t[pos-1]=='o'){/// I have to subtract one because t[0] = 1 and t[8] = 9
    cout << "\nThat space was taken!\n";
    return;
  }
  if(pos<=0 || pos>9){
    cout << "\nInvalid number!\n";
    return;
  }
  t[pos-1]=turn;
}


I just want to make it so they don't lose their turn (i.e if o chooses an invalid place, turn goes to x.)
Last edited on
Change play() to a bool function. Have it return false if a move could not be made and true if the move was made. Then change line 3 of your game loop to:
1
2
3
 
  if (! play(t, turn))
    continue;  //  Return to top of loop 



closed account (3vX4LyTq)
This works, but it still changes from x to o. So basically if you are o, and you choose an invalid place, then turn changes to x. Did I do something wrong?

Here's what I did
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
while(o<9) {
  play(t, turn);
  board(t);
  if (! play(t, turn))
    continue;
    
  if (checkwin(t)){
    break;
  }
  if(turn=='x'){
    cout << "\nPlayer 2:\t";
    turn='o';
  }
  else{
    cout << "\nPlayer 1:\t";
    turn='x';
  }

  o++;

}
if(o==9){
cout << "It's been nine turns! Game over.";
}

And to my play() function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool play(char t[], char turn){
  //decides where to put the "x" or "o"
  int pos;
  cin >> pos;
  if(t[pos-1] =='x' || t[pos-1]=='o'){/// I have to subtract one because t[0] = 1 and t[8] = 9
    cout << "\nThat space was taken!\n";
    return false;
  }
  if(pos<=0 || pos>9){
    cout << "\nInvalid number!\n";
    return false;
  }
  t[pos-1]=turn;
  return true;
}


Just in case you want to run the whole thing:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include<iostream>

using namespace std;

bool checkwin(char t[]);
void board(char t[]);
bool play(char t[], char turn);

int main(){
char t[]={'1','2','3','4','5','6','7','8','9'}, turn='x';
int x = 0;
int o = 0;
cout << "Welcome to Tic Tac Toe! Game is over after 9 moves. Press enter to start\n";
cin.ignore();///makes you press enter
cout << "Player one goes first! You are X! Choose a space\n";
board(t);

while(o<9) {
  play(t, turn);
  board(t);
  if (! play(t, turn))
    continue;

  if (checkwin(t)){
    break;
  }
  if(turn=='x'){
    cout << "\nPlayer 2:\t";
    turn='o';
  }
  else if (turn =='o'){
    cout << "\nPlayer 1:\t";
    turn='x';
  }

  o++;

}
if(o==9){
cout << "It's been nine turns! Game over.";
}
}


//FUNCTIONS
void board(char t[]){

  ///prints and updates the board
  cout << t[0] << " | " << t[1] << " | " << t[2] << "\n";
  cout << "----------" << endl;
  cout << t[3] << " | " << t[4] << " | " << t[5] << "\n";
  cout << "----------" << endl;
  cout << t[6] << " | " << t[7] << " | " << t[8] << "\n";
}

bool play(char t[], char turn){
  //decides where to put the "x" or "o"
  int pos;
  cin >> pos;
  if(t[pos-1] =='x' || t[pos-1]=='o'){/// I have to subtract one because t[0] = 1 and t[8] = 9
    cout << "\nThat space was taken!\n";
    return false;
  }
  if(pos<=0 || pos>9){
    cout << "\nInvalid number!\n";
    return false;
  }
  t[pos-1]=turn;
  return true;
}
bool checkwin(char t[]) {
    ///X win condition
    if(t[0] == 'x' && t[1] == 'x' && t[2] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    else if(t[2] == 'x' && t[5] == 'x' && t[8] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    else if(t[0] == 'x' && t[3] == 'x' && t[6] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    else if(t[6] == 'x' && t[7] == 'x' && t[8] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    else if(t[0] == 'x' && t[4] == 'x' && t[8] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    else if(t[6] == 'x' && t[4] == 'x' && t[2] =='x'){
        cout << "\n X wins! GG! \n";
        return true;
    }
    /// o win condition
    else if(t[0] == 'o' && t[1] == 'o' && t[2] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }
    else if(t[2] == 'o' && t[5] == 'o' && t[8] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }
    else if(t[0] == 'o' && t[3] == 'o' && t[6] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }
    else if(t[6] == 'o' && t[7] == 'o' && t[8] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }
    else if(t[0] == 'o' && t[4] == 'o' && t[8] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }
    else if(t[6] == 'o' && t[4] == 'o' && t[2] =='o'){
        cout << "\n O wins! GG! \n";
        return true;
    }


    return false;
}
Last edited on
Line 19,21: You're calling play twice. Remove line 19.

Lines 71-125: You're still missing winning combinations. There are 8 winning combinations for each player (3 rows, 3 cols, 2 diagonals). You only have 6 combinations.

As I mentioned before, checkwin() can be shortened considerably by only checking for one player's win at a time.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//  Works for either player
bool checkwin(char t[], char turn) 
{   //  Row 0
    if(t[0] == turn && t[1] == turn && t[2] == turn)
        return true;
    //  Row 1 
    if(t[3] == turn && t[4] == turn && t[5] == turn)
        return true;
    //  Row 2
    if(t[6] == turn && t[7] == turn && t[8] == turn)
        return true;    
    //  Col 0            
    if (t[0] == turn && t[3] == turn && t[6] == turn)
        return true;
    //  Col 1
    if (t[1] == turn && t[4] == turn && t[7] == turn)
        return true;
    //  Col 2
    if (t[2] == turn && t[5] == turn && t[8] == turn)
        return true;
    //  Diag L-R
    if (t[0] == turn && t[4] == turn && t[8] == turn)
        return true;
    //  Diag R-L 
    if (t[2] == turn && t[4] == turn && t[6] == turn)
        return true;
    //  None of the above        
    return false;
}



To avoid crashing the program, play() should check the value of pos before checking t[pos-1]. Otherwise what happens if they enter 150000000 for pos?

Another option is to leave main() as is and put a while look inside play()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void
play(char t[], char turn)
{
    //decides where to put the "x" or "o"
    int pos;
    while (true) {
        cin >> pos;
        --pos;                  // change pos from 1-9 to 0-8
        if (pos < 0 || pos > 8) {
            cout << "\nInvalid number!\n";
            continue;
        }

        if (t[pos] == 'x' || t[pos] == 'o') {   /// I have to subtract one beca\
use t[0] = 1 and t[8] = 9
            cout << "\nThat space was taken!\n";
            continue;
        }
        break;
    }
    t[pos] = turn;
}

Topic archived. No new replies allowed.