Ir para conteúdo
Fórum Script Brasil
  • 0

Jogo da Velha(minMax) - Jogada da maquina


jcrbs

Pergunta

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;
}

Editado por jcrbs
Link para o comentário
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      652k
×
×
  • Criar Novo...