Hello,
i´m trying to make the tic tac toe game in c++, but i´m stuck to check if player 1 or 2 wins or is draw.
I cant figured out how to check the rows, colums and diagonals to check if player 1 or 2 wins.

If the game have a static array is easy because we can define all the positions that lead to win, but this array is dynamic.
Anybody can help me with this.
I leave here my code for appreciation.
Regards to all.

#include <iostream>#include<stdio.h>#include<conio.h>using namespace std;void regras (){ cout<<"************************"<<endl; cout<<"***** Jogo do Galo *****"<<endl; cout<<"************************"<<endl; cout<<endl; cout<<endl; cout<<"Para jogar carregue no numero correspondente"<<endl; cout<<"à posição que quer marcar a sua opção."<<endl; cout<<endl; cout<<endl; cout<<"O jogador 1 marca com X."<<endl; cout<<"O jogador 2 marca com O."<<endl; cout<<"\tBom jogo."<<endl; cout<<endl; cout<<endl;}class Cria_Matriz1{ int n,m; int **matrix;public: Cria_Matriz1(int parametro_n) : n(parametro_n) { m=n; matrix= new int*[n]; int c=1; for (int i = 0; i<n; ++i) { for (int j=0; j<n; ++j) { matrix[i]= new int [m]; matrix[i][j]=c; c++; cout <<"["<<matrix[i][j]<<"]"<<" "; } cout << endl; //cout << endl; } } ~Cria_Matriz1() { delete [] matrix; }};class Cria_Matriz //comentar{ int n,m; char **matriz; char jogador1; char jogador2;public: Cria_Matriz(int parametro_n) : n(parametro_n) ,jogador2('O') ,jogador1('X') { m=n; matriz= new char*[n]; for (int i=0; i<n;++i) { matriz[i]= new char [m]; for (int j=0; j<m; ++j) { matriz[i][j]=' '; //cout <<"["<<matriz[i][j]<<"]"<<" "; } cout<<endl; } } ~Cria_Matriz() { delete [] matriz; } void jogar (int a)//comentar { int d, b=0, k, z=0, count1=0, count2=0; //int i=0; //int j=0; while (b==0) { if (z==2) z=0; d=1; while (d!=0) { if(z==0) { cout <<"Jogador 1 escolha uma posição.\n"<<endl; cin>>k; count1++; } else { cout <<"Jogador 2 escolha uma posição.\n"<<endl; cin>>k; count2++; } /*if (k>'a'||k<'z' && k>'A'||k<'Z') cout<<"Insira um numero."<<endl; d=1;*/ if(k<=0 || k>(n*n)) { cout<<"Aposta fora do tamanho da matriz."<<endl; d=1; } else { if (matriz[(k-1)/a][(k-1)%a]=='X'||matriz[(k-1)/a][(k-1)%a]=='O') { cout<<"Posição já ocupada."<<endl; d=1; } else d=0; } //b=1; } if (z==0) matriz[(k-1)/a][(k-1)%a]=jogador1; else matriz[(k-1)/a][(k-1)%a]=jogador2; mostrar(); z++; if(count1==n || count2==n) vitoria (); } } void mostrar()//Retorna a matriz com a opção escolhida pelos jogadores { for (int i =0; i < n; ++i) { for (int j= 0; j < n; ++j) { cout <<"["<<matriz[i][j]<<"]"<<" "; } cout<<endl; } } bool win() { int j=0,count1=0,i,count2=0; for (int i =0; i < n; ++i) for (int j= 0; j < n; ++j) { if(matriz[i][j]==jogador1); //j++; } return true; } bool draw() { return false; }};int main (){ system ("chcp 1252"); int a; regras(); cout<< "Insira o tamanho do tabuleiro, no minimo 3. Obrigado\n"; cin>>a; Cria_Matriz1 matrix(a); Cria_Matriz mat(a); mat.jogar(a); system ("PAUSE"); return 0;}

>> If the game have a static array is easy because we can define all the positions that lead to win, but this array is dynamic.

You can access the dynamically allocated array in pretty much the same way as a statically allocated array. So, if you know how to do it with a statically allocated array, you do the same thing with a dynamically allocated array (the main difference is how you allocate and de-allocate the memory).

Maybe you have a specific problem with the code ? If so, please explain the problem you have in as much detail as possible.

Just as a remark : wouldn't you check whether there's a winner after every turn ? You can check that by looking if the placed piece completes a row of three or not.

Can you explain me ou i can accomplish this
>>the main difference is how you allocate and de-allocate the memory.
please i´m a beginner on this matter.
thank you.

I'm wondering if your question has to do not with 'dynamicly' sized array, but with a 'variable' sized array. In other words, like Infinity says it shouldn't matter to you 'how' the memory gets allocated. However, it looks like the 'amount' of memory your allocating (or the size of your array) changes. Can you explain why you would want to use a variable sized array for a game of tic tac toe? It seems to me that the board is always the same size so I don't quite understand why you would want to do that. I didn't have time to really analyze your code so sorry if I am misreading it, but that's what it looked like at first glance.

And just a clarification for you, 'dynamic' refers to the ability to allocate memory at any TIME, not the ability to allocate memory of any SIZE. However, it's the ability to do it at any time that also allows us to choose the size when we need it rather than before we know how much memory we need.

Hi infinity08, i already do that when i create the dynamic arrays as you can see on my code.
But my realy problem is when i want to see if some positions on the array are with 'X' in this case or with 'O'.
i try to do this like this but but dont work :(
Like this i want to see if the 'X' win in every colums
for (int i =0; i < n;++i) \\ while is true increment i so we can see the positions 00,10,20, for a matrix 3x3 but not the positions 01,11,21
if(matriz[i][j]==jogador1)
return true;
On this i want to see every value o 'X' on rows
for (int j =0; j < n;++j) \\ while is true increment i so we can see the positions 01,02,03, for a matrix 3x3 but not the positions 10,11,12
if(matriz[i][j]==jogador1)
return true;
and for the diagonal i didn´t figure out.
thanks

Why are you saying "<n" in your for loops? Wouldn't n always be equal to 2? Your board size doesn't change so I don't see why you are using a variable there. I haven't had a chance to look at your code carefuly, but that's just something odd that sticks out to me.

For a static array of 3x3 i make something like this.

bool vitoria()
{
int f=0, i=0,j=0;

for(int i=0;i<n;++i)
if (matriz[i][j]==matriz[i][j+1] && matriz[i][j+2]==matriz[i][j+1])
return true;
//for(int i=0;i<n;++i)
if (matriz[i][j]==matriz[i+1][j] && matriz[i+2][j]==matriz[i+1][j])
return true;
for(int i=0;i<n;++i)
if (matriz[i][j]==matriz[i+1][j+1] && matriz[i+1][j+1]==matriz[i+2][j+2])
return true;
}
but for dynamic array i cant do it because the array can be a 3x3 or 4x4 or 8x8 etc....

OK, your implementation for the static array is only good if your array is really small. But what if you had an array of 500x500? You wouldn't want to write all the code it would take to check that using the same logic that you are currently using. So your problem has less to do with dynamic arrays, and more to do with just a poor logic.

Here's some psuedo code of a better way you could do it.

GameOver = false
for (i = 1; i < number of items in row; i++)
{
if item i in the row <> 1st item in the row then break
}
if i = number of items in row then GameOver = true

For starters, in your loop you say j < n. If you have an array with 15 items then that means that the last value for j will be 14, which is the top # of the array (0 to 14 = 15 items). However, you are accessing item number j+1, which on the last loop will = 15, which is one higher then the highest index of your array.

I haven't used c++ in years, but if I remember correctly it doesn't throw an error when you do this, it just accessing the next piece of memory which could be anything and is definitely not likely to be an X or an O.

Change your if statement from
if (matriz [i][j]!=matriz [i][j+1])
to
if (matriz [i][j]!=matriz [i][0])

All of the items have to be the same, and there will always be an index of 0 since it is the first index. So it's simpler just to use it to check against.

>> But my realy problem is when i want to see if some positions on the array are with 'X' in this case or with 'O'.

Whenever a player places a piece, you can check whether that piece completes a line of 3. If it does, the player wins. If not, the game continues.

Even on boards bigger than 3x3, that's not really a problem (although the game itself becomes less interesting imo). All you have to do, is use the position of the piece as the middle point of a 5x5 matrix, and in all 4 directions (horizontal, vertical, and the two diagonals), check whether there are two neighboring pieces of the same type. For this, you can use code that is similar to what you had for the statically allocated array (with the only difference that the positions are calculated relative to a certain variable position on the board, rather than a fixed position).

A way you can "optimize" it, is to first check the 3x3 matrix around the position, and if needed, expand to the 5x5 matrix around it.

bool vitoria()//Verifica se alguém ganhou a partida. { int count=0,i=0,j=0; // ver se alguem fez a linha for (int i = 0; i < n; ++i) { char c = matriz[i][0]; for (int j = 1; j < n; ++j) { if (c != ' ' && c == matriz[i][j]) count++; } if (count == n-1) return true; count = 0; } // ver se alguem fez a coluna for (int i = 0, count = 0; i < n; ++i) { char c = matriz[0][i]; for (int j = 1; j < n; ++j) { if (c != ' ' && c == matriz[j][i]) count++; } if (count == n-1) return true; count = 0; } // ver se alguem fez a diagonal char c = matriz[0][0]; for ( int i = 1, count = 0; i < n; ++i) { if (c != ' ' && c == matriz[i][i]) count++; if (count == n-1) return true; } c = matriz[0][n-1]; for (int i = 1, j = n-2, count = 0; i < n; ++i, --j) { if (c != ' ' && c == matriz[i][j]) count++; if (count == n-1) return true; } return false; }

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…

This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…