Universidade Federal de Minas Gerais
Instituto de Ciências Exatas
Departamento de Ciência da Computação

Algoritmos e Estruturas de Dados I

Jogo da Velha (tic-tac-toe) monolítico para exercícios

 

O programa abaixo joga (de maneira precária) o “jogo-da-velha” e tem o objetivo de servir de base para vários exercícios. O primeiro erro do programa é não verificar se houve empate, e este é um exercício: alterar o programa para considerar a ocorrência de empate.

 

#include <stdio.h>

#include <stdlib.h>

 

int main(int argc, char *argv[])

{

    printf("deseja iniciar? (s/n)");

    int resp=0;

    if(scanf("%c", &resp)!=1){

      printf("nao entendi, adeus!\n"); //scanf("%*[^\n]%*c")?;

      return 0;

    };

    int enter;

    scanf("%c", &enter);

    int compJoga;

    compJoga= !(resp=='s' ||  resp=='S');

    int t11=0, t12=0, t13=0;

    int t21=0, t22=0, t23=0;

    int t31=0, t32=0, t33=0;

    int linha, coluna, virgula;

    int ocupado;

    int preenchido;

    int ninguemGanhou;

    int fechouLinha1, fechouLinha2, fechouLinha3;

    int fechouCol1, fechouCol2, fechouCol3;

    int fechouDiagPrinc, fechouDiagSec;

    do{//laco para sucessivas rodadas do jogo

 

      if(compJoga){

          //computador pode ganhar? computador ->A

          printf("vez do computador(A)\n");

          if(      t11==0&&(t12=='A'&&t13=='A' || t21=='A'&&t31=='A' || t22=='A'&&t33=='A') ){

             t11='A';

          }else if(t12==0&&(t11=='A'&&t13=='A' || t22=='A'&&t32=='A')){

            t12='A';

          }else if(t13==0&&(t11=='A'&&t12=='A' || t23=='A'&&t33=='A' || t22=='A'&&t31=='A')){

            t13='A';

          }else if(t21==0&&(t22=='A'&&t23=='A' || t11=='A'&&t31=='A')){

            t21='A';

          }else if(t22==0&&(t21=='A'&&t23=='A' || t12=='A'&&t32=='A' ||

                            t11=='A'&&t33=='A' || t13=='A'&&t31=='A' )){

            t22='A';

          }else if(t23==0&&(t21=='A'&&t22=='A' || t13=='A'&&t33=='A')){

            t23='A';

          }else if(t31==0&&(t32=='A'&&t33=='A' || t11=='A'&&t21=='A' || t13=='A'&&t22=='A')){

            t31='A';

          }else if(t32==0&&(t31=='A'&&t33=='A' || t12=='A'&&t22=='A' )){

            t32='A';

          }else if(t33==0&&(t31=='A'&&t32=='A' || t13=='A'&&t23=='A' || t11=='A'&t22=='A' )){

            t33='A';

            // se o usuário pode ganhar então bloquear

          }else if(t11==0&&(t12=='B'&&t13=='B' || t21=='B'&&t31=='B' || t22=='B'&&t33=='B') ){

             t11='A';

          }else if(t12==0&&(t11=='B'&&t13=='B' || t22=='B'&&t32=='B')){

            t12='A';

          }else if(t13==0&&(t11=='B'&&t12=='B' || t23=='B'&&t33=='B' || t22=='B'&&t31=='B')){

            t13='A';

          }else if(t21==0&&(t22=='B'&&t23=='B' || t11=='B'&&t31=='B')){

            t21='A';

          }else if(t22==0&&(t21=='B'&&t23=='B' || t12=='B'&&t32=='B' ||

                            t11=='B'&&t33=='B' || t13=='B'&&t31=='B' )){

            t22='A';

          }else if(t23==0&&(t21=='B'&&t22=='B' || t13=='B'&&t33=='B')){

            t23='A';

          }else if(t31==0&&(t32=='B'&&t33=='B' || t11=='B'&&t21=='B' || t13=='B'&&t22=='B')){

            t31='A';

          }else if(t32==0&&(t31=='B'&&t33=='B' || t12=='B'&&t22=='B' )){

            t32='A';

          }else if(t33==0&&(t31=='B'&&t32=='B' || t13=='B'&&t23=='B' || t11=='B'&t22=='B' )){

            t33='A';

          }else{

             //verificar pela ordem: centro->canto->lado

             if(t22==0)t22='A';

             else if(t11==0) t11='A';

             else if(t13==0) t13='A';

             else if(t31==0) t31='A';

             else if(t33==0) t33='A';

             else if(t12==0) t12='A';

             else if(t21==0) t21='A';

             else if(t23==0) t23='A';

             else if(t32==0) t32='A';

             else printf("algo de podre I...\n");

 

          };

      }else{

        do{//laco garante usuario ocupar uma posicao do tabuleiro

            do{ //laco  garante uma leitura

              printf("Entre com linha (1 a 3) virgula coluna (1 a 3):");

              scanf("%d,%d", &linha, &coluna);

              scanf("%c", &enter);

              printf("Sua jogada (B) foi linha:%d e coluna:%d\n", linha, coluna);

              if(linha<1 || linha>3) printf("linha deve estar entre 1 e 3\n");

              if(coluna<1 || coluna>3) printf("coluna deve estar entre 1 e 3\n");

            }while(linha<1||linha>3||coluna<1||coluna>3);

            ocupado=0;

            switch(linha*10+coluna){

              case 11: if(t11==0) t11='B'; else ocupado=1; break;

              case 12: if(t12==0) t12='B'; else ocupado=1; break;

              case 13: if(t13==0) t13='B'; else ocupado=1; break;

              case 21: if(t21==0) t21='B'; else ocupado=1; break;

              case 22: if(t22==0) t22='B'; else ocupado=1; break;

              case 23: if(t23==0) t23='B'; else ocupado=1; break;

              case 31: if(t31==0) t31='B'; else ocupado=1; break;

              case 32: if(t32==0) t32='B'; else ocupado=1; break;

              case 33: if(t33==0) t33='B'; else ocupado=1; break;

              default: printf("Algo de podre II\n"); return 0;

            };

            if(ocupado) printf("posicao ja ocupada, tente outra!\n");

        }while(ocupado);

 

 

      };

      //verifica se alguém ganhou

      fechouLinha1=t11!=0&&t11==t12&&t12==t13;

      fechouLinha2=t21!=0&&t21==t22&&t22==t23;

      fechouLinha3=t31!=0&&t31==t32&&t32==t33;

      fechouCol1=t11!=0&&t11==t21&&t21==t31;

      fechouCol2=t12!=0&&t12==t22&&t22==t32;

      fechouCol3=t13!=0&&t13==t23&&t23==t33;

      fechouDiagPrinc=t11!=0&&t11==t22&&t22==t33;

      fechouDiagSec=t13!=0&&t13==t22&&t22==t31;

      ninguemGanhou=!(fechouLinha1 || fechouLinha2 || fechouLinha3 ||

          fechouCol1 || fechouCol2 || fechouCol3 ||

          fechouDiagPrinc ||fechouDiagSec);

      compJoga=!compJoga;

      //imprime tabuleiro

      printf("%c|%c|%c\n", t11?t11:' ',t12?t12:' ',t13?t13:' ');

      printf("------\n");

      printf("%c|%c|%c\n", t21?t21:' ',t22?t22:' ',t23?t23:' ');

      printf("------\n");

      printf("%c|%c|%c\n", t31?t31:' ',t32?t32:' ',t33?t33:' ');

      preenchido=t11!=0&&t12!=0&&t13!=0&&t21!=0&&t22!=0&&t23!=0&&t31!=0&&t32!=0&&t33!=0;

    }while(ninguemGanhou && !preenchido);

    if(compJoga)

      printf("Voce ganhou, parabens\n");

    else

      printf("Voce perdeu...\n");

 

 

  system("PAUSE");

  return 0;

}

 

Exercícios:

1)      Conforme foi citado acima, um “defeito” do programa é não verificar se houve empate. Altere o programa de forma a tratar a situação de empate.

2)      Utilize o programa para “testar de maneira exploratória” se ele apresenta alguma falha.

3)      Altere o programa para considerar como entrada apenas um dígito (ao invés de linha virgula coluna) os dígitos 0,1,2,3,4,5,6,7,8  deverão corresponder a 1,1; 1,2; 1,3; 2,1; 2,2; 2,3; 3,1; 3,2 e 3,3.

4)      Após a discussão do material de arranjos, alterar a representação do tabuleiro de 9 variáveis para arranjo de char.

5)      Após a discussão do material de arranjos alterar a representação do tabuleiro de 9 variáveis para arranjo de “enum”; utilize enumeração para codificar os valores ( enum posicao? / enum unidade? / enum celula? / enum casa? / enum <nome> {LIVRE, CRUZ,. BOLA};  p.ex. enum casa tabuleiro[9];

6)      Após a discussão do material de função, alterar o programa para definir funções e utilizar somente chamadas de funções na função “main”.