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;
}
I played normally. It has to point out a situation where the code desvirtue?
– Augusto Vasques
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.
– Isaac