Jogo da Velha contra o Computador.

Publicado por Danilo 18/04/2004

[ Hits: 36.863 ]

Homepage: http://www.danilocesar.com

Download jogo.c




Este Script C cria um jogo da velha contra o comptuador. Muito interessante, pois com técnicas básicas de algoritmos é possível
criar uma espécie de IA que é capaz de se defender, escolher posição de ataque. O Algoritmo prevê muita coisa, talvez na próxima versão, crie um que possa utilizar 'estratégias' de jogo.

As partes mais importantes do código estão comentadas, acho que é um ótimo script pra quem está começando a programar em C

  



Esconder código-fonte

/***************************************************/
/* Jogo da Velha.                                  */
/* Este Script C foi complicado em gcc 3.0 usando  */
/* Linux Debian Sarge                              */
/*                                                 */
/* A "IA" desde game consiste em prever as         */
/* ações do adversário.                            */
/* Basicamente, ele verifica se ele ou o adversário*/
/* podem ganhar jogando em uma casa específica     */
/* Caso ele ache um espaço que termine o jogo, ele */
/* marcará esta posição. Caso ele ache 2 posições, */
/* o algoritmo decide pelo que dá a vitória a si   */
/*                                                 */
/* Danilo Cesar                                    */
/* danilo_eu@hotmail.com                           */
/***************************************************/

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


#define Lado 3

char matriz[3][3]; /*Começa Declarando a Matriz do Jogo*/
char matriza[3][3];
char matrizb[3][3];
char vitoria;

void init_matriz();
void imprime_matriz();
int  jogador_joga(int a, int b);
void clrscr(void);
void pega_valores(void);
int checar(void);
int pc_joga();
void gera_rand();

/*Gera a semente randomica necessária para a função rand
e é executada no começo do programa*/
void gera_rand()
{
  int stime;
  int ltime;

  ltime=time(NULL);
  stime=(unsigned) ltime/2;
  srand(stime);

}

int pc_joga()
{
  int x,y,mx,my;
  int k,j,i;
  int erro=0;

  x=(rand()%3);
  y=(rand()%3);

  if(matriz[x][y]!=' ')
    {
      pc_joga();
      return(1);
    }
  else
    {
      /**************************************
O Computador gerará 2 números aleatórios X e Y.
E verificará se as coordenadas do ponto (X,Y) estão livre.
Se estiverem livres (matriz[x][y]==' ') então ele criará um
"backup" da matriz original, e vai começas a jogar em cima delas.
      */
      for(i=0;i<3;i++)
   for(j=0;j<3;j++)
     matriza[i][j]=matriz[i][j];


      for(i=0;i<3;i++)
   for(j=0;j<3;j++)
     {
       if (matriz[i][j]==' ')
         {
      /*Neste primeiro trecho de codigo, o computador
       já criou uma nova matriz. Aqui, ele marca O num ponto
      qualquer e depois verifica se com este ponto ele consegue ganhar o jogo*/
      matriz[i][j]='O';
      if((checar()!=0))
        {
          mx=i;
          my=j;
          erro=2;
         }
      else
        {/*Caso o computador não possa marcar zero neste ponto, ele
fará o teste para ver se o jogador pode ganhar o jogo. Caso ele consiga vencer o jogo, o computador
marca esta posição para evitar a vitória adversária.

Logicamente, a varável erro é verificada como diferente de 2. Pois caso o computador ache
um ponto onde ele possa ganhar, não vale a pena ele procurar outro para evitar a vitória adversária.
*/
          matriz[i][j]='X';
          if((checar()!=0)&&(erro!=2))
            {
         mx=i;
         my=j;
         erro=1;
            }

        }

         matriz[i][j]=' ';
              }
     }

      //Restaura Matriz 
      for(i=0;i<3;i++)
   for(j=0;j<3;j++)
     matriz[i][j]=matriza[i][j];
      
      if (erro==0)
    matriz[x][y]='O';
      if (erro!=0)
   matriz[mx][my]='O';
    }
}




/*Função que verifica se há vencedor*/
int checar()
{
  int erro=0;

  int i;
  //Caso a diagonal esteja vencida
  if ((matriz[0][0]==matriz[1][1])&&(matriz[1][1]==matriz[2][2])&&(matriz[0][0]!=' '))
   {
     erro=1;
     vitoria=matriz[0][0];
   }
  

  //Verifica Linhas e Colunas
  for(i=0;i<Lado;i++)
    {
      if ((matriz[i][0]==matriz[i][1])&&(matriz[i][1]==matriz[i][2])&&(matriz[i][0]!=' '))
   {
     erro=1;
     vitoria=matriz[i][0];
   }
      if ((matriz[0][i]==matriz[1][i])&&(matriz[1][i]==matriz[2][i])&&(matriz[0][i]!=' '))
   {
     erro=1;
     vitoria=matriz[0][i];
   }
    }
  //Verifica Diagonal Inversa
  if ((matriz[2][0]==matriz[1][1])&&(matriz[1][1]==matriz[0][2])&&(matriz[2][0]!=' '))
   {
     erro=1;
     vitoria=matriz[2][0];
   }


  return(erro);
}



/*Função que pede as coordenadas ao usuário*/
void pega_valores(void)
{
  int x,y;
  printf("\n\nDigite as coordenadas do tipo: Linha, Coluna");
  scanf("%d%d",&x,&y);
  jogador_joga(x,y);
}

/*Função para limpar a tela*/
void clrscr(void)
{
  system("clear");
}


/*Esta função recebe como argumento a coordenada onde deve-se marcar o X.
Faz as verificações necessárias, e marca X na matriz*/
int jogador_joga(int a, int b)
{
  clrscr();
  if((a>Lado)||(b>Lado)||(a<1)||(b<1))
    {
      printf("Valores Inválidos %d,%d\n\n",a,b);
      imprime_matriz();
      
      pega_valores();
    }
  else if(matriz[a-1][b-1]!=' ')
    {
      printf("Casa já foi preenchida %d,%d \n\n",a,b);
      imprime_matriz();
      pega_valores();
    }
  else
    matriz[a-1][b-1]='X';

}


/*Esa função simplismente gera um gráfico ASCII da Matriz na tela*/
void imprime_matriz()
{
  int i;
  printf("\n\n");
  for(i=0;i<Lado;i++)
    {
      printf(" %c | %c | %c\n",matriz[i][0],matriz[i][1],matriz[i][2]);
      if(i<Lado-1)
   printf("------------\n");
    }
}

/*Inicia a Matriz*/
void init_matriz()
{
  int k,j;
  for (k=0;k < Lado;k++)
    for(j=0;j < Lado;j++)
      matriz[k][j]=' ';
}


int main(void)
{
  
  int jogadas;
  gera_rand();                       // Coloca semente randomica no sistema

  init_matriz();
  jogadas = 0;                       //Zera o numero de jogadas.
  do
    {
      imprime_matriz();
      pega_valores();
      jogadas++;
      if((checar()==0)&&(jogadas<9)) // Verifica se não houve vitórias ou se acabaram
   {                            // ou se acabaram o numero de jogadas.
     pc_joga();                 // Caso contrário, o computador joga e numero de jogadas
     jogadas++;                 // Aumenta um
   }
    }while((checar()==0)&&(jogadas<9)); //Repere a verificação
  imprime_matriz();                   // Imprime matriz final na tela
  return(0);
}

Scripts recomendados

Despertador em C

Argv e Argc

Balanceamento de parênteses utilizando Pilha

Campo Elétrico

Cara ou Coroa


  

Comentários
[1] Comentário enviado por birilo em 18/04/2004 - 23:28h

Seguinte gente.... Fui verificar o código hoje de umas coisas que eu esqueci de tirar....

Linha 27, retirar a declaração global:
char matrizb[3][3];
a variável vitória declarada a baixo também pode ser retirada, pois eu acabei não utilizando.

A 'Matriza', variavel Global, era importante quando eu estava construindo o código, mas também não é mais necessária. Pode-se retirar esse trecho do código.

[2] Comentário enviado por fabio em 22/04/2004 - 20:49h

Maneiríssimo esse script! :)))

[3] Comentário enviado por Bridda em 03/06/2004 - 22:20h

Danilo, vc poderia me ajudar a arrumar um programa deste mesmo jogo só que para sistemas distribuídos? por favor, diz que sim, estou desesperada!!!

[4] Comentário enviado por jochan em 14/12/2005 - 14:34h

Muito legal, vai me ajudar bastente no meu projeto de C++ ... =)

[5] Comentário enviado por HeltonBarbosa em 14/08/2006 - 07:56h

Muito bom esse script, ao ver esse código tive uma idéia e logo postarei no VOL. Valeu...

[6] Comentário enviado por 360guilherme em 29/01/2007 - 17:00h

Até que gostei do jogo
tô tentando implementar um usando arvore para a faculdade

mas achei dois probleminhas nele:
- ele não é invencivel! um jogo desse tipo usando principios de IA deve3ria no maximo permitir um empate.
- o outro problema é que toda vez que fico a uma jogada de ganhar o jogo encerra sozinho, a não ser que esse seja o seu metodo para não permitir que o computador perca.

valeu

[7] Comentário enviado por birilo em 01/02/2007 - 07:45h

Cara....

Faz tanto tempo que fiz este script cara que nem lembro mais como funciona...
Que eu me lembre não dá problema nele....

Mas, depois de um tempo, pensei em desenvolver outro usando árvores. Desta forma seria mais fácil calcular todos os movimentos possíveis do Humano. Mas não fiz por falta de tempo...


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts