Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Gr4v370

[Resolvido] Jogo em C

Recommended Posts

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

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

_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

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.

 

2wmme1f.jpg

Compartilhar este post


Link para o post
Compartilhar em outros sites

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

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

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

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

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

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

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.