Jump to content
Fórum Script Brasil
  • 0

Jogo da Velha(minMax) - Jogada da maquina


jcrbs

Question

Eu queria saber como melhorar o jogo do computador. Porque quando eu elevar o nível de jogo no computador em vez disso, deve desempenhar o seu melhor, o que não ocorre. Eu coloquei o movimento em uma lista de árvore aumentando-a cada interação de acordo com a atual diretoria e do nível de dificuldade. Por exemplo, se o nível aumenta gera mais ocorrências de avaliar.

/****

*

* MelhorJogada(): Estima a melhor jogada a ser feita a seguir

*

* Argumentos: tab (entrada) - tabuleiro que representa a raiz da árvore de jogo

* atual

* profundidade (entrada) – a profundidade da árvore de jogo

* jogador (entrada) – o jogador da vez

* novoTab (saída) - tabuleiro original alterado para conter a melhor

* jogada

*

****/

/****

*

* ConstroiArvore(): Retorna um ponteiro para uma árvore de jogo

*

* Argumentos: tab (entrada) - tabuleiro que representa a raiz da árvore

* profundidade (entrada) – a profundidade da árvore

*

* Retorno: ponteiro para a raiz da árvore criada

*

****/

/****

*

* Expande(): Expande um nó da árvore de jogo, gerando todas as posições

* que podem ser obtidas a partir do tabuleiro do nó recebido

* como argumento. Os nós gerados tornam-se filhos do nó

* recebido como argumento. Então, esta função é chamada

* recursivamente usando os nós gerados como argumentos até

* que a profundidade desejada seja atingida.

*

* Argumentos: p (entrada/saída) - ponteiro para o nó a ser expandido

* nivel (entrada) – nível do nó

* profundidade (entrada) – profundidade da expansão

*

****/

/****

*

* GeraFilhos(): Retorna um ponteiro para uma lista de nós que são filhos do

* nó cujo tabuleiro é passado como argumento.

*

* Argumentos: tab (entrada) – tabuleiro do qual serão gerados os nós

*

* Retorno: ponteiro para a lista de nós gerados

*

****/

/****

*

* AcrescentaNaLista(): Acrescenta um nó à lista de nós recebida como argumento

* e retorna um ponteiro para a lista acrescida

*

* Argumentos: lista (entrada/saída) – ponteiro para início da lista de nós

* tab (entrada) – tabuleiro antes da jogada

* linha, coluna (entrada) – a linha e a coluna onde será feita a

* jogada

* jogada (entrada) – a jogada a ser feita (X ou O)

*

* Retorno: ponteiro para a lista acrescida do nó resultante da jogada

*

****/

/****

*

* ProcuraMelhorLance(): Procura a melhor jogada na árvore cuja raiz é

* recebida como argumento

*

* Argumentos: arvore (entrada) – ponteiro para a árvore de jogo

* jogador (entrada) – o jogador (X ou O) que tem a vez

* melhor (saída) – ponteiro para o nó que representa a melhor jogada

* valor (saída) – o valor do melhor nó

*

****/

/****

*

* Avalia(): Avalia estaticamente a posição do tabuleiro para o dado jogador.

* O resultado da avaliação é o número de linhas, colunas e

* diagonais que podem ser preenchidas pelo jogador menos o número

* destas que podem ser preenchidas por seu oponente.

*

* Argumentos: tab (entrada) - o tabuleiro que será avaliado

* jogador (entrada) - o jogador que tem a vez

*

* Retorno: o valor da avaliação

*

****/

* ConstroiArvore (): Retorna um ponteiro para uma árvore de jogo

* Argumentos: guia (entrada) - a placa que representa a raiz da árvore de profundidade (de entrada) - a profundidade da árvore

* Retorno: ponteiro para a raiz da árvore criada

* Expande (): Expande um nó da árvore de jogo, criando todas as posições que podem ser obtidos a partir da placa do nó recebido como argumento. A gerado nos tornamos filhos do nó recebido como argumento. Assim, esta função é chamada recursivamente gerado usando os nós como argumentos, até a profundidade desejada.

* Argumentos: P (entrada / saída) - ponteiro para o nó a ser expandido

* Nível (entrada) - nível de nó

* Profundidae (em) - expansão de profundidade

* GeraFilhos (): Retorna um ponteiro para uma lista de nós que são filhos do nó cujo conselho é passado como argumento.

* Argumentos: guia (entrada) - O Conselho de que serão gerados os nós

* Retorno: ponteiro para a lista de nós gerados

* AcrescentaNaLista (): Adiciona um nó para a lista que recebeu como um argumento e retorna um ponteiro para a lista mais

* Argumentos: lista (entrada / saída) - ponteiro para o início da lista de nós

* Guia (entrada) - a bordo antes da mudança

* Linha, coluna (de entrada) - a linha ea coluna onde o jogo será

* Move (entrada) - o movimento a ser feito (X ou O)

*

* Retorno: ponteiro para o nó lista resultante do jogo aumento

* ProcuraMelhorLance (): Procurando a melhor jogada na árvore cuja raiz é

Recebido como argumento

* Argumentos: árvore (entrada) - ponteiro para a árvore de jogo

* Player (entrada) - o jogador (X ou W), com o

* Melhor (saída) - ponteiro para o nó que representa o melhor jogo

* Valor (output) - o valor da melhor nó

* Avaliar (): Avalia posição estaticamente placa para o jogador.

* O resultado da avaliação é o número de linhas, colunas e diagonais que podem ser preenchidos pelo jogador menos o número destes que pode ser preenchido por seu adversário.

* Argumentos: guia (entrada) - O Conselho que será avaliada

* Player (entrada) - o jogador que tem a vez

* Retorno: O valor da avaliação

#include <stdio.h>
#include <stdlib.h>


typedef enum {VAZIO = ' ', O = 'O', X = 'X'} tConteudo;
typedef enum {MIN, MAX} tTipoDeNo;
typedef enum {FAIL, SUCESS} tValida;
typedef enum {EASY = 1, MEDIUM = 2, HARD = 3} tDificult;


typedef  struct  no
{
    tConteudo tabuleiro[3][3];
    tTipoDeNo tipoDeNo;
    struct  no  *filhoEsquerda;
    struct  no  *proximoIrmao;
} tNo, *tArvore;


tArvore AcrescentaNaLista( tArvore *lista, tConteudo tab[][3],
                           unsigned linha, unsigned coluna, tConteudo jogada )
{
    tArvore   aux;
    unsigned  i, j;
    aux = (tArvore)malloc(sizeof(tNo));

    for (i = 0; i < 3; ++i)
        for (j = 0; j < 3; ++j)
            aux->tabuleiro[i][j] = tab[i][j];
    aux->tabuleiro[linha][coluna] = jogada;
    aux->proximoIrmao = *lista;
    aux->filhoEsquerda = NULL;
    *lista = aux;
    return aux;
}



tArvore GeraFilhos(tConteudo tab[][3])
{
    tArvore   listaDeNos = NULL;
    tConteudo quemJoga;
    unsigned  i, j;
    quemJoga =  O;
    for (i = 0; i < 3; ++i)
        for (j = 0; j < 3; ++j)
            if (tab [i][j] == VAZIO)
                listaDeNos = AcrescentaNaLista(&listaDeNos, tab, i, j, quemJoga);
    return listaDeNos;
}

void Expande(tArvore p, unsigned nivel, unsigned profundidade)
{
    tArvore filhos;
    if (nivel <= profundidade)
    {
        filhos = GeraFilhos(p->tabuleiro);
        p->filhoEsquerda = filhos;

        while(filhos)
        {
            if (p->tipoDeNo == MAX)
                filhos->tipoDeNo = MIN;
            else
                filhos->tipoDeNo = MAX;

            filhos->filhoEsquerda = NULL;

            Expande(filhos, nivel + 1, profundidade);
            filhos = filhos->proximoIrmao;
        }
    }
}


tArvore ConstroiArvore(tConteudo tab[][3], unsigned profundidade)
{
    tArvore  arvore;
    unsigned i, j;
    arvore = malloc(sizeof(tNo));

    for (i = 0; i < 3; ++i)
        for (j = 0; j < 3; ++j)
            arvore->tabuleiro[i][j] = tab[i][j];
    arvore->tipoDeNo = MAX;
    arvore->filhoEsquerda = NULL;
    arvore->proximoIrmao = NULL;
    Expande(arvore,  1, profundidade);
    return arvore;
}

int Avalia(tConteudo tab[][3], tConteudo jogador)
{
    unsigned  i, j;
    tConteudo oponente;
    int valor = 0, valorOponente = 0;

    for (i = 0; i < 3; ++i)
        if ( ((tab[i][0] == jogador) || (tab[i][0] == VAZIO)) &&
                ((tab[i][1] == jogador) || (tab[i][1] == VAZIO)) &&
                ((tab[i][2] == jogador) || (tab[i][2] == VAZIO)) )
            valor++;
    /* Verifica quantas colunas o jogador pode preencher */
    for (j = 0; j < 3; ++j)
        if ( ((tab[0][j] == jogador) || (tab[0][j] == VAZIO)) &&
                ((tab[1][j] == jogador) || (tab[1][j] == VAZIO)) &&
                ((tab[2][j] == jogador) || (tab[2][j] == VAZIO)) )
            valor++;
    /* Verifica quantas diagonais o jogador pode preencher */
    if ( ((tab[0][0] == jogador) || (tab[0][0] == VAZIO)) &&
            ((tab[1][1] == jogador) || (tab[1][1] == VAZIO)) &&
            ((tab[2][2] == jogador) || (tab[2][2] == VAZIO)) )
        valor++;
    if ( ((tab[0][2] == jogador) || (tab[0][2] == VAZIO)) &&
            ((tab[1][1] == jogador) || (tab[1][1] == VAZIO)) &&
            ((tab[2][0] == jogador) || (tab[2][0] == VAZIO)) )
        valor++;
    oponente =  X;

    for (i = 0; i < 3; ++i)
        if ( ((tab[i][0] == oponente) || (tab[i][0] == VAZIO)) &&
                ((tab[i][1] == oponente) || (tab[i][1] == VAZIO)) &&
                ((tab[i][2] == oponente) || (tab[i][2] == VAZIO)) )
            valorOponente++;

    for (j = 0; j < 3; ++j)
        if ( ((tab[0][j] == oponente) || (tab[0][j] == VAZIO)) &&
                ((tab[1][j] == oponente) || (tab[1][j] == VAZIO)) &&
                ((tab[2][j] == oponente) || (tab[2][j] == VAZIO)) )
            valorOponente++;

    if ( ((tab[0][0] == oponente) || (tab[0][0] == VAZIO)) &&
            ((tab[1][1] == oponente) || (tab[1][1] == VAZIO)) &&
            ((tab[2][2] == oponente) || (tab[2][2] == VAZIO)) )
        valorOponente++;
    if ( ((tab[0][2] == oponente) || (tab[0][2] == VAZIO)) &&
            ((tab[1][1] == oponente) || (tab[1][1] == VAZIO)) &&
            ((tab[2][0] == oponente) || (tab[2][0] == VAZIO)) )
        valorOponente++;
    return (valor - valorOponente);
}

void ProcuraMelhorLance(tArvore arvore, tConteudo jogador, tArvore *melhor,
                        int *valor)
{
    tArvore  p, melhor2;
    int      valor2;
    if (!arvore->filhoEsquerda)
    {
        *valor = Avalia(arvore->tabuleiro,jogador);
        *melhor = arvore;
    }
    else
    {
        p = arvore->filhoEsquerda;
        ProcuraMelhorLance(p, jogador, melhor, valor);
        *melhor = p;

        if (arvore->tipoDeNo == MIN)
            *valor = (-1)*(*valor);
        p = p->proximoIrmao;
        while (p)
        {
            ProcuraMelhorLance(p, jogador, &melhor2, &valor2);
            if (arvore->tipoDeNo == MIN)
                valor2 = (-1)*valor2;
            if (valor2 > *valor)
            {
                *valor = valor2;
                *melhor = p;
            }
            p = p->proximoIrmao;
        }
        if (arvore->tipoDeNo == MIN)
            *valor = (-1)*(*valor);
    }
}

void DestroiArvore(tArvore* raiz){

     if(*raiz != NULL){
             if((*raiz)->filhoEsquerda != NULL)
                DestroiArvore(&((*raiz)->filhoEsquerda));
             if((*raiz)->proximoIrmao != NULL)
                DestroiArvore(&((*raiz)->proximoIrmao));
             free(*raiz);
             *raiz = NULL;
     }
}



void MelhorJogada( tConteudo tab[][3], unsigned profundidade, tConteudo jogador,
                   tConteudo novoTab[][3] )
{
    tArvore  arvore, melhorLance;
    unsigned i, j;
    int      valor;

    arvore = ConstroiArvore(tab, profundidade);

    ProcuraMelhorLance(arvore, jogador, &melhorLance, &valor);
    for (i = 0; i < 3; ++i)
        for (j = 0; j < 3; ++j)
            novoTab[i][j] = melhorLance->tabuleiro[i][j];
    DestroiArvore(&arvore);
}

void Apresentacao(void)
{

    char enter;

    printf("Bem-vindo ao Jogo da Velha:\n");
    printf("O jogador comeca!!! \nEscolha se quer ser 'X' ou 'O'\nPronto p/comecar...");
    printf("Aperte ENTER p/ iniciar...");
    scanf("%c", &enter);
    if(enter == '\n')
    {
        system("cls");
    }

}
void InicializaTabuleiro(tConteudo tabuleiro[][3])
{

    unsigned  i, j, nOs = 0, nXs = 0;
    printf("\t\t\t\tTABULEIRO INICIALIZADO\n\n");
    for (i = 0; i < 3; ++i)
    {

        if(i == 1 || i ==2 )
        {
            printf("--- --- ---\n");
        }

        for (j = 0; j < 3; ++j)
        {
            tabuleiro[i][j] = VAZIO;
            if( j ==1)
                printf("| %c |", tabuleiro[i][j]);
            else
                printf(" %c ", tabuleiro[i][j]);
        }

        printf("\n");
    }

}

void ApresentaJogo(tConteudo tabuleiro[][3])
{

    unsigned  i, j;

    for (i = 0; i < 3; ++i)
    {

        if(i == 1 || i ==2 )
        {
            printf("--- --- ---\n");
        }

        for (j = 0; j < 3; ++j)
        {

            if( j ==1)
                printf("| %c |", tabuleiro[i][j]);
            else
                printf(" %c ", tabuleiro[i][j]);
        }

        printf("\n");
    }

}


void EscolheJogada(tConteudo tabuleiro[][3], tConteudo  jogador)
{

    tValida cond = FAIL;
    int opcao;


    do{

            printf("Escolha a jogada 1 a 9:\n");
            scanf("%d", &opcao);


            switch(opcao)
            {
            case 1:
                if(tabuleiro[0][0] == VAZIO)
                {
                    tabuleiro[0][0] = jogador;
                    cond = SUCESS;
                }
                break;
                 case 2:
                if(tabuleiro[0][1] == VAZIO)
                {

                    tabuleiro[0][1] = jogador;
                    cond = SUCESS;
                }
                break;
            case 3:
                if(tabuleiro[0][2] == VAZIO){
                    tabuleiro[0][2] = jogador;
                    cond = SUCESS;
                }
                break;
            case 4:
                if(tabuleiro[1][0] == VAZIO){
                    tabuleiro[1][0] = jogador;
                    cond = SUCESS;
                }
                break;
            case 5:
                if(tabuleiro[1][1] == VAZIO)
                {

                    tabuleiro[1][1] = jogador;
                    cond = SUCESS;
                }
                break;
            case 6:
                if(tabuleiro[1][2] == VAZIO)
                {
                    tabuleiro[1][2] = jogador;
                    cond = SUCESS;
                }
                break;
            case 7:
                if(tabuleiro[2][0] == VAZIO)
                {

                    tabuleiro[2][0] = jogador;
                    cond = SUCESS;
                }
                break;
            case 8:
                if(tabuleiro[2][1] == VAZIO)
                {

                    tabuleiro[2][1] = jogador;
                    cond = SUCESS;
                }
                break;
            case 9:
                if(tabuleiro[2][2] == VAZIO)
                {
                    tabuleiro[2][2] = jogador;
                    cond = SUCESS;
                }
                break;
            }
        }while (cond!= SUCESS);


}

unsigned JogoTerminado(tConteudo  tabuleiro[][3])
    {

        unsigned  i, j;
        tConteudo cont = VAZIO;

        unsigned jogadas =0;
        for (i = 0; i < 3; ++i)
            for (j = 0; j < 3; ++j)
                if (tabuleiro[i][j] == VAZIO)
                {
                    jogadas++;
                }

        return jogadas;
    }


tConteudo EhVencedor(tConteudo Matriz[][3])
{
    int linha, coluna;
    tConteudo vez = X;
    int ct=0;
    while (ct < 2){

     for (linha = 0; linha < 3; linha++){
     if ((Matriz[linha][0] == vez) && (Matriz[linha][1] == vez) && (Matriz[linha][2] == vez))
     return vez;

  for (coluna = 0; coluna < 3; coluna++){
    if ((Matriz[0][coluna] == vez) && (Matriz[1][coluna] == vez) && (Matriz[2][coluna] == vez))
      return vez;
  }
  if ((Matriz[0][0] == vez) && (Matriz[1][1] == vez) && (Matriz[2][2] == vez)){
     return vez;
    }
  if ((Matriz[0][2] == vez) && (Matriz[1][1] == vez) && (Matriz[2][0] == vez)){
    return vez;
}
     }
    vez = O;
    ct++;

}
   return VAZIO;
}



void AtualizaTabuleiro(tConteudo tabuleiro[][3], tConteudo novoTabuleiro[][3]){

        unsigned  i, j;

        for (i = 0; i < 3; ++i)
            for (j = 0; j < 3; ++j)
            tabuleiro[i][j] = novoTabuleiro[i][j];

}




    int main (void)
    {

        tConteudo tabuleiro[3][3];
        tConteudo novoTabuleiro[3][3];
        tConteudo jogador = X;
        tConteudo oponente = O;
        tConteudo campeao = VAZIO;
        tDificult prof = HARD;
        int opcao;
        int flag =  0;

        //Apresentacao();
            //printf("%d", (int)prof);
        InicializaTabuleiro(tabuleiro);
        //InicializaTabuleiro(novoTabuleiro);

        /*
        printf("\nEscolha a Dificuldade:\n 1 - FACIL\n2 - MEDIO\n3 - DIFICIL \n");
        scanf("%d", &prof);*/

        printf("%d", JogoTerminado(tabuleiro));
        printf("\nVc quer Iniciar?:\n 1 - SIM\n0 - não \n");
        scanf("%d", &flag);



        while( JogoTerminado(tabuleiro) > 0)
        {
            printf("Quantidade de jogadas= %d\n", JogoTerminado(tabuleiro));
            if (flag == 1)
            {
                EscolheJogada(tabuleiro, jogador);
                flag = 0;
                //ApresentaJogo(tabuleiro);
            }
            else
            {
                MelhorJogada( tabuleiro, (int)prof,oponente,novoTabuleiro);
                //EscolheJogada(tabuleiro, oponente);
                //
                //ApresentaJogo(novoTabuleiro);
                AtualizaTabuleiro(tabuleiro, novoTabuleiro);

                flag = 1;
            }

            ApresentaJogo(tabuleiro);
            campeao = EhVencedor(tabuleiro);

            if(campeao == O ){
            printf("COMPUTER WIN");
            break;
            }else if(campeao == X){
            printf("YOU WIN!");
            break;
            }


        }


if(campeao == VAZIO){
    printf("DRAW!!!");
}



        system("PAUSE");
        return 0;
}

Edited by jcrbs
Link to comment
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152.2k
    • Total Posts
      652k
×
×
  • Create New...