I and two other friends are doing a game of the old in C using MiniMax and tree as a Data Structure project and we are having a problem when it comes to receiving the game, and also when it is time to show it to the user. We believe that the error is likely to be in this line of code: jogada(&(*arv)->posicao[play], jogaPrimeiro, (t+1)%2);
, but we still can not fix it. Any help is very welcome.
Follow the complete code with some comments:
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
//Raiz = Max.
//Bolinha = 2 (turno ímpar)
//Xis = 1 (turno par)
int vetorDisponibilidadeJogada[9];
int vetorJogadas[9];
typedef struct node
{
int tabuleiro[9];
int minimax;
node *posicao[9];
int jogada;
} node;
void inicializar(node **arv);
void inicializaVetorPossibilidades();
void funcaoRecursivaPossibilidades(node **arv, int alturaDaArvore, int dificuldade);
int insere(node **arv, int dificuldade, int *vetor, int turno);
int acabou(node **arv);
void jogada(node **arv, int quemJoga, int t); //quemJoga deve ser 0 ou 1 (0 = Vc, 1 = IA)
void imprime(int *vetor);
//void imprimeLinha(node **arv){
// int i;
// for(i=0; i<9; i++){
// imprime((*arv)->posicao[i]->tabuleiro);
// }
//}
main()
{
setlocale(LC_ALL, "Portuguese");
int dificuldade, jogaPrimeiro, i;
node *raiz, *nutella;
inicializaVetorPossibilidades();
inicializar(&raiz);
do
{
printf("\nEscolha a dificuldade [1-9]: ");
scanf("%i", &dificuldade);
fflush(stdin);
}while (dificuldade < 1 and dificuldade > 9);
funcaoRecursivaPossibilidades(&raiz, 0, dificuldade);
//imprimeLinha(&raiz);
do
{
printf("\nEscolha quem joga primeiro [0 -> Usuário - 1 -> IA]: ");
scanf("%i", &jogaPrimeiro);
fflush(stdin);
}while (jogaPrimeiro < 0 and jogaPrimeiro > 1);
jogada(&raiz, jogaPrimeiro, 0);
}
void inicializar(node **arv)
{
*arv = (node*) malloc (sizeof(node));
int i;
for (i = 0; i < 9; i++)
{
(*arv)->posicao[i] = NULL;
(*arv)->tabuleiro[i] = 0;
}
}
void inicializaVetorPossibilidades ()
{
int i;
for (i = 0; i < 9; i++)
vetorDisponibilidadeJogada[i] = 1;
}
void funcaoRecursivaPossibilidades(node **arv, int alturaDaArvore, int dificuldade)
{
int i = 0;
if (alturaDaArvore == dificuldade)
{
insere(&(*arv), dificuldade, vetorJogadas, 0);
}
else {
for (i = 0; i < 9; i++){
if (vetorDisponibilidadeJogada[i] == 1)
{
vetorDisponibilidadeJogada[i] = 0;
vetorJogadas[alturaDaArvore] = i;
funcaoRecursivaPossibilidades(arv, alturaDaArvore + 1, dificuldade);
vetorDisponibilidadeJogada[i] = 1;
}
}
}
}
int insere(node **arv, int dificuldade, int *vetor, int turno)
{
int i, comp;
if(turno == dificuldade) return 0;//conferir isto
if(!((*arv)->posicao[vetor[turno]]))//se o prox nó ainda não foi alocado, ele é alocado, inicializado, recebe o estado atual do tabuleiro e a nova jogada
{
((*arv)->posicao[vetor[turno]]) = (node*) malloc (sizeof(node));
inicializar(&(*arv)->posicao[vetor[turno]]);//zera todo o tabuleiro e faz todos ponteiros apontarem para NULL
//minimax deve receber a pior possibilidade aqui
(*arv)->posicao[vetor[turno]]->minimax = ((turno+1)%2)+1;//inicializa o valor de minimax de acordo com a pior possibilidade
// 1<0; 2>0>1
for(i = 0; i < 9; i++)
(*arv)->posicao[vetor[turno]]->tabuleiro[i] = (*arv)->tabuleiro[i];//copia o nó atual para o que está sendo alocado
(*arv)->posicao[vetor[turno]]->tabuleiro[turno] = (turno%2 + 1);//faz a nova jogada no tabuleiro que foi alocado
}
if(!acabou(&(*arv)->posicao[vetor[turno]]))//se o jogo ainda não acabou, continua alocando as jogadas
{
comp = insere(&(*arv)->posicao[vetor[turno]], dificuldade, vetor, turno+1);//comp recebe o minimax propagado pela função ate aqui
//se o turno for 1, minimax recebe o menor se for 2 recebe o maior
if(comp == ((turno)%2)+1)//o retorno é o desejado?
{
(*arv)->posicao[vetor[turno]]->minimax = comp;
}else
if(!comp and (*arv)->posicao[vetor[turno]]->minimax != ((turno)%2)+1)//o retorno é 0 E eu ainda não tenho o desejado?
{
(*arv)->posicao[vetor[turno]]->minimax = comp;
}
}else
{
(*arv)->posicao[vetor[turno]]->minimax = acabou(&(*arv)->posicao[vetor[turno]]);//minimax sabe quem ganhou quando o jogo acaba
}
return (*arv)->posicao[vetor[turno]]->minimax;//propaga o minimax para a chamada recursiva
}
int acabou(node **arv)
{
int i, j, v[3];
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
v[j] = (*arv)->tabuleiro[(i * 3) + j];
if(v[0] == v[1] and v[0] == v[2] and v[0])
return v[0];
}
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
v[j] = (*arv)->tabuleiro[(j * 3) + i];
if(v[0] == v[1] and v[0] == v[2] and v[0])
return v[0];
}
for(i = 0; i < 3; i++)
v[i] = (*arv)->tabuleiro[(i * 3) + i];
if(v[0] == v[1] and v[0] == v[2] and v[0])
return v[0];
for(i = 0; i < 3; i++)
v[i] = (*arv)->tabuleiro[(i * 3) + 2 - i];
if(v[0] == v[1] and v[0] == v[2] and v[0])
return v[0];
return 0;
}
void jogada (node **arv, int jogaPrimeiro, int t)
{
int play, i, eleito, minimaxAtual, desejado;
node *ponteiro;
imprime((*arv)->tabuleiro);
if(acabou(&(*arv)))
return;
if(jogaPrimeiro)
{
minimaxAtual = 2;
desejado = 1;
}else
{
minimaxAtual = 1;
desejado = 2;
}
if (!((t+jogaPrimeiro)%2))
{
printf("\nEscolha sua jogada [0-8]: ");
scanf("%d", &play);
fflush(stdin);
jogada(&(*arv)->posicao[play], jogaPrimeiro, (t+1)%2);
}else
{
for(i = 0; i < 9; i++)
{
if(!(*arv)->tabuleiro[i])
{
if((*arv)->posicao[i]->minimax==minimaxAtual)
{
eleito = i;
}else
{
if((*arv)->posicao[i]->minimax==desejado)
{
minimaxAtual = desejado;
eleito = i;
}else
if((*arv)->posicao[i]->minimax==0&&minimaxAtual!=desejado)
{
minimaxAtual = 0;
eleito = i;
}
}
}
}
jogada(&(*arv)->posicao[eleito], jogaPrimeiro, (t+1)%2);
}
}
void imprime(int *vetor)
{
int i, j;
char jogada[9];
for(i = 0; i < 9; i++)
{
if(vetor[i] == 1) jogada[i] = 'X';
if(vetor[i] == 2) jogada[i] = 'O';
if(vetor[i] == 0) jogada[i] = ' ';
}
for(i = 0; i < 3; i++)
{
printf(" %c | %c | %c\t\t\t %i | %i | %i\n", jogada[(i * 3) + 0], jogada[(i * 3) + 1], jogada[(i * 3) + 2], (i * 3) + 0, (i * 3) + 1, (i * 3) + 2);
if(i < 2)
printf("---+---+---\t\t\t---+---+---\n");
}
}