Gr4v370 0 Denunciar post Postado Março 20, 2011 Boa tarde, pessoal, Estou tentando fazer um jogo em C, que compare 2 números em "char" e diga se estão na posição correta e quantos dígitos estão corretos. Por exemplo: O jogo gera um número aleatório de 5 dígitos: 11211 O usuário terá 10 chances para adivinha-lo. Eu fiz um código, mas não está funcionando corretamente, acontece o seguinte erro: Número gerado = 11211 Palpite do usuário = 11111 O programa retorna: 4 dígitos em posição correta - OK 20 dígitos corretos - errado (deveria retornar 4 dígitos corretos) Por favor, alguém poderia me ajudar a corrigir esse erro? Obrigado. for (tentativas = 1; tentativas <= 10; tentativas++) { printf("\nTentativa [%d]: ",tentativas); scanf("%s",vet2); for (j=0; j<5; j++) { if (vet1[j]==vet2[j]) { posicao++; } } for (i=0; i<5; i++) { for (j=0; j<5; j++) { if (vet2[i]==vet1[j]) { certo++; } } } printf("Numero de digitos em posicoes certas = %d\n",posicao); printf("Numero de digitos certos = %d\n\n",certo); if (posicao==5) { printf("Parabens! Voce adivinhou o numero!\n\n"); tentativas = 10; } else { posicao = 0; certo = 0; } if (tentativas==10 && posicao!=5) { printf("Voce nao conseguiu advinhar!\n\n"); printf("\nO numero sorteado foi: %s\n\n",vet1); } } system("PAUSE"); return 0; } Acredito que o erro esteja nessa parte do código: for (i=0; i<5; i++) { for (j=0; j<5; j++) { if (vet2[i]==vet1[j]) { certo++; } } } Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Março 21, 2011 for (i=0; i<5; i++) { for (j=0; j<5; j++) { if (vet2[i]==vet1[j]) { certo++; } } } Pare p/ pensar um pouco: você tem "11211" gerado e "11111" digitado. Se são 4 digitos iguais e o loop aninhado é executado 5 vezes, cada vez somando 4 ao resultado anterior, você tem 5*4 = 20. Use apenas um for nessa parte, como você fez na primeira comparação. Lembrete: aprenda a usar um depurador. Compartilhar este post Link para o post Compartilhar em outros sites
Gr4v370 0 Denunciar post Postado Março 21, 2011 _Isis_, obrigado pela resposta, Mas acho que você não entendeu o codigo, se eu fizer o que você falou o programa não vai funcionar corretamente, veja outro exemplo: Numero gerado: 12345 Palpite : 54321 Do jeito que você falou o programa retornaria: 1 dígito em posição correta - OK 1 dígito correto - errado (deveria retornar 5 dígitos corretos) Por esse motivo tenho de usar dois "for", assim ele compara numero por numero. No primeiro caso uso apenas um "for" pq só preciso comparar se o que está dentro das posições dos vetores são iguais, o "for" compara se a posição 0 do vetor1 é igual a posição 0 do vetor2 e incrementa até posição 6 dos vetores. Exemplo: Posição do vetor1->|0|1|2|3|4|5| Numero gerado------->|1|2|3|4|5|'\0'| Posição do verot2->|0|1|2|3|4|5| Palpite usuario-------->|5|4|3|2|1|'\0'| Entendeu? PS. O erro só ocorre quando tem números repetidos no número gerado, no exemplo acima o programa funciona corretamente. Compartilhar este post Link para o post Compartilhar em outros sites
Gr4v370 0 Denunciar post Postado Março 21, 2011 Vejam a figura abaixo, que mostra como o programa funciona (POSIÇÃO DIGITOS e DIGITOS CERTO (A)), gostaria que o programa fizesse como está na figura (DIGITOS CERTOS (Bê)), quando o programa encontrar um numero igual, ele incrementar e PARA e passa para o proximo numero, mas sem procurar na posição encontrada anteriormente. Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Março 21, 2011 Nesse caso, sim. Mas não tem como prever qual das duas verificações você vai usar. E quem garante que não pode existir uma terceira? você pode tentar algumas dessas implementações, mas ainda assim vai precisar modificar o código devido a repetições dos números (isso pode alterar a contagem dos dígitos corretos e dos dígitos em lugares corretos. Por exemplo, se o número gerado for "12321" e o digitado, "13287", poderíamos ter, para o dígito 1, a contagem de 2 corretos mas de um lugar incorreto. você dividiu o problema em duas partes: a primeira é tratar a string como um conjunto, eliminando todas as repetições de dígitos e a partir daí, contar quantos dígitos corretos foram informados, sem se preocupar com a posição deles. A segunda parte envolve percorrer sequencialmente as strings comparando os dígitos em cada posição das duas strings. Em C++ existe o set, que facilita a primeira parte. Veja se o código a seguir resolve os seus problemas. Nele eu só incremento as variáveis quando tenho certeza de que o dígito pertence ao conjunto e que a posição dele está correta com o número gerado. #include <strings.h> #include <string.h> const int MAX = 5; char conjunto_digitos[MAX]; int gera_conjunto(char * gerado){ memset(conjunto_digitos, -1, MAX); int idx = 0; for(int i=0; i<MAX; i++) { if (index(conjunto_digitos, gerado[i]) == NULL) { conjunto[idx] = gerado[i]; idx++; } } conjunto_digitos[idx] = '\0'; return idx; } bool procura_digito_conjunto(char digito){ if (strchr(conjunto_digitos, digito) == NULL) return false; return true; } bool procura_digito_posicao(char * gerado, char * informado, int posicao_informado){ if (gerado[posicao_informada] == informado[posicao_informada]) return true; return false; } int main(void) { char gerado[MAX] = "12326"; char informado[MAX] = "12916"; int tamanho_conjunto = gera_conjunto(gerado); int digitos_pertencentes = 0; int posicoes_corretas = 0; for (int i=0; i<MAX; i++) { if (procura_digito_conjunto(informado[i])) { if (procura_digito_posicao(gerado, informado, i)) { digitos_pertencentes++; posicoes_corretas++; } } } return 0; } Compartilhar este post Link para o post Compartilhar em outros sites
Gr4v370 0 Denunciar post Postado Março 21, 2011 Estou começando aprender a linguagem C agora, sei muito pouco e em C++ não sei nada. _Isis_, não teria um jeito mais simples de fazer o programa funcionar em C? A posição do numero o codigo acha certinho, só falta ele "aprender" a contar os digitos quando tem repetição, pq quando os numero não se repetem ele conta os digitos certinhos tb. Compartilhar este post Link para o post Compartilhar em outros sites
HwapX 20 Denunciar post Postado Março 22, 2011 Bom se entendi bem é isso que você queria, não costumo postar o codigo pronto mais não to com coragem pra tentar explicar. #include <stdio.h> int main(){ char gerado[] = "12345"; char digitado[] = "54321"; char valg[strlen(gerado) - 1]; char vald[strlen(digitado) - 1]; int corretos = 0; int g, d; for(d = 0; d < strlen(digitado);d++) vald[d] = 0; for(g = 0; g < strlen(gerado); g++){ valg[g] = 0; for(d = 0; d < strlen(digitado); d++){ if(gerado[g] == digitado[d] && vald[d] == 0){ valg[g] = 1; vald[d] = 1; break; } } if(valg[g] == 1) corretos++; } printf("total de numeros corretos = %d", corretos); return(0); } Deixei sem limites de tamanho para o valor gerado e para o valor digitado, então caso queira algum é com você. Qualquer duvida estamos ai =]. Compartilhar este post Link para o post Compartilhar em outros sites
Gr4v370 0 Denunciar post Postado Março 22, 2011 Hacker_wap é exatamente isso que faltava no meu código, muito obrigado. Quando tiver com coragem e tempo, explica como você chegou nesse código, pq tudo isso ainda é muito novo pra mim. PS. Obrigado a _Isis_ tbm. Compartilhar este post Link para o post Compartilhar em outros sites
_Isis_ 202 Denunciar post Postado Março 22, 2011 Estou começando aprender a linguagem C agora, sei muito pouco e em C++ não sei nada. _Isis_, não teria um jeito mais simples de fazer o programa funcionar em C? A posição do numero o codigo acha certinho, só falta ele "aprender" a contar os digitos quando tem repetição, pq quando os numero não se repetem ele conta os digitos certinhos tb. O "gera_conjunto" simplesmente retira todas as repetições dos dígitos do número gerado. Conjuntos não possuem elementos repetidos. A função "procura_digito_conjunto" usa a strchr p/ fazer a busca no conjunto de dígitos do número gerado (que é uma string). Se ela retornar NULL, a função retorna false indicando que o dígito lido do número informado não pertence ao conjunto de dígitos do número gerado. A função "procura_digito_posicao" retorna true se para uma mesma posição nos dois array (número gerado e número informado) os dígitos forem iguais. Se o gerado for G="12134" e o informado I="12315", você teria essa execução, seguindo o main: conjunto_digitos="1234" digitos_pertencentes = 0 posicao_correta = 0 i=0: procura_digito_conjunto(1) -> true digitos_pertencentes = 1 procura_digito_posicao -> true posicao_correta = 1 i=1: procura_digito_conjunto(2) -> true digitos_pertencentes = 2 procura_digito_posicao -> true posicao_correta = 2 i=2: procura_digito_conjunto(3) -> true digitos_pertencentes = 3 procura_digito_posicao ->false posicao_correta = 2 i=3: procura_digito_conjunto(1) -> true digitos_pertencentes = 4 procura_digito_posicao -> false posicao_correta = 2 i=4: procura_digito_conjunto(5) -> false digitos_pertencentes = 4 procura_digito_posicao -> false posicao_correta = 2 No final você tem que, dos 5 dígitos do número informado, 4 estão certos (pertencem ao conjunto) e apenas 2 estão nas posições corretas. Detalhe: coloquei o incremento no lugar errado do for. Deveria ser assim: if (procura_digito_conjunto(informado[i])) { digitos_pertencentes++; if (procura_digito_posicao(gerado, informado, i)) posicoes_corretas++; } Compartilhar este post Link para o post Compartilhar em outros sites
HwapX 20 Denunciar post Postado Março 22, 2011 Cara não vo da uma explicação melhor porque eu sinceramente não sou bom nisso. O codigo novamente sem resíduos #include <stdio.h> int main(){ char gerado[] = "11111"; char digitado[] = "11221"; char vald[strlen(digitado) - 1]; int corretos = 0; int g, d; for(d = 0; d < strlen(digitado);d++) vald[d] = 0; for(g = 0; g < strlen(gerado); g++) for(d = 0; d < strlen(digitado); d++){ if(gerado[g] == digitado[d] && vald[d] == 0){ corretos++; vald[d] = 1; break; } } printf("total de numeros corretos = %d", corretos); return(0); } enquanto G for menor que o tamanho do numero gerado enquanto D for menor que o tamanho do numero digitado se GERADO[G] for igual a DIGITADO[D] e VALD[D] == 0 então incrementar CORRETOS VALD[D] == 1; sair do loop atual; fim se proximo D proximo G VALD 0 significa que ainda não foi encontrado nenhum numero igual ao numero digitado correspondente a posição D 1 significa que ja foi encontrado um numero igual a ela então não a necessidade de verificar novamente aquela posição. Aqui tem um codigo um pouco mais light mais só sera util se você não for reutilizar o numero utilizado #include <stdio.h> int main(){ char gerado[] = "12345"; char digitado[] = "54321"; int corretos = 0; int g, d; for(g = 0; g < strlen(gerado); g++) for(d = 0; d < strlen(digitado); d++) if(gerado[g] == digitado[d]){ corretos++; digitado[d] = -1; break; } printf("total de numeros corretos = %d", corretos); return(0); } a diferença dele para o anterior é que em vez de fazer a validação em um vetor separado ele somente anula o numero depois de incrementar os numeros corretos assim ele não vai mais ser igual aos outros. Até =]. Compartilhar este post Link para o post Compartilhar em outros sites
Gr4v370 0 Denunciar post Postado Março 22, 2011 Obrigado a todos! :joia: Compartilhar este post Link para o post Compartilhar em outros sites