jogo da forca em C!

nandoice

Power Member
Boas!
Ando a tentar fazer o jogo da forca em C, nao sei se conhecem, qualquer coisa parecido com isto: http://guida.querido.net/jogos/forca/animais.htm

E como se tem de trabalhar com caracteres nao sei bem como vereficar se a palavra foi inserida e se é valida do genero vereficar se contem numeros por exemplo(0 a 9) e como depois substituir por '_' se algum puder ajudar desde ja agradeco.
Cumps
 
Última edição:
o que tu pretendes fazer nao é dificil, armazenas a palavar que é suposto ser descoberta num vector do genero, char palavra[]="ovelha"; e depois vais comparando o input do utilizador com cada posiçao do vector .
 
mas pode-se fazer char palavra="1234567890" e comparar?

podes compara um vector com outro e ver se sao iguais, mas esse nao é o teu objectivo na forca.
O algoritmo a meu ver para fazeres a forca era o seguinte:
-tinhas uma variavel que contava as letras que ja tinham saido correctas
-Com um ciclo while percorrias o vector posiçao a posiçao e comparavas com a letra que o user introduziu.

Nao podes fazer char palavra="254246326", pk isto nao tas a definir um vector de chars, tas antes a dizer que a palvra é uma variavel do tipo char e tas a quer efiar la uma string.
No exemplo que eu te dei char palavra[]="asdasdadas" as chavetas sem nada significa que o compilador vai ter que calcular o numero de posiçoes que o vector vai ter. Neste caso sao 10, por isso vai da posiçao 0-8(caracteres da string) e a posiçao 9 é o caracter '\0' que indica fim de string.
 
eu tenho isto pra ja

while (palavra!='\0')
{
printf("Palavra Invalida!!\n");

printf("\nInsira a palavra: ");
scanf("%c", &palavra);
}

a unica coisa que faz é vereficar se a palavra foi inserida!
tambem ja tratei da parte de substituit a palavra inserida por "_"

agora nesse ciclo falas-me de inserir strings? mais crio um array com numeros?
 
Mas dis-me uma coisa, queres que o user diga logo qual a palavra correcta sem primeiro fazer tentativas letra a letra?

while (palavra!='\0')
{
printf("Palavra Invalida!!\n");

printf("\nInsira a palavra: ");
scanf("%c", &palavra);
}
Este codigo nao tem grande sentido tu queres é verificar se palavra[x]=!='\o' (x-posiçao no vector) e nao vais esvrever nada nesse vector porque ele so serve de comparaçao. Tens é de cria outra variavel por exemplo, char ch;
e fazes uma coisa deste genero:


int i=0;
char ch; /* serve para guardar a letra que o user vai inserir */
char palavra[]="laranja";
while(palavra!='\0')
{
printf("introduza a letra: ");
scanf("%c",&ch);
if(palavra==ch)
(faz qualquer coisa);
i++; /* incremento o contador de posiçao */
}

Podes usar uma coisa deste genero para percorrer o vector e para compar letra a letra

Edit: uma string pode ser so de letras ou com numeros tb o que define uma string sao as as aspas, umas string é sempre delimitada por " ". Axo que ainda nao dominas muito bem a sintaxe do c. Tenta ler um bocado primeiro antes de passares ja para a programaçao, assim ficas com mais conhecimento como funcionam os ciclos e os vectores por exemplo.
Mas eu nao me importo de te continuar a tirar a tirar duvidas!!!
 
Última edição:
é estupido neh, mas o prof quer assim! estou a fazer melhoria a cadeira...

"Jogo da Forca
Implemente o jogo da forca. Nesta implementac~ao, o programa deve pedir
inicialmente a frase \misterio" com que vai jogar. Depois, mostra-a na forma
de um mapa com a posic~aoo das letras em relac~ao aos espacos.
Em cada uma das 6 tentativas (este numero pode ser variavel), o jogador
vai fornecer uma letra que, caso exista na frase \misterio", sera substituda
no mapa. No caso de n~ao existir, deve ser apresentada, em todas as jogadas
posteriores, numa zona de letras ja usadas.
Como resultado nal, o computador deve mostar sempre a frase \misterio",
indicando se o Jogador conseguiu descobrir todas as letras, ou se perdeu por ter
esgotado as tentativas."

tens aqui a prova, temos de inserir a palavra e depois adivinha-la! eu perguntei se podia fazer com ficheiros mas ele disse que la mais para a frente porque eu ja programei e ha la pessoal qeu ainda nao.
 
algoritmo possivel:

ter 2 arrays :
-um array key[]="hello"
-um segundo com a mesma dimensao do 1º mas este por preencher (ex: forfill[]="_ _ _ _ ")


1- mostras o array forfill[] no output

2- mandas o user inserir uma letra

3- percorres o array 'key' comparando o valor de cada posicao com a letra inserida pelo user.
Caso seja igual registas essa posicao para poderes idexar ao array 'forfill' e colocares la a letra por ele inserida.

4- repetir 1,2,3 (ciclo) ate acabar o numero de tentivas

o codigo fazes tu para aprenderes :P

abrc
 
Última edição:
while (palavra!='\0')

para se vereficar se a palavra foi inserida isto basta, tu dizes para percorrer um a um a procura de caracteres ou numeros que nao correspondam a palavra...

e se char s[4] = "Ola";
é o mesmo que
char s[4] = {'O', 'l', 'a', '\0'};

posso fazer char num[10]="0123456789" ???

eu tambem li que se pode fazer atraves da tabela Asci!
 
Última edição:
O algoritmo do machu era o que eu tinha em mente. Faz como ele disse.
Nao ha problema nenhum em fazeres char num[10]="0123456789" é a mesma coisa que fazeres
char num[10]={'0','1','2',........,'\0'} '1' é diferente de 1 o primeiro é um caracter e o segundo é um inteiro.
Axo que ainda nao percebeste bem o conceito do algoritmo.
Tu nao vais agarrar numa palavra inteira e comparala com a que o user vai introduzir, pk ele vai dando letras, nao a palavra toda, por isso tu so precisas de verificar se a letra que ele introduziu se encontra na palavra que foi definida se foi enontrada retornas por exemlo a__a__ no caso de alface e por ai adiante. tas a perceber? ou entao sou eu que nao tou a perceber a tua duvida
 
Última edição:
podes

ascii ja tu usas...nao percebi isso de fazeres atraves da tabela ascii..usar hexadecimal? decimal?

hexadecimal
0x00 = '\0' = 0 ( caracter terminador)
0x20 = " " (espaco)
0x30 = "0"
0x31= "1"

Código:
//exemplo : array bidimensional 5 linhas por 6 colunas:
unsigned char teste[5][6] = {
	
    {' ', '-', '.', 0x30, 0},  // 0 ou '\0' ou 0x00
    {',', ';', ':', 0x31 ,'\0'},
    {'a', 'b', 'c', '2', 0x00},
    {"jkl5"},
    {"wxyz9"}
};

se reparares fazeres {"jkl5"}={'j','k','l','5',0,0} e {"wxyz9"} = {'w','x','y','z','9',0} ele mete automaticamente o caracter terminador porque reservaste espaço suficiente (6 colunas)...se reservares 5 colunas ele nao te mete o caracter terminador no array {"wxyz9"} o que nao é bom porque ficas sem saber onde acaba o array caso pretendas percorrelo ate ao fim . Onde é que fica o fim neste caso? É até aparecer o proximo caracter terminador na memoria.

mas se fizeres teste[]="0123456789" sem definires o tamanho ele mete sempre o caracter terminador no fim (se nao me engano).

abrc
 
Última edição:
pois experimentei desse modo nao da pois toma os numeros como caracteres...

eu li que existe um determinado codigo de comparacao atraves da tabela asci, tipo de 0 a 9 existe um tipo de caracteres que faz a comparacao desses numeros... ja consegui substituir a palavras por _ agora vou fazer a parte das tentativas em que inserimos uma letra. so essa parte de fazer comparacao da palavra com os numeros é que nao estou bem a ver como irei fazer talvez criar uma array e inserir os numeros e corre-los um a um?
 
Observa a tabela ascii:

0 é diferente de "0"

ou seja
"0"+"1" = 48 +49 = 97 (decimal)
"0"+1= "1" = 49 (decimal)
0+1 = 1 (decimal)

tens de ter atencao com que valores ascii estas a trabalhar

char x[4]={0,1,43,9};

x[0]= 0 (decimal) -> caracter 'null'
x[1]= 1 (decimal) -> caracter 'SOH'
x[2]= 43 (decimal) -> caracter '+'
x[3]= 9 (decimal) -> caracter 'TAB'

x[3]-x[1]= 9-1 = 8 (decimal) -> caracter 'backspace'
x[3]+x[2]= 9+43 = 52 (decimal) -> caracter '4'

char y[]="12439";

y[0]= '0' = 48 (decimal)
y[1]= '1' = 49 (decimal)
y[2]= '2' = 50 (decimal)
y[3]= '4' = 52 (decimal)
y[4]= '3' = 51 (decimal)
y[5]= '9' = 57 (decimal)

y[5]-y[1]= 57-49 = 8 (decimal) -> caracter 'backspace'
y[5]+y[2]= 57+50 = 107 (decimal ) -> caracter 'k'

comparacao da palavra com os numeros? nao percebo o que queres dizer mas acho que estas a baralhar!

Um maximo de 256 tentativas (0-255) chega para esse jogo (limite maximo para um char sao 8 bits )

deves ter:
char max_tentativas = 15; //pode ir ate 255 a contar com o 0
char tentativas = 0;

1-tu inseres a palavra e gravas num array 'key'.
2- a seguir mandas o user inserir um caracter.
3- comparas o caracter inserido ('h' por exemplo) com o valor contido em cada indice do array 'key'. Encontrou o 'h' na 1ª posicao do array (indice 0) entao fazes forfill[0]="h";

verificas se ele acertou (acerta quando todas as posicoes de 'forfill' sao iguais as posicoes de 'key')
Se acertou terminas o ciclo (fim)
Se nao, Incrementas a variavel 'tentativas' e testas-a.
Se esta for igual a 'max_tentativas' terminas o ciclo (fim)

4-repetes 2,3 enquanto nao acabarem as tentativas ou ele nao acertar

Pensar no algoritmo é o mais dificil...transpôr para codigo só com pratica e muitos erros!

abrc
 
Última edição:
estas a usar a tabela ascii correcto, nao percebes os numeros com palavras é no inicio quano inseres uma palavra para o jogo, não é mt corrector inserires "fernand3" pois tem um numero a questao é vereficar se no inicio a palavra é valida! (tinha era uma validacao destas atravas da tabela ascii nao implica que faca por la)...
percebes-te agora?

ja tenho o programa um pouco feito mas gostava de fazer a validacao no inicio, contava mais pra nota!

ja agora o que faz mesmo o "forfill", nao percebi bem?
 
Para validar tens ver se cada valor em cada posicao do array 'key' é letra ...ser letra é estar entre 65 e 90 na tabela ascii (maiusculas) e 97 a 122 para minusculas ...podes considerar tambem validos outros caracteres isolados (exemplo : 'ã' =132 )

"A" = 65 (ascii/decimal)
"a" = 97 (ascii/decimal)

exemplo:
if ( (key[0]>=65 && key[0]<="Z") || (key[0]>="a" && key[0]<=122) || key[0]==132 )
//valid
else
//not valid

forfill é apenas um exemplo ( primeiro post que fiz na thread)

forfill[]="_ _ _ _ _"
ou
forfill[]=" ***** "

é o array que mostras ao utilizador ...ele acerta uma letra...preenches a letra no array e mostras. O aspecto fica por exemplo se ele acertar no "a":
" _ a _ _ a "

abrc
 
Boas, na minha opinião acho que complicaram em demasia todo o problema! Eu também tive como trabalho fazer o jogo da forca e podes implementa-lo de forma simples. Qt à verificação da palavra que o utilizador inseres, concordo com o machu, mas, ao invés de comparares apenas a primeira letra, fazeres um ciclo for que corre a palavra toda e verifica se cada caracter está entre os ranges das letras do alfabeto ("A" e "Z", "a" e "z"). Ora:
while(palavra == '\0' )
o utilizador insere a palavra;
for (i=0;i<strlen(palavra);i++) //strlen é a dimensao da palavra introduzida
if (!((palavra >= "A" && palavra <="Z") || (palavra >= "A" && palavra <="Z")))
//a condicao é verdadeira caso ela NÃO esteja nos ranges - ! (NOT).
printf("Palavra invalida\n");
palavra = '\0' (i.e. apenas para controlar o ciclo while)
break; //sai do ciclo for imediatamente
else palavra_escondida = '_'; //para criares já o mapa da palavra



esta parte apenas verifica se a palavra contém apenas caracteres do alfabeto e cria o mapa da palavra inserida, caso queiras possibiltar a entrada de "-" ou espaços é simplesmente trabalhando com os ranges. É só um exemplo, até porque há imensas maneiras de abordar o problema, algumas se calhar não tão lineares e legiveis quanto isso. Apenas tentei conjugar alguns conceitos que tinham sido abordados aqui e que possas entender mais facilmente, com a excepção da função strlen() que se encontra na biblioteca <string.h> penso eu.

para a introdução de letras, crias outro ciclo while que enquanto as tentativas forem diferentes de 0 e a palavra_escondida for diferente da palavra ele vai repetindo...ora, digo um ciclo while porque estou a supor que há partida n perdes nenhuma tentativa se acertares na letra...entao:

while (tentativas!=0 || strcmp(palavra, palavra_escondida))
-o utilizador introduz uma letra
for(i=0;i<strlen(palavra);i++)
if(palavra == letra)
palavra_escondida = letra;
else
tentativas--;


e basicamente é isto. precisas apenas de contemplar todas as restrições que queiras impor....
cabe a ti fazeres o código, podia deixar-te aqui um a funcionar mas assim não irias aprender!

espero ter ajudado!
Cumps!
 
Última edição:
eu nao quero que me facam o codigo quero tentar perceber a parte de ascii! so para fazer a validacao. irei testar mais tarde pois agora estou com dois problemas no programa quando insiro a letra ex: nando ele ira ser codificada por ***** para que a pessoa que vai adivinhar nao saber a letra introduzida ate aqui tudo bem...

e criei dois arrays chave para codificar as letras com os asterixcos e guardar a palavra e outra com o nome palavra que ira guardar o _ _ _ _ _ para apresentar no ecran, o caso é o seguinte quando tento mostrar a palavra que contem o array chave aparece-me smiles do genero (:):):):):)) no correr do programa tenho o seguinte

printf(" a palavra é "%c"", chave);
o que sera que aconteceu?

depois ou entar descobrir a palavra atraves da comparacao atraves de uma letra inserida char letra; e comparacao com chave onde ta guardada a palavra tambem me das os smiles

obrigado pela ajuda ate agora, e desculpem o incomodo
 
boas,

LaNgSuYaR, a validacao da palavra nunca poderia ser feita só com o 1º indice como tu dizes e muito bem, apenas dei um indice ao calhas como exemplo de como deveria ser tratado cada elemento do array ;)

nandoice,
a funcao getche() apanha um caracter escrito no input e não ecoa o que acabaste de digitar no output logo o utilizador nunca ve o que estas a inserir! Escusas portanto de ter os asteriscos.m Se os quiseres na mesma basta fazeres print do caracter '*' por cada caracter digitado por ti

while ( (ch = getche() ) != '\n');
//colocas cada caracter inserido por ti num array ate ser feito Enter (0x0D = '\n' = 13)
//printas um '*' no output
// validas se o caracter é letra

O conteudo de 'chave' após finalizares o ciclo deve ser por ex:
{'h','e','l','l','o','\0'}
Colocaste o caracter null (terminador) no fim de fazeres inserires a palavra toda? Tens de o fazer senão, onde se encontra o fim do array 'chave' que estas a querer fazer output?

Depois de saires do ciclo metes '\0' ou 0 ou 0x00 na ultima posicacao do array chave
. Como teste faz logo o output do array no fim do ciclo e verifica o seu conteudo

abrc
 
o que disses-te tenho eu feito:

printf("Insira a palavra: ");

while (letra=getch()!=13)
{

chave=letra;
printf("%c",'*');
i++;

}

mas quer dizer que nunca vou conseguir ler a palavra? como eu vou substituir depois nos _ _ _ _ _ ?
 
nao percebeste ainda o raciocinio...nao vais ler a palavra por inteiro! vais é ler caracter a caracter o array 'chave' e comparar com a letra inserida pelo user. Se for igual preenches o array "_ _ _ _ " na posicao onde a ocorrencia é igual.

le bem e pensa no que foi escrito nos posts acima porque ja foi tudo explicado

abrc
 
Back
Topo