1
Me and two other friends are doing an old game in C using Minimax and tree as a Data Structure project and we are having trouble receiving the move, and also when showing it to the user. We believe it is likely that the error is in this line of code: jogada(&(*arv)->posicao[play], jogaPrimeiro, (t+1)%2);
, but we still can not fix. Any help is very welcome.
Follow the full code and 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");
}
}
Welcome to Stackoverflow, Jean! You can include the error you get when running the program (complete if possible) - Oh, and do the tour to know a little more about the site... :)
– Daniel
Please specify (give more details) about the problem you are encountering so the reader can easily understand how your code should work and help you objectively.
– Fernando Silveira