Play Tic-tac-toe with Minimax. Problem printing moves

Asked

Viewed 555 times

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... :)

  • 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.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.