Jump to content
vascor1

Jogo da Forca (duvida)

Recommended Posts

vascor1

Boas pessoal, eu sou novo aqui no forum e na area de programaçao.

Venho-vos hoje pedir ajuda num trabalho que eu tenho para a escola.

O objectivo é criar um jogo da forca, apenas posso usar a funçao main e as bibliotecas mais simples (string.h,stdio..)

Eu tenho feito este trabalho aos poucos, mas nunca conseguindo concluir, pois sempre que resolvo um problema, outro novo ou ja resolvido aparece.

A base do jogo em si acho que esta concluida, mas as partes das vidas e para trocar os _ pelas letras as vezes nao querem funcionar.

Já cheguei ao ponto onde consegui por tudo a funcionar, mas neste momento o jogo ja nao quer terminar quando acerto todas as letras.

Ao tentar resolver este problema fui tentando outras maneiras, chegando ao ponto que já nao avisa quando as letras estao repetidas nem quando acabam as vidas...

Mas bem, vou postar aqui o codigo a que cheguei e se me puderem ajudar agradeço. =D

#include <stdio.h>
#include <string.h>

int main (void) {

char frase[31], letras[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int tamanho = 0, certas=0, vidas = 20 ,i ,igual = 0, antes,j;
char tentativa[20];

//pedir a frase
printf("Introduza a frase a adivinhar (max 31 letras): ");
gets(frase);

tamanho = strlen(frase);
printf("\n\nFrase com %i letras: ", tamanho);

//pedir letras
while (certas < tamanho) {

for ( i = 0 ; i < vidas ; i++){

//mostrar espaços
printf("\n");
for( j = 0; j < tamanho; j++) {

if ( frase[j] == 32 )
letras[j] = 2;

if (letras[j] == 1 )
printf("%c",frase[j]);
else
if (letras[j] == 2)
printf(" ");
else
printf("-");

}

printf("\nTentativa %i", i+1);
printf("\nLetras corretas: %i", certas);
printf("\nInsira uma letra: ");
scanf("%c", &tentativa[i]);
getchar();

antes = certas;

for (j = 0; j < tamanho; j++) {

if (letras[j] == 1) {
if (tentativa[i] == frase[j]) {
igual = 1;
break;
}
continue;
}

if (tentativa[i] == frase[j]) {
letras[j] = 1;
certas++;
}
}


}

//vidas
if (antes == certas && igual == 0) {
vidas--;
if (vidas = 0)
break;
}
else
if (igual == 1)
printf("Letra repetida! Tente outra vez!");
}
//fim do jogo
if (vidas == 0)
printf("Acabaram-se as tentativas!\nA frase era: %s", frase);
else
printf("\nAcertou!\nA frase era: %s", frase);

return 0;

}

Edited by thoga31
Tags code + GeSHi

Share this post


Link to post
Share on other sites
vascor1

Boas HappyHippyHippo, desde já obrigado pela resposta.

O que queres dizer com "perdido"? está mal organizado ou a logica está incorreta?

Eu vi a tua solução que apresentaste, mas para ser sincero não percebi quase nada, teria secalhar que perder mais tempo a olhar para ela com mais calma, pois muito do que está lá ainda nao dei, ou se dei fazemos de outra maneira.

Mas viste algum erro no meu código? pelo menos algo ligado à forma de escrever ou das funções usadas?

Share this post


Link to post
Share on other sites
HappyHippyHippo

O que queres dizer com "perdido"? está mal organizado ou a logica está incorreta?

nem uma nem outra. dá a sensação que o teu código não é simples quando poderia ser

eu não disse que estava errado, se bem que está e já vou dizer porque, simplesmente acho que poderia ser feito de uma forma bem mais simples. como a maneira apresentada no código que te mostrei com o link

o teu problema é simples e vais perceber com dois testes:

- tenta jogar em que a frase a adivinhar é "a b"

- agora tenta jogar mas a frase é : "ab"

qual dos dois jogos é que acabou e qual é que não acabou ?

qual a diferença entre eles ?

--------------------------

ps : já agora, deixo então aqui o código comentado para ver se percebes dessa forma

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

/* tamanho máximo de uma palavra no dicionário */
#define MAX_WORD_SIZE 32

int main(int argc, char** argv) {
 /* dicionário : lista de palavras possíveis a serem descobertas */
 char * dictionary[] = {"casa",
                        "quadro",
                        "heptagono",
                        "aviao",
                        "cao"};

 char hint[MAX_WORD_SIZE], // array usado para apresentar a pista
                           // a pista será o conjunto de tracos e as letras já
                           // adivinhadas nas posições correctas da palavra a
                           // adivinhar
      choise = 0; // caracter usado para guardar a escolha de letra do jogador
 int word = 0, // índice da palavra a adivinhar no dicionário
     size = 0, // tamanho da letra a adivinhar
     hits = 0, // número de letras já descobertas
     i = 0;    // variável auxiliar de iteração

 /* inicializar o gerador de números aleatórios */
 srand(time(NULL));

 /* escolher uma palavra do dicionário aleatoriamente */
 word = rand() % (sizeof(dictionary) / sizeof(char *));

 /* guardar o tamanho da palavra a ser adivinhada */
 size = strlen(dictionary[word]);

 /* ciclo de escrita dos traços na string pista */
 for (i = 0; i < size; i++)
   hint[i] = '-';

 /* finalizar a string pista */
 hint[i] = 0;

 /* apresentar a pista */
 printf("Palavra : %s\n", hint);

 /* ciclo do jogo */
 while (hits != size) {
   /* pedido de uma letra */
   printf("Digite uma letra : ");

   /* forçar a saida dos dados do printf porque este não tem um '\n' */
   fflush(stdout);

   /* leitura do teclado pela letra escolhida */
   if (scanf("%c", &choise) == 1) {

     /* ciclo de validação da letra escolhida */
     for (i = 0; i < size; i++) {

       /* verificar se na palavra a ser adivinhada, na posição iterada,
        * encontrasse a letra que o jogador inseriu */
       if (dictionary[word][i] == choise) {
         /* apresentar a letra na string pista */
         hint[i] = choise;

         /* incrementar o número de letras já descobertas */
         hits++;
       }
     }

     /* apresentar a pista */
     printf("Palavra : %s\n", hint);
   }

   /* limpeza - limpar o buffer de leitura do teclado */
   while (getchar() != '\n') /* void */;
 }

 /* apresentar a mensagem de sucesso na descoberta da palavra */
 printf("Parabens ... adivinhou a palavra\n");

 return 0;
}

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Sim, com ele comentado percebo bastante melhor =D mesmo existindo varias coisas que nao posso usar por nao ter aprendido em aula =S

Mas olha, tentei fazer o que disseste e , ou eu sou muito burro =D, ou nao percebi o que querias que fizesse, nenhum deles acabou. vou mandar print.

2uzw6xf.jpg

e

1533bf9.jpg

Share this post


Link to post
Share on other sites
HappyHippyHippo

faz-me um favor ... altera esta linha :

printf("\nLetras corretas: %d de %d", certas, tamanho); // <----

diz-me agora o que te apareceu


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Quando uso a palavra "ab" ele diz 0 de 2 e nao termina, acho que é porque me falta um break; nalgum sitio nao?

Quando uso o "a b" ele ja diz 0 de 3 <-- era isto que te referias? =D o espaço conta como letra?

Enquanto nao chegava a nenhuma conclusao,.. fui refazer o codigo do zero com base em algum do teu codigo (espero que nao te importes =D, nao esta assim tao parecido)

Estou a fazer a parte das vidas, mas ate agora tudo bem, ele funciona se nao passar do maximo de tentativas que lhe dei =D e termina! =P

vou só desenvolvelo mais um bocado e ja posto para veres o que achas e se aprendi alguma coisa =D

Share this post


Link to post
Share on other sites
vascor1

Boas, e já cá estou com mais duvidas =D.

Já terminei o codigo, mas existem uns pequenos problemas.

1 - Quando coloco mais que uma letra como tentativa, por exemplo 3, ele le a primeira, o enter, e a ultima.

2- As letras repetidas estao a ser mal contadas em certas situaçoes. por ex, quando colocamos a 1ª letra e ele diz que esta repetida (nao existindo nenhuma anteriormente colocada ou outra igual na frase)

se pudesses dar uma olhadela no codigo e dizeres o que achas e dar algumas dicas para como resolver estes problemas ficava bestante agradecido =D

#include <stdio.h>
#include <string.h>

int main(void)
{

   char frase[31], pista[31], escolha, usadas[26];
   int i, j, tamanho, certas = 0, vidas = 20, tentativas = 20, antes, repetida = 0;

//escolher a frase
   printf("Introduza a frase a adivinhar(ate 31 letras): ");
   gets(frase);

//limpar ecran
   system("cls");

//tamanho da palavra
   tamanho = strlen(frase);

//pista inicial
   for (i = 0; i < tamanho; i++) {
if (frase[i] != ' ')
    pista[i] = '_';
else if (frase[i] == ' ')
    pista[i] = ' ';

   }

//apresentar tamanho
   printf("Frase com %i letras: n", tamanho);

//Jogo
   while (certas != tamanho) {

for (tentativas = 0; tentativas < 20; tentativas++) {

//apresentar pista
    printf("n%sn", pista);

//pedir letras
    printf("nTentativa %i", tentativas + 1);
    printf("nLetras corretas: %i", certas);
    printf("nVidas Restantes: %i", vidas);
    printf("nLetras Repetidas: %i", repetida);
    printf("nInsira uma letra: ");

    scanf("%c", &escolha);
    getchar();

//verificar as escolhas
    for (i = 0; i < tamanho; i++) {
	for (j = 0; j < 26; j++) {
	    if (escolha == usadas[j]) {
		repetida++;
		break;
	    }
	}

	if (frase[i] == escolha) {
	    pista[i] = escolha;
	    usadas[i] = escolha;
	    certas++;
	}
    }



//vidas
    antes = certas;

    if (antes == certas && repetida == 0) {
	vidas--;
	if (vidas == 0) {
	    printf("Acabaram-se as tentativas!");
	    printf("nA frase era: %s", frase);
	    break;
	}
    }
//letra repetida
    if (repetida != 0)
	printf("Letra repetida! Tente outra vez!n");

//fim
    if (certas == tamanho) {
	printf("nGanhou!!!");
	printf("nA frase era: %s", frase);
	break;
    }
}
   }
   return 0;
}

Edited by Rui Carlos
Formatação da mensagem.

Share this post


Link to post
Share on other sites
HappyHippyHippo

tens vários problemas ...

o primeiro de todos é o scanf.

para te simplificar a vida, usa este código :

https://www.portugal-a-programar.pt/topic/63688-c-codigo-auxiliar-para-iniciantes-leitura-teclado-linked-list/?do=findComment?comment=535849

segundo: não resolveste o problema dos espaços ...

terceiro (e quando vi este deixei de procurar por mais ...) :

imagina que insiro como 1ª opção a letra 'a' e a 2ª opção a mesma letra 'a' ... repetida ...

vamos ver o que acontece no código na segunda opção :

for (i = 0; i < tamanho; i++) { // entro no cíclo
 for (j = 0; j < 26; j++) {    // entro no cíclo
   if (escolha == usadas[j]) { // yep ... o 'a' já foi usado ...
     repetida++;               // repetidas passa a ter o valor de 1
     break;                    // vamos saltar fora do ciclo for interno 
   }
 }
 // ...
}
// ...
if (antes == certas && repetida == 0) { // repetidas tem o valor de 0 ? nop ... vamos tirar uma vida ...
 vidas--;
 // ...
}

mas vamos ver o que acontece quando insiro a terceira opção (por exemplo 'r' .. não interessa ...)

vamos ver o que acontece no código na segunda opção :

for (i = 0; i < tamanho; i++) { // entro no cíclo
 for (j = 0; j < 26; j++) {    // entro no cíclo
   if (escolha == usadas[j]) { // nop ..
     repetida++;
     break;
   }
 } // faz o ciclo sem problemas ...
 // ...
}
// ...
if (antes == certas && repetida == 0) { // repetidas tem o valor de 0 ? NAO !!!! ... vamos tirar uma vida ...
 vidas--;
 // ...
}

------------------------------------------

queres uma dica então ? aqui vai ...

imagina que a palavra reservada continue não existe e a palavra reservada break só é usada em estruturas de controlo switch, para "separar" todos os casos descritos

enquanto não estives habituado no que toca a fluxo de execução, esta é uma das tuas regras de ouro


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Bem,

--Já corrigi o erro dos espaços, fiz um for em que sempre que encontra-se um ' ' na frase reduzia o tamanho por 1.

--Para corrigir o erro dos repetidos o que fiz foi no final das verificações defeni-o de volta para 0.

--Ele continua a dar o erro da letra repetida logo a 1ª tentativa, mas suponho que seja por causa do scanf.

nao percebi muito bem como iria usar o que estava naquele link, mas nao posso adicionar bibliotecas que nao tenha dado em aula =S

o que fiz foi perguntar a um colega meu que me disse que para limpar corretamente a buffer do teclado tinha que colocar o getchar() dentro deum do while, está isso correto? eu pessoalmente nao percebi como é que isso nao me iria limpar a primeira letra colocada e nao consigo polo a funcionar.

consegues ajudar de alguma maneira em que apenas use +/- o que já tenho no codigo? eu ainda nao aprendi muito de C, estamos mesmo no inicio

desculpa la o incomodo, eu sei que sou bue chato =S

Share this post


Link to post
Share on other sites
HappyHippyHippo

o link não é um biblioteca, é simplesmente um conjunto de código que podes usar ...

afinal, usas o libc e não reclamas de o usar

scanf(...);
while (getchar() != '\n') /* void */;

Edited by HappyHippyHippo

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Boa tarde. o codigo agora esta assim

#include 
#include 

int main (void) {

char frase[31], pista[31], escolha, usadas[26];
int i, j, tamanho, certas=0, vidas=20, tentativas = 20, antes, repetida=0;

//escolher a frase
printf("Introduza a frase a adivinhar(ate 31 letras): ");
gets(frase);

//limpar ecran
system("cls");

//tamanho da palavra
tamanho = strlen(frase);
for (i = 0; i< tamanho; i++) {
if (frase[i] == ' ')
tamanho--;
}

//pista inicial
for (i = 0; i < strlen(frase); i++) {
if (frase[i] != ' ')
pista[i] = '_';
else
if (frase[i] == ' ')
pista[i] = ' ';

}

//apresentar tamanho
printf("Frase com %i letras: \n", tamanho);

//Jogo
while (certas != tamanho) {

for (tentativas = 0; tentativas < 20; tentativas++) {

//apresentar pista
printf("\n%s\n", pista);

//pedir letras
printf("\nTentativa %i", tentativas+1);
printf("\nLetras corretas: %i", certas);
printf("\nVidas Restantes: %i", vidas);
printf("\nLetras Repetidas: %i", repetida);
printf("\nInsira uma letra: ");
scanf("%c", &escolha);

//limpar buffer
while (getchar() != '\n');

//verificar as escolhas

antes = certas;

for( i = 0; i < strlen(frase); i++) {

if(frase[i] == pista[i]) {
if(escolha == usadas[i]) {
repetida++;
break;
}
continue;
}

if( escolha == frase[i] ) {
pista[i] = escolha;
certas++;
}

}

//vidas
if (antes == certas && repetida == 0) {
vidas--;
if (vidas == 0) {
break;
}
}
else
if (repetida != 0) { //letra repetida
printf("\nLetra repetida!(%i) Tente outra vez!\n", repetida);
}






repetida = 0;
}





}

//fim
if (vidas==0)
printf("Acabaram as tentativas!\nA frase era: %s", frase);
else
if (certas == tamanho){
printf("\nGanhou!!!");
printf("\nA frase era: %s", frase);


}



return 0;
}

Edited by thoga31
Tags code + GeSHi

Share this post


Link to post
Share on other sites
HappyHippyHippo
for( i = 0; i < strlen(frase); i++) {
 if(frase[i] == pista[i]) {
   if(escolha == usadas[i]) { // <---- isto não faz sentido nenhum porque ponta lhe pegues ...


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Pois, eu tinha isso diferente,como estava no anterior, só que deram me esse codigo e tentei para ver o que dava e acabei por nao trocar para o original.

Como sugeres que fassa? podes dar alguma sugestao nem que seja em pseudo codigo sff? ontem fritei o cerebro a volta desse problema e nao o consegui resolver =S

Share this post


Link to post
Share on other sites
HappyHippyHippo

andes de mais, eu já te disse para não usares o continue e o break sem saberes exactamente o que estás a fazer ...

depois, já te disseram o que fazer :

comenta o código a dizer o que faz, se estiver correcto, o que estiveres a ler irá fazer sentido, caso contrário, vai parecer um absurdo


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
vascor1

Boas, fiz o que me disseste, comentei o codigo e tirei os continues e breaks todos.

Mas mesmo assim ha uma coisa que nao estou a pereber. Qualquer que seja a letra que coloque em primeiro lugar, ele dizme que esta repetida,...

vê lá se o codigo nao te parece certo, eu comentei e nao era suposto a primeira dar repetida,.. porque a usadas está vazio ...

for( i = 0; i < strlen(frase); i++) {

for (j = 0; j < strlen(frase); j++) {

if(escolha == usadas[j]) {
repetida++;
}
}

if( escolha == frase[i] && repetida == 0 ) {
pista[i] = escolha;
usadas[i] = escolha;
certas++;
}

}

já agora, como defino para o codigo que aparece na janela code seja em C??

Edited by thoga31
GeSHi

Share this post


Link to post
Share on other sites
vascor1

hm,.. esclareceme só uma duvida,.. ele só irá fazer o que está fora do ciclo interior depois de o concluir neh?

senao podia ser que ele identificava a mesma letra n vezes (n = tamanho da palavra) e a primeira vez contava certa, mas as outras ja estariam repetidas,.. ou seja, se n = 3, colocava-se uma letra, ele ia ver se ja tinha sido usada, como nao, adicionava-a e quando voltasse a correr o ciclo iria ver que ja tinha sido usada, por isso dava 2 repetidas,..

vou ver se é isso, exprimentar trocar os ciclos ou assim,.. que achas? estou a ficar doido de tanto tempo que ja passei a volta deste prob?

Edited by vascor1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.