Jogo da velha, básico

Publicado por Marco Carvalho de Oliveira 21/09/2006

[ Hits: 25.069 ]

Homepage: http://demoncyber.wordpress.com/

Download Teste.cpp




Certa vez, um amigo meu, que faz curso de Engenharia Civil, pediu para eu lhe ajudar com exercícios de programação. Nossa, não entendo porque Engenharia Civil possui isto, assim como outros cursos por aí, mas acho que esta discussão foge ao escopo. Bom, escrevi isto porque não podia usar de um código muito complexo, mas também não queria fazer um lixo, final de contas, ficou bem interessante o código e ele está documentado. Dou todos os direitos de cópia. Espero ajudar alguém. =]

  



Esconder código-fonte

#include <stdio.h>

int   tabuleiro[3][3];
// Variável que mantém as posições das jogadas
int   njogada;
// Mantém qual é o numero da jogada
float vitorias[2];
// Mantém o placar das partidas
int   gamePC=0;
// Variável usada para saber se o computador joga ou não

void opcaoInvalida(int option){
  // imprime a opção inválida e uma ajuda de como escolher uma opção válida
  printf("*********************************************");     
  printf("\n\t\tOpcao invalida");
  printf("\n*********************************************");
  printf("\n");
  printf("\nA opcao %d nao consta na lista",option);        
  printf("\nPor favor tente uma opcao valida");
  printf("\n");
  printf("\nExemplo: 1");
  printf("\n");
  printf("\nO exemplo acima acessa o jogo no modo ");
  printf("\nJogador X Jogador");
  printf("\n");
  printf("\n*********************************************");     
  printf("\n\t\tOpcao invalida");
  printf("\n*********************************************");    
}

void empate(){
  // Imprime a resolução da partida como empate e depois imprime o placar
  printf("*********************************************");     
  printf("\n\tA partida empatou (Placar)");
  printf("\n*********************************************\n");
  printf("\n Jogador 1 vitorias: %f",vitorias[0]);
  printf("\n Jogador 1 derrotas: %f",vitorias[1]);
  printf("\n");
  printf("\n Jogador 2 vitorias: %f",vitorias[1]);
  printf("\n Jogador 2 derrotas: %f",vitorias[0]);
  printf("\n");  
  printf("\n Total de partidas : %f\n",(vitorias[0]+vitorias[1]));
  printf("\n*********************************************");     
  printf("\n\tA partida empatou (Placar)");
  printf("\n*********************************************");     
}

void imagemVitoria(int jogador){
  // Exibi uma "imagem" de vitória apos o termino de cada partida
  printf("*********************************************");  
  printf("\n\t    PARABENS JOGADOR %d",jogador);
  printf("\n");    
  printf("\n            AGRADECEMOS A PREFERÊNCIA      ");
  printf("\n*********************************************");  
  printf("\n");
  printf("\nWW     WW     WW IIIIIIIIIIIII NNN         NNN ");
  printf("\n WW   WWWW   WW      IIIII     NNN NNN     NNN ");
  printf("\n  WW WW  WW WW       IIIII     NNN     NNN NNN ");
  printf("\n   WW     WW     IIIIIIIIIIIII NNN         NNN "); 
  printf("\n*********************************************"); 
}

void placar(){
  // Imprime os dados do placar da partida
  printf("\n*********************************************");     
  printf("\n\t\tPlacar");
  printf("\n*********************************************\n");
  printf("\n Jogador 1 vitorias: %f",vitorias[0]);
  printf("\n Jogador 1 derrotas: %f",vitorias[1]);
  printf("\n");  
  printf("\n Jogador 2 vitorias: %f",vitorias[1]);
  printf("\n Jogador 2 derrotas: %f",vitorias[0]);
  printf("\n");  
  printf("\n Total de partidas : %f\n",(vitorias[0]+vitorias[1]));
  printf("\n*********************************************");     
  printf("\n\t\tPlacar");
  printf("\n*********************************************");
}  

void zeraPlacar(){
  // Zera as variáveis que mantém os dados de vitória logo zerando o placar    
  vitorias[0]=0;
  vitorias[1]=0;
  printf("\n*********************************************");     
  printf("\n\t\tPlacar Zerado!");
  printf("\n*********************************************\n");
  printf("\n Jogador 1 vitorias: %f",vitorias[0]);
  printf("\n Jogador 1 derrotas: %f",vitorias[1]);
  printf("\n");    
  printf("\n Jogador 2 vitorias: %f",vitorias[1]);
  printf("\n Jogador 2 derrotas: %f",vitorias[0]);
  printf("\n");    
  printf("\n Total de partidas : %f\n",(vitorias[0]+vitorias[1]));    
  printf("\n*********************************************");     
  printf("\n\t\tPlacar Zerado!");
  printf("\n*********************************************");    
}

void regras(){
  // Imprime as regras para se efetuar jogadas no jogo. 
  printf("\n*********************************************");
  printf("\n\t\tRegras!");
  printf("\n*********************************************\n");       
  printf("\nPara efetuar uma jogada se informa a posicao ");
  printf("\nda jogada ao modelo linha.coluna\n");
  printf("\nExemplo: 1.3 \n");
  printf("\nEsta jogada acima, vai marcar de acordo com o");
  printf("\no dono da jogada, o lance na linha 1 coluna 3\n");
  printf("\n*********************************************");
  printf("\n\t\tRegras!");
  printf("\n*********************************************");         
}

void abertura(){
  // Imprime informações sobre o programa
  printf("*********************************************");
  printf("\n\t\tJogo da Velha");
  printf("\n*********************************************");
  printf("\n");
  printf("\n\tJogo da velha PKY");
  printf("\n\tCriado em 2006");
  printf("\n\tPor Demon Cyber");
  printf("\n\tLinguagem: C");
  printf("\n\tTelefone:989898989");
  printf("\n\tContato: [email protected]");
  printf("\n\tA Faculdade qualquer");    
  printf("\n");
  printf("\n*********************************************");     
  printf("\n\t\tJogo da Velha");
  printf("\n*********************************************");  
}

int inicio(){
  // Imprime as opções de jogo e ápos isso lê a opção selecionada
  int result;
  printf("\n*********************************************");
  printf("\n\tPrograma de jogo da velha opcoes");
  printf("\n*********************************************\n");
  printf("\tJogador X Jogador  (1)\n");
  printf("\tJogador X PC       (2)\n");  
  printf("\tPlacar             (3)\n");
  printf("\tZera Placar        (4)\n");
  printf("\tRegras             (5)\n");  
  printf("\tSair               (6)\n");
  printf("\n\tOpcao:              ");
  scanf("%d",&result);
  return result;
}

void fimCasa(){
  // Imprime o corpo do fim de uma casa     
  printf(" ----- ");   
}

void inicioCasa(){
  // Imprime o corpo do ínicio de uma casa
  printf(" ----- ");
}

void casaVazia(){
  // Imprime o corpo de uma casa vazia
  printf("|     |");
}

void casaX(int line){
  // Imprime o corpo de uma casa que possuirá X     
  switch(line){
    case 0:
      printf("|X   X|");
    break;
    case 1:
      printf("| X X |");         
    break;      
    case 2:
      printf("|  X  |");         
    break;      
    case 3:
      printf("| X X |");         
    break;      
    case 4:
      printf("|X   X|");         
    break;      
  }  
}

void casa0(int line){
  // Imprime o corpo de uma casa que possuirá bolinha
  switch(line){
    case 0:
      printf("| *** |");
    break;
    case 1:
      printf("|*   *|"); 
    break;      
    case 2:
      printf("|*   *|");    
    break;      
    case 3:
      printf("|*   *|");         
    break;      
    case 4:
      printf("| *** |");      
    break;      
  }      
}

void zeraTabuleiro(){
  // Zera as variáveis que contém as posições das casas preenchidas
  int i,j;
  for(i=0; i <=2; i++){
    for(j=0; j <=2; j++){
        tabuleiro[i][j]=0;
    }
  }
}

void desenhaTabuleiro(){
  // Desenha o tabuleiro e as casas preenchidas com suas respctivas jogadas
  int i=0;
  int j=0;
  int z=0;
  printf("\n");
  for( z=0; z <= 2; z++){
  
    printf("\t    ");
    for( i=0; i <= 2; i++ )
      inicioCasa();     
    printf("\n");
      
    for( j=0; j < 5; j++ ){
      printf("\t    ");
      for( i=0; i <= 2; i++ ){
            
        if(tabuleiro[z][i] == 0)
          casaVazia();
        if(tabuleiro[z][i] == 1)
          casaX(j);
        if(tabuleiro[z][i] == -1)
          casa0(j);         
      }
      printf("\n");
    }
     
    printf("\t    ");
    for( i=0; i <= 2; i++ )
      fimCasa();         
    printf("\n");     
   }     
}

int verificaVitoria(){
  /*
    Verifica se algum jogador conseguiu condição de vitória
        
    Condições:
    
    *se a soma de toda uma linha, coluna ou diagonal resultar em 3 o jogador 1 
  venceu.
   
    *se resultar em -3 o jogador 2 venceu.
    
    *caso contrario ninguém venceu ainda
    
    *se todas as casas tiverem ocupadas ( 9 jogadas ) e nenhuma soma igualar os 
    casos acima patida empatou
    
  */
  int i,j;
  int somaA,somaB;
  somaA = 0;
  somaB = 0;
  
  for(j=0; j<3; j++){
    somaA = 0;
    somaB = 0;
    for(i=0; i<3; i++){
      somaA = somaA + tabuleiro[i][j];
      somaB = somaB + tabuleiro[j][i];
    }
    if (somaA == 3  || somaB == 3 )
      return 1;    
    if (somaA == -3 || somaB == -3)
      return 2;
  }

  somaA = tabuleiro[0][0] + tabuleiro[1][1] + tabuleiro [2][2];
  somaB = tabuleiro[0][2] + tabuleiro[1][1] + tabuleiro [2][0];
  if (somaA == 3  || somaB == 3 )
    return 1;    
  if (somaA == -3 || somaB == -3)
    return 2;
  if (njogada == 9)  
    return 3;
  return 0;
}

int verificaJogada(float jogada, int donoJogada){
  /*
    Verifica se a jogada é válida
    Caso sim:
      Verifica se a casa está vazia e então a preenche com o dono da Jogada
    Caso não:
      1 - Desenha de novo o tabuleiro com as posições sem a jogada inválida 
      2 - Informa uma mensagem de jogada Inválida com possivel erro a casa ja ter 
    sido preenchida    
  */
  if ((jogada == float(1.1)) && (tabuleiro[0][0] == 0)){
    tabuleiro[0][0] = donoJogada;
    return 1;
  }
  if ((jogada == float(1.2)) && (tabuleiro[0][1] == 0)){
    tabuleiro[0][1] = donoJogada;
    return 1;
  }     
  if ((jogada == float(1.3)) && (tabuleiro[0][2] == 0)){
    tabuleiro[0][2] = donoJogada;
    return 1;
  }     
  if ((jogada == float(2.1)) && (tabuleiro[1][0] == 0)){
    tabuleiro[1][0] = donoJogada;
    return 1;
  }     
  if ((jogada == float(2.2)) && (tabuleiro[1][1] == 0)){
    tabuleiro[1][1] = donoJogada;
    return 1;
  }     
  if ((jogada == float(2.3)) && (tabuleiro[1][2] == 0)){
    tabuleiro[1][2] = donoJogada;
    return 1;
  }     
  if ((jogada == float(3.1)) && (tabuleiro[2][0] == 0)){
    tabuleiro[2][0] = donoJogada;
    return 1;
  }     
  if ((jogada == float(3.2)) && (tabuleiro[2][1] == 0)){
    tabuleiro[2][1] = donoJogada;
    return 1;
  }     
  if ((jogada == float(3.3)) && (tabuleiro[2][2] == 0)){
    tabuleiro[2][2] = donoJogada;
    return 1;
  }
  desenhaTabuleiro();     
  printf("\n**Jogada Invalida \n(Nota: A jogada ja pode ter sido feita)");
  return 0;
}

int jogadaPCAutomatizada(int soma){
  /* 
    Ele verifica se a soma de uma linha ou coluna equivale a 2 ou -2
  caso sim, lá é a posição para a proxima jogada pois o computador vai
  vencer caso seja 2, ou poderá perder se não jogar naquela casa caso 
  seja -2.
  */
  int i,j,z;
  int somaA,somaB;
  float jogada;
  for(j=0; j<3; j++){
    somaA= 0;
    somaB= 0;
    for(i=0; i<3; i++){
      somaA = somaA + tabuleiro[i][j];
      somaB = somaB + tabuleiro[j][i];
    }
    
    if(somaA == soma){
      for( z=0; z < 3; z++){
        if(tabuleiro[z][j] == 0)
          i = z;
      }                                                         
      jogada = (i+1) + ((j+1)*.10);                              
      verificaJogada(jogada,1);      
      return 1;
      }
    if(somaB == soma){             
      for( z=0; z < 3; z++){
        if(tabuleiro[j][z] == 0)
          i = z;
      }                             
      jogada = (j+1) + ((i+1)*.10);            
      verificaJogada(jogada,1);
      return 1;
      }      
  }
  
  somaA = tabuleiro[0][0] + tabuleiro[1][1] + tabuleiro [2][2];
  if(somaA == soma){
    
    for( z=0; z < 2; z++){
      if(tabuleiro[z][z] == 0)
        jogada = float(z + float((z+1)*0.10)+1);
    }
                  
    verificaJogada(jogada,1);
    return 1;    
  }  
  
  somaB = tabuleiro[0][2] + tabuleiro[1][1] + tabuleiro [2][0];   
  if(somaB == soma){
           
    if(tabuleiro[0][2] == 0)
      jogada = 1.3;
    if(tabuleiro[1][1] == 0)
      jogada = 2.2;
    if(tabuleiro[2][0] == 0)
      jogada = 3.1;
              
    verificaJogada(jogada,1);
    return 1;    
  }
  
  return 0;
}

void PCJoga(){
  /*
    Ele chama duas vezes o jogadaPCAutomatizada uma verificando se o pc
  está auma jogada da vitória ou se ele está a uma jogada da derrota, caso
  mão se encaixe nestas duas jogadas, ele procura uma jogada preparada, caso 
  não encontre informa erro de IA.
  */
  if( jogadaPCAutomatizada(2) != 0 ) 
    return;
  if( jogadaPCAutomatizada(-2) != 0 )
    return;
    
  switch(njogada){
    case 0:
      verificaJogada(1.1,1);
    break;
    case 2:
      if(tabuleiro[2][2] == 0)   
        verificaJogada(3.3,1);
      else
        verificaJogada(1.3,1);
    break;
    case 4:
      verificaJogada(3.1,1);   
    break;
    default:
      printf("Erro de IA por favor feche o programa CTRL+C e informe o erro");
    break;
  }
  printf("\nA jogada abaixo foi do pc");
}

int verificaDonoJogada(){
  /*
    método que verifica o dono da jogada baseado no lance da jogada
    Condições
      1 = jogador 1 (X)
      -1 = jogador 2 (O)
  */
  if((njogada % 2) == 0 )
    return 1;    
  else
    return -1;
}

void leJogada(){     
  /*
    Verifica o dono da jogada, lê a jogada , caso jogada válida aumenta contador
    de jogadas e desenha o tabuleiro, caso não continua a ler jogadas até a 
    existêncai de uma válida.
  */
  float jogada;
  int continuar=0;
  int donoJogada;
  int jogadaCorreta=0;
       
  donoJogada= verificaDonoJogada();     
  if((donoJogada == 1) && (gamePC == 1))
    PCJoga();
  else
    while( continuar == 0){
      printf("\nInforme a jogada:\n");
      scanf("%f",&jogada);
      continuar = verificaJogada(jogada,donoJogada);
    }

  njogada= njogada + 1;
       
  desenhaTabuleiro();
}

void jogar(){
  /*
    Fica verificando a condição de vitória, caso não tenha acontecido, continua 
  a ler as jogadas.Apos condição de vitória ter sido resolvida imprime resultado
  da partida.
  */
  int vitoria=0;
  while( verificaVitoria() == 0)
    {
      leJogada();  
    }
    
  vitoria = verificaVitoria();
  if(vitoria == 1){
    imagemVitoria(1);
    if(gamePC != 1)
      vitorias[0] = vitorias[0] + 1;
  }
  if(vitoria == 2){
    imagemVitoria(2);
    if(gamePC != 1)    
      vitorias[1] = vitorias[1] + 1;    
  }
  if(vitoria == 3){
    empate();             
    if(gamePC != 1){
      vitorias[0] = vitorias[0] + 0.5;
      vitorias[1] = vitorias[1] + 0.5;
    }
  }
}

void montaTabuleiro(){
   /*
     Zera as posições das jogadas do tabuleiro
     Zera o numero de jogadas feitas
     Desenha o tabuleiro
     Começa o jogo
   */
   zeraTabuleiro();
   njogada = 0;
   desenhaTabuleiro();
   jogar();
}

void preparePC(){
  gamePC = 1;
  montaTabuleiro();
  gamePC = 0;     
}

main(){
  int continuar = 1;
  int option;
  
  abertura();
    
  while(continuar ==1){
    option = inicio();
    switch (option){
      case 1:
        montaTabuleiro();
        break;
      case 2:
        preparePC();
        printf("");
        break;         
      case 3:
        placar();
        break;
      case 4:
        zeraPlacar();
        break;
      case 5:
        regras();
        break;
      case 6:
        continuar = 0;
        break;
      default:
        opcaoInvalida(option);
      break;
    }
  }     
}

Scripts recomendados

Também enche a memória, porém desta vez com processos

Números Primos

Jogo para adivinhar o numero

Calculadora

parse_args


  

Comentários
[1] Comentário enviado por davidsonpaulo em 21/09/2006 - 08:49h

Fala Marco,

Quanto a você não entender porque o ensino de lógica de programação em Engenharia Civil. Conhece algum engenheiro que trabalhe usando apenas papel, lapiseiras e réguas? Hoje em dia todos possuem no computador a principal ferramenta de trabalho, utilizando softwares de CAD que utilizam de linguagens de programação próprias, necessárias para traçar formas complexas, calcular valores de esforço e resistência e todo tipo de cálculo. Até as calculadoras científicas podem ser programadas, e um engenheiro que não souber fazer essa tarefa, embora consiga realizar o seu trabalho, vai ser um profissional de nível inferior, pode ter certeza.

A propósito, tenho um projeto que acredito que lhe interessará bastante, vou lhe enviar um email.

Abraços,

Davidson

[2] Comentário enviado por Raptor em 22/09/2006 - 23:23h

Amigo, desculpa a ignorância, mas como faço para executar?
Basta salvar como teste.cpp e executar em um terminal?
# teste.cpp
Somente isto?

[3] Comentário enviado por mar_tchello em 24/09/2006 - 18:36h

Ficou muito legal, mas o computador sempre inicia jogando em uma única posição.
Não seria complicado fazer um sorteio de posições, mas consequentemente ele deveria analizar todas as condições possiveis, ja que a posição é dinâmica.

[4] Comentário enviado por yetlinux em 28/09/2006 - 11:17h

Respondendo ao Raptor:

Tente $ g++ Teste.cpp -o Teste
depois $ ./Teste


[5] Comentário enviado por Raptor em 28/09/2006 - 15:56h

Olha só amigo yetlinux, apareceu esta mensagem:

bash: g++: command not found

[6] Comentário enviado por yetlinux em 02/10/2006 - 14:18h

Você precisa instalar o gcc no seu sistema. Depende da sua distro.

Se for RedHat-Like (Fedora, Conectiva) use o rpm com um pacote rpm.

Se for Debian-Like (Knoppix, Kurumin, Ubuntu), use dpkg/apt com pacotes .deb.
Use diretamente <b>$ apt-get install g++</b>

Se for Slackware-Like, use o installpkg com um pacote .tgz.


[7] Comentário enviado por Raptor em 07/10/2006 - 03:26h

Agora funcionou. Valeu.

[8] Comentário enviado por paulomar em 14/10/2006 - 09:19h

Cara!! show esse script, parabéns....Agora só para dar uma ajudinha para quem for compila-lo e executa-lo, têm que fazer so uma correção na Função
" int verificaJogada " os IF estão com a syntax assim :

if ((jogada == float (1.1)) && (tabuleiro[0][0] == 0)) ......

Têm que somente acrescentar dois parenteses entre o float ficando assim :

if ((jogada == (float) (1.1)) && (tabuleiro[0][0] == 0))

[9] Comentário enviado por strondy em 18/06/2008 - 09:36h

ae galera preciso do jogo da velha com as seguintes condiçoes

a) No início o programa deverá solicitar o nome
b) Também dever ser solicitado ao usuário quantas partidas deseja jogar, não permitir a entrada de
valores pares para a quantidade de partidas para que não ocorra o empate.
c) Cada jogador deverá informar a posição do tabuleiro que deseja jogar de forma intercalada.
Defina uma forma de representar cada posição do mesmo.
d) O jogador que começa a partida é que informou o nome primeiro, nas próximas rodadas quem
começa a partida deverá ser intercalado entre os dois jogadores.
e) Caso um jogador vença uma partida o programa deverá dizer quem foi, computar um ponto ao
vencedor e mostrar o placar geral das partidas.
f) Caso todas posições estejam preechidas a partida finalizará não computando pontos aos
jogadores.
g) A cada jogada deverá aparecer o tabuleiro com as peças atualizadas e o placar geral das partidas.
h) Caso o programa verifique que algum jogador não tem mais chance de vencer o outro adversário
deverá ser considerado final do Jogo.
h) No final do Jogo dar a mensagem de GAME OVER e mostrar quem foi o campeão e quantas
partidas foram disputadas.

alguem poderia me ajudar?
vlw

[10] Comentário enviado por strondy em 18/06/2008 - 09:37h

pode envia pro meu email ou post aki mesmo
meu email eh
[email protected]


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts