View Full Version : jogo da forca em C!
nandoice 10-04-2007, 21:06 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
LumpyNutz 10-04-2007, 22:10 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 .
nandoice 10-04-2007, 22:26 mas pode-se fazer char palavra="1234567890" e comparar?
LumpyNutz 10-04-2007, 23:11 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.
nandoice 10-04-2007, 23:47 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?
LumpyNutz 11-04-2007, 00:11 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[i]!='\0')
{
printf("introduza a letra: ");
scanf("%c",&ch);
if(palavra[i]==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!!!
nandoice 11-04-2007, 00:17 é 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
nandoice 11-04-2007, 00:25 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!
LumpyNutz 11-04-2007, 00:54 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
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"
//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
nandoice 11-04-2007, 15:49 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
nandoice 12-04-2007, 00:40 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
LaNgSuYaR 12-04-2007, 16:50 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[i] >= "A" && palavra[i] <="Z") || (palavra[i] >= "A" && palavra[i] <="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[i] = '_'; //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[i] == letra)
palavra_escondida[i] = 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!
nandoice 12-04-2007, 19:10 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[i] para codificar as letras com os asterixcos e guardar a palavra e outra com o nome palavra[i] que ira guardar o _ _ _ _ _ para apresentar no ecran, o caso é o seguinte quando tento mostrar a palavra que contem o array chave[i] 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[i] 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
nandoice 13-04-2007, 13:07 o que disses-te tenho eu feito:
printf("Insira a palavra: ");
while (letra=getch()!=13)
{
chave[i]=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
nandoice 15-04-2007, 15:53 thanks vou tentar perceber entao...
agora estou com problemas quando se insere uma palavra nao consigo vereficar se esta contida no array!
cumps
Também podes usar strcmp(); para comparar as palavras (incluindo string.h)
E em vez de '\0', usa '\n' se estiveres a planear usar mais de duas palavras, mas para isso, vais precisar de fazer scanf("%[^\n]",asdf);.
PS: sou demasiado preguiçoso para ler os outros posts lol
um exemplo:
>> crias duas strings, uma para conter a palavra, outra para conter os espaços:
char palavra[50];
char hidden[50];>> depois pedes que introduzam a palavra:
scanf("%s", palavra);>> depois crias um ciclo que substitua a palavra por espaços em 'hidden':
for(i=0; i<strlen(palavra); i++)
hidden[i] = '_';
hidden[i+1]='\0'
>> depois pedes uma letra (definida por exemplo por um 'char letra') e a comparação e substituição é feita da seguinte forma:
j=0;
/* verifica se a letra ja existe */
for(i=0; i<strlen(hidden); i++)
if(hidden[i] == letra)
j=1;
/* procura a letra na palavra e substitui na palavra escondida */
if(j == 0) {
for(i=0; i<strlen(hidden); i++)
if(palavra[i] == letra) {
j=2;
hidden[i]=letra;
}
}
/* verifica se a palavra j‡ est‡ certa */
if(strcmp(hidden, palavra) == 0)
j=3;
/* envia o c—digo correspondente ao cliente */
if(j==0) {
printf("não existe\n");
} else if(j==1) {
printf("letra já existente\n");
} else if(j==2) {
printf("letra correcta\n");
} else if(j==3) {
printf("palavra completa!\n");
}
espero ter ajudado..
nandoice 17-04-2007, 17:18 http://i135.photobucket.com/albums/q126/nandoice/Semttulo.jpg
void testaletra(char *caract)
{
int i;
for (i=0;chave[i]; i++)
{
if(chave[i]==*caract)
{
palavra[i]=chave[i];
printf("%s", palavra);
}
}
}
void tentativas()
{
int j=0, i=0;
char caract;
n
do
{
printf("\nInsira uma letra: ");
caract=getchar();
testaletra(&caract);
/*printf("\nTem %d tentativas!",x);*/
}while(caract !=27);
}
agradeco ao pessoal todas as dicas, mas a entrega do trabalho sera amanha e ocorre-me isso cada vez que tento inserir um letra e pede para inserir 2x, nao percebo porque eu vou-vos mandar o codigo correspondente a esse bloco e tambem queria por quando acerta e erra mas nao sei como...
cumps
LaNgSuYaR 17-04-2007, 17:28 isso acontece-te porque a função scanf deixa em buffer um '\n' pra resolver isso, podes fazer um define, logo a seguir aos #include:
#define eoln while (getc(stdin) != '\n') {;}
o que isto faz é limpar o buffer até encontrar um '\n'. Usa-o sempre a seguir ao scanf, deve resolver o problem... para o chamares fazes simplesmente
eoln;
li o código na diagonal, mas quando tiver mais tempo, se surgir alguma dica ainda a posto hoje!!
cumps!
nandoice 17-04-2007, 18:18 mas eu nesse bloco nao tenho la nenhum scanf...
inserio-o ai, isso ta correcto mas agora antes aparece 2 palavras(escondidas) seguidadas
do genero _______ _______ insira a letra:
printf("\nInsira uma letra: ");
caract=getchar();
testaletra(&caract);
eoln;
/*printf("\nTem %d tentativas!",x);*/
}while(caract !=27);
LaNgSuYaR 17-04-2007, 22:18 getchar() era o que queria dizer, dsclpa! com o 'eoln' passa a funcionar aí? pq a única raazão plausível de repetir o ciclo, é mesmo o buffer não estar 'limpo'!
nandoice 18-04-2007, 00:50 fflush(stdin) tambem serve pelo que me disseram!
agora nao consigo inserir as palavras num vector para que mostre as palavras inseridas...
mas eu nesse bloco nao tenho la nenhum scanf...
inserio-o ai, isso ta correcto mas agora antes aparece 2 palavras(escondidas) seguidadas
do genero _______ _______ insira a letra:
printf("\nInsira uma letra: ");
caract=getchar();
testaletra(&caract);
eoln;
/*printf("\nTem %d tentativas!",x);*/
}while(caract !=27);
fechaste o buffer com o caracter '\0' na ultima posicao como te tinha dito no ultimo ou penultimo post?
|
|