Old game with Minimax does not work good

Asked

Viewed 51 times

1

I have a problem with my code that I can’t identify. In some moments my Minimax does not make the right move in which it should prevent the user from winning. I already searched everything, but I can’t. Follow the code in C:

#include<stdio.h>

int linha;
int coluna;

int max(int tabuleiro[3][3], int limite, int alfa, int beta);

void imprimir(int tabuleiro[3][3]){ //apenas imprime o tabuleiro
    int l;
    int c;
    for(l = 0 ; l < 3; l++){
        for(c = 0 ; c < 3; c++){
            if(tabuleiro[l][c] == 0){
                printf("    ");
            }else if(tabuleiro[l][c] == 1){
                printf("  X ");
            }else{
                printf("  O ");
            }
            if(c != 2){
                printf("|");
            }
        }
        printf("\n");
    }
    printf("\n");
}

int verificar(int tabuleiro[3][3], int linha, int coluna){ // verifica se a linha e coluna estão ocupadas ou não
    if(tabuleiro[linha][coluna] == 0){
        return 1;
    }else{ 
        return -1;
    }
}

int checar(int tabuleiro[3][3], int limite){//verifica se alguém ganhou
    if((tabuleiro[0][0] == 1 && tabuleiro[0][1] == 1 && tabuleiro[0][2] == 1) ||
    (tabuleiro[1][0] == 1 && tabuleiro[1][1] == 1 && tabuleiro[1][2] == 1) ||
    (tabuleiro[2][0] == 1 && tabuleiro[2][1] == 1 && tabuleiro[2][2] == 1) ||
    (tabuleiro[0][0] == 1 && tabuleiro[1][0] == 1 && tabuleiro[2][0] == 1) ||
    (tabuleiro[0][1] == 1 && tabuleiro[1][1] == 1 && tabuleiro[2][1] == 1) ||
    (tabuleiro[0][2] == 1 && tabuleiro[1][2] == 1 && tabuleiro[2][2] == 1) ||
    (tabuleiro[0][0] == 1 && tabuleiro[1][1] == 1 && tabuleiro[2][2] == 1) ||
    (tabuleiro[0][2] == 1 && tabuleiro[1][1] == 1 && tabuleiro[2][0] == 1)){
        return 10;
    }else if((tabuleiro[0][0] == 2 && tabuleiro[0][1] == 2 && tabuleiro[0][2] == 2) ||
        (tabuleiro[1][0] == 2 && tabuleiro[1][1] == 2 && tabuleiro[1][2] == 2) ||
        (tabuleiro[2][0] == 2 && tabuleiro[2][1] == 2 && tabuleiro[2][2] == 2) ||
        (tabuleiro[0][0] == 2 && tabuleiro[1][0] == 2 && tabuleiro[2][0] == 2) ||
        (tabuleiro[0][1] == 2 && tabuleiro[1][1] == 2 && tabuleiro[2][1] == 2) ||
        (tabuleiro[0][2] == 2 && tabuleiro[1][2] == 2 && tabuleiro[2][2] == 2) ||
        (tabuleiro[0][0] == 2 && tabuleiro[1][1] == 2 && tabuleiro[2][2] == 2) ||
        (tabuleiro[0][2] == 2 && tabuleiro[1][1] == 2 && tabuleiro[2][0] == 2)){
            return -10;
    }else if(limite == 9){
        return 0;
    }else{
        return -1;
    }
}

int * guardar_posicoes(int *vetor, int i, int j, int tam){//preenche o vetor que será utilizado no min ou max com as posições que estão livres
    vetor[tam] = i;
    vetor[tam+1] = j;
    return vetor;       
}

int * casas_disponiveis(int matriz[3][3], int *vetor){//busca quais posições do tabuleiro estão livre
    int tam = 0;
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            if(matriz[i][j] == 0){
                guardar_posicoes(vetor, i, j, tam);//chamada do método para preencher o vetor
                tam = tam + 2;
            }
        }
    }
    return vetor;
}

int maior(int max, int alfa){
    if(max >= alfa){
        return max;
    }else{
        return alfa;
    }
}

int menor(int min, int beta){
    if(min <= beta){
        return min;
    }else{
        return beta;
    }
}

int min(int tabuleiro[3][3], int limite, int alfa, int beta){
    int l = limite;
    int valorMin;
    valorMin = checar(tabuleiro, l);
    if(valorMin != -1){
        return valorMin;
    }else{
        int vetor[20];
        for(int k = 0; k < 20; k++){
            vetor[k] = -1;
        }
        casas_disponiveis(tabuleiro, vetor);
        int i = 0;
        while(vetor[i] != -1){
            tabuleiro[vetor[i]][vetor[i+1]] = 2;
            l = l + 1;
            int valorMax;
            valorMax = max(tabuleiro, l, alfa, beta);
            if(valorMin > valorMax || valorMin == -1){
                valorMin = valorMax;
            }
            if(valorMin <= alfa){
                tabuleiro[vetor[i]][vetor[i+1]] = 0;
                return valorMin;
            }
            beta = menor(valorMin, beta);
            tabuleiro[vetor[i]][vetor[i+1]] = 0;
            l = l - 1;
            i = i + 2;
        }
        return valorMin; 
    }
}

int max(int tabuleiro[3][3], int limite, int alfa, int beta){
    int l = limite;
    int valorMax;
    valorMax = checar(tabuleiro, l);
    if(valorMax != -1){
        return valorMax;
    }else{
        int vetor[20];
        for(int k = 0; k < 20; k++){
            vetor[k] = -1;
        }
        casas_disponiveis(tabuleiro, vetor);
        int i = 0;
        while(vetor[i] != -1){
            tabuleiro[vetor[i]][vetor[i+1]] = 1;
            l = l + 1;
            int valorMin;
            valorMin = min(tabuleiro, l, alfa, beta);
            if(valorMin > valorMax || valorMax == -1){
                valorMax = valorMin;
                linha = vetor[i];
                coluna = vetor[i+1];
            }
            if(valorMax >= beta){
                linha = vetor[i]; 
                coluna = vetor[i+1];
                tabuleiro[vetor[i]][vetor[i+1]] = 0;
                return valorMax;
            }
            alfa = maior(valorMax, alfa);           
            tabuleiro[vetor[i]][vetor[i+1]] = 0;
            l = l - 1;
            i = i + 2;          
        }
        return valorMax;
    }
}

int main (void){
    int tabuleiro[3][3];
    int limite, opc, l, c, valor, alfa, beta;
    limite = 0;
    for(int i = 0; i < 3; i++){
        for(int j = 0; j < 3; j++){
            tabuleiro[i][j] = 0;
        }
    }
    imprimir(tabuleiro);
    printf("Escolha um jogador para comecar:\n1 - Computador (X)\n2 - Usuario (O)\n");
    scanf("%d", &opc);
    if(opc == 2){
        printf("\nVez do usuario, informe as coordenadas\n");
        printf("Linha: ");
        scanf("%d", &l);
        printf("coluna: ");
        scanf("%d", &c);
        tabuleiro[l][c] = 2;
        imprimir(tabuleiro);
        limite++;
        while(limite <= 9){
            if(limite%2 == 0){
                printf("\nVez do usuario:\n");
                printf("Linha: ");
                scanf("%d", &l);
                printf("coluna: ");
                scanf("%d", &c);
                int v = verificar(tabuleiro, l, c);
                if(v == 1){
                    tabuleiro[l][c] = 2;
                    imprimir(tabuleiro);
                    limite++;
                }else if(v == -1){
                    printf("\nEscolha outra opcao\n");
                }               
            }else{
                printf("\nVez do computador:\n");
                alfa = -20;
                beta = 20;
                max(tabuleiro, limite, alfa, beta);
                tabuleiro[linha][coluna] = 1;
                imprimir(tabuleiro);
                limite++;   
            }
            valor = checar(tabuleiro, limite);
            if(valor != -1){
                break;
            }
        }
    }else if(opc == 1){
        printf("\nVez do computador:\n");
        alfa = -20;
        beta = 20;
        max(tabuleiro, limite, alfa, beta);
        tabuleiro[linha][coluna] = 1;
        linha = -1;
        coluna = -1;
        imprimir(tabuleiro);
        limite++;
        while(limite <= 9){
            if(limite%2 == 0){
                printf("\nVez do computador:\n");
                alfa = -20;
                beta = 20;
                max(tabuleiro, limite, alfa, beta);
                tabuleiro[linha][coluna] = 1;
                imprimir(tabuleiro);
                limite++;
            }else{
                printf("\nVez do usuario:\n");
                printf("Linha: ");
                scanf("%d", &l);
                printf("coluna: ");
                scanf("%d", &c);
                int v = verificar(tabuleiro, l, c);
                if(v == 1){
                    tabuleiro[l][c] = 2;
                    imprimir(tabuleiro);
                    limite++;
                }else if(v == -1){
                    printf("\nEscolha outra opcao\n");
                }
            }
            valor = checar(tabuleiro, limite);
            if(valor != -1){
                break;
            }
        }
    }else{
        printf("Opcao invalida, encerrando...");
    }
    if(valor == 10){
        printf("\n### Vitoria do computador! ###\n");
    }else if(valor == 0){
        printf("\n### Empate! ###\n");
    }else{
        printf("\n### Vitoria do usuario! ###\n");
    }
    return 0;
}
  • 1

    I played normally. It has to point out a situation where the code desvirtue?

  • You start with the computer, then choose the positions row= 1 and column = 2, then it plays, next you choose row= 1 and column = 1, then you will notice that the computer will not stop the user.

No answers

Browser other questions tagged

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