Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Entendimento da função sorteiaNumeros

Fala, pessoal, tudo bem?

Gostaria de uma ajuda para compreender o método de evitar os números repetidos, ou seja, a função sorteiaNumeros, sobre a qual não entendi nada rs, já vi a aula umas 3x e não entra na cabeça.

Segue o código completo.

<meta charset="UTF-8">

<input/>
<button>Compare com o meu segredo</button>

<script>
    function sorteia() {

       return Math.round(Math.random() * 10);

    }

    function sorteiaNumeros(quantidade) {

        var segredos = [];

        var numero = 1;

        while(numero <= quantidade) {

              var numeroAleatorio = sorteia();
              var achou = false;

              if (numeroAleatorio !== 0) {
                     for(var posicao = 0; posicao < segredos.length; posicao++) {

                           if(segredos[posicao] == numeroAleatorio){
                                achou = true;
                                break;
                           }

                     }

                     if (achou == false) {
                           segredos.push(numeroAleatorio);
                           numero++;
                     }
              }

        }

        return segredos;

    }

    var segredos = sorteiaNumeros(3);

    console.log(segredos);

    var input = document.querySelector("input");
    input.focus();

    function verifica() {

       var achou = false;

       for(var posicao = 0; posicao < segredos.length; posicao++) {

              if(input.value == segredos[posicao]) {

                     alert("Você ACERTOU!");
                     achou = true;
                     break;
              } 
       }

       if(achou == false) {

              alert("Você ERROU!");
       }

       input.value = "";
       input.focus();

    }

    var button = document.querySelector("button");

    button.onclick = verifica;

</script>
8 respostas

Fala, Giovani! Tudo bem contigo?

Vou fazer um passo a passo para deixar um pouco mais claro. Quando vemos um todo pode dar uma confundida rs...

Eu numerei a sequencia de 1 a 23 para que possa entender cada passo da execução.

Vamos lá?!

<meta charset="UTF-8">

<input />
<button>Compare com o meu segredo</button>

<script>
  //01 - Aqui eu crio uma função que vai sortear nos números. Agora está quietinha rs
  function sorteia() {

    return Math.round(Math.random() * 10);

  }

  //02 - Vamos criar a função que vai sortear a quantidade de números que será especificado. Está dormindo por enquanto...
  //06 - Voltamos para a função porque foi chamado (ítem 03). Não se esqueça que "quantidade" será três.
  function sorteiaNumeros(quantidade) {

    //07 - Aqui temos a array que guardará os três números
    var segredos = [];

    //08 - Neste, queremos que a contagem começa pelo número 1. Chamado de contador.
    var numero = 1;

    //09 - Aqui estamos dizendo que enquanto o contador "numero" for menor que a "quantidade(3)" faça tal coisa
    while (numero <= quantidade) {

      //10 - Olha onde estamos pedindo para sortear. Convocamos a função!!! Ele vai sortear um número até 10
      var numeroAleatorio = sorteia();

      //11 - Nesta variável consideramos falsa, mas logo abaixa vamos entender melhor
      var achou = false;

      //12 - Criamos uma condicional! Se o número sorteado for diferente de 0...
      if (numeroAleatorio !== 0) {

        //13 - Esse é quem colocará os números dentro da array
        for (var posicao = 0; posicao < segredos.length; posicao++) {

          //14 - Aqui estamos verificando se já completamos o total de números sorteados. Se tiver, não executa mais(break). Se ainda não...
          if (segredos[posicao] == numeroAleatorio) {
            achou = true;
            break;
          }

        }

        //15 - Sorteia mais um e adiciona. Repete o processo até cair no ítem 14. Este "false"(ítem 11) faz com que o processo continue. Se fosse "true" daria "break"
        if (achou == false) {
          segredos.push(numeroAleatorio);
          numero++;
        }
      }

    }

    //16 - Terminado o processo (break), guardou e está mostrando no console.log(ítem 04)
    return segredos;

  }

  //03 - Agooooora vamos começar. Veja que foi especificado quantos números eu quero chamando a função e também já estou colocando dentro de uma variável.
  var segredos = sorteiaNumeros(3);

  //04 - Aqui eu só quero que os números sorteados apareçam no console(F12)
  console.log(segredos);

  //05 - Esse é a caixa que será colocado o "chute"
  var input = document.querySelector("input");
  input.focus();

  //18 - Quando clicamos(ítem 17) começamos esta função de verificação
  function verifica() {

    //19 - Essa variável tem o mesmo valor do ítem 11
    var achou = false;

    //20 - Vai fazer o processo de loop. Mesmo que o do ítem 02, porém para verificar se acertou ou não.
    for (var posicao = 0; posicao < segredos.length; posicao++) {

      //21 - Verifica se o valor colocado no campo bate com algum valor sorteado
      if (input.value == segredos[posicao]) {

        //22 - Acertou? Acontece o "break" e já exibe o "Acertou"
        alert("Você ACERTOU!");
        achou = true;
        break;
      }
    }

    //23 - Errou? Aparece "Errou" e volta para o campo para tentar um novo chute.
    if (achou == false) {

      alert("Você ERROU!");
    }

    input.value = "";
    input.focus();

  }

  var button = document.querySelector("button");

  //17 - Neste, clicamos para verificar nosso chute
  button.onclick = verifica;

</script>

Giovani, espero ter ajudado!!!

Bons estudos e vamos em frente!!!

solução!

Olá Giovani, tudo bem com você?

Então vamos lá! Vou te mostrar passo a passo como funciona essa função :)

  • Vamos pegar a partir de sua chamada:
    var segredos = sorteiaNumeros(3);

A pessoa que chama a função está pedindo para sortear 3 números que serão armazenados na variável segredos

Então vamos para a função:

function sorteiaNumeros(quantidade) {

        var segredos = [];

        var numero = 1;

Estamos inicializando o array que será composto pelos 3 números sorteados, e uma variável chamada numero com o valor 1 para indicar que estamos sorteando o primeiro número

Após isso temos:

   while(numero <= quantidade) {
              var numeroAleatorio = sorteia();
              var achou = false;

Temos então que a quantidade é o que o nosso usuário passou, ou seja, o número de valores que ele quer sortear, e logo no começo sorteamos o número com a função sorteia:

return Math.round(Math.random() * 10);

Então geramos um número que vale de 0 até 10, e criamos também uma variável achou que já iremos entender para que serve :)

 if (numeroAleatorio !== 0) {
                     for(var posicao = 0; posicao < segredos.length; posicao++) {

 }

Após sortearmos o valor, estamos verificando se ele é diferente de 0, se for igual iremos sortear outro valor!

Agora caso ele seja diferente estamos criando um laço que começa de 0 até a quantidade de elementos que temos em nosso vetor ( na primeira execução irá valer 0, pois não temos nada)

if(segredos[posicao] == numeroAleatorio){
    achou = true;
    break;
}

Então em nosso laço iremos observar cada elemento do array de segredos, no caso segredos[posicao] e comparar se é igual ao número que acabamos de sortear, caso seja mudamos aquela variável achou para true, indicando que esse valor já está dentro do nosso array de segredos

Por fim temos o ultimo trecho do código:

if (achou == false) {
      segredos.push(numeroAleatorio);
      numero++;
}

Então se não encontramos o número sorteado, nós adicionamos ele no nosso array de segredos com a função push e indicamos que queremos sortear o próximo número, caso ele já esteja não iremos entrar nesse if e iremos sortear outro valor ainda para aquela posição

Vou simular uma pequena execução procurando 3 números:

  • Criamos o array de segredos que está vazio e a nossa variavel número valendo 1
  • O numeroAleatorio é sorteado e vale 8
  • achou será criada com false
  • Iriamos agora percorrer o nosso array, entretanto ele está vazio, então é impossível que o primeiro valor seja repetido
  • achou então se mantém como false, e é adicionada em segredos e agora número vale 2
  • O numeroAleatorio é sorteado novamente e vale 5
  • achou é criada como false
  • Iremos percorrer o array segredos que só contem 1 elemento, e segredos[posicao] vale 8 que é diferente de 5
  • Então achou continua false e também é adicionada em segredos e agora o numero vale 3
  • Vamos supor que o numeroAleatorioé 5 novamente
  • achou é criada como false
  • Iremos percorrer o array, nesse momento posicao vale 0, então segredos[posicao] vale 8 que é diferente de 5, depois posicao vira 1 e temos que segredos[posicao]vale 5 então é igual
  • Mudamos achou para true e paramos de percorrer nosso array
  • Como achou é true não iremos aumentar o valor de número nem adicionar em nosso array
  • Então iremos sortear um novo valor
  • Vamos supor que o valor sorteado dessa vez foi 3 e irá ocorrer todo esse processo de verificar que é diferente de 8 e 5, e será adicionado em nosso vetor
  • Agora número irá valer 4 e a quantidade vale 3, então acabará nosso while pois numero < quantidade

E por fim temos: return segredos; que é devolver para o nosso usuário os 3 valores aleatórios não repetidos :)

Conseguiu compreender?

Abraços e Bons Estudos!

Fala, Cassio, tudo bem?

Opa, o passo a passo já deu uma boa clareza, entendi bem os processos de sortear o número, guardar na array e a função verifica.

Só ainda não compreendi como é feito o processo que evita gerar números aleatórios repetidos na array.

Outra coisa, não há problema que existam duas variáveis "segredos"? A que guarda a array e a que chama a função sorteiaNumeros? Aliás, me fugiu da mente: quando atribuímos uma função à uma variável, já estamos chamando essa função, correto?

Valeu!

Opa Giovani, ainda não sei se viu minha resposta, mas vou tentar te explicar suas novas dúvidas :)

Só ainda não compreendi como é feito o processo que evita gerar números aleatórios repetidos na array.

Temos aquele laço que percorre cada posição do array de segredos se em algum momento o valor que foi sorteado no momento estiver lá dentro, mudamos o valor de achou para true e isso impede que caia no if que insere os valores no array de segredos!

não há problema que existam duas variáveis "segredos"? A que guarda a array e a que chama a função sorteiaNumeros?

Então, existe o que chamamos de escopo que é o espaço onde está essa variável, não podemos ter nomes iguais no mesmo escopo, mas veja que uma está dentro da função e outra está no nosso código ( o que chamamos de escopo global), então não há problemas, pois o javascript sabe que quando ele está dentro da função segredos vai ser o vetor e quando estiver fora será a outra variável!

Abraços e Bons Estudos!

Opa, Giovani, veja a explicação do Geovani!!!

Ele esclareceu com excelência!!!

Precisar... estamos a disposição!!

Geovani, desculpe, respondi antes do seu comentário aparecer, mas creio que agora tudo ficou mais claro :)

Só restou uma única dúvida no:

if(segredos[posicao] == numeroAleatorio){
    achou = true;
    break;
}

O break, supondo que a condição ache um número repetido na observação do array, não deveria quebrar o processo de jogar os números no array, fazendo o sorteio parar?

Obrigado!

Então Giovani,

Na verdade o break neste caso é para parar deixar o nosso código mais eficiente, imagine a seguinte situação:

  • Pedimos para sortear 7 valores e iremos sortear o 6º valor, então temos algo parecido como:

segredos = [ 10, 5, 3, 7, 4]

  • Vamos supor que o 6º valor sorteado é o numero 3, então iriamos comparar:

  • 10 diferente de 3-> false

  • 5 diferente de 3 -> false

  • 3 igual a 3 -> true

Concorda comigo que nesse momento não precisamos mais comparar com o 7 e com o 4, porque já achamos o valor repetido, certo?

Então o que acontece é que mudamos o valor de achou e o break irá parar a execução do for, então na verdade:

Supondo que a condição ache um número repetido na observação do array, não deveria quebrar o processo de jogar os números no array, fazendo o sorteio parar?

Não :)

Na verdade quebramos o processo de percorrer o array, mas a execução do while continua funcionando, e é dentro dela e abaixo do for que está nossa lógica de inserção no array!

Só iriamos quebrar o processo de jogar os números se esse break estivesse dentro do while e fora de outro laço!

Abraços e Bons Estudos!

Muito bom, deu para compreender melhor o processo de percorrer o array, estava perdidíssimo com essa parte hehehe espero, logo, dominar toda essa lógica!

Valeu demais, pessoal, obrigado pelos esclarecimentos!!