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”.