1
resposta

[Bug] bug função sortear

let lista = []

function adicionar(){
    let nomeAmigo = document.getElementById('nome-amigo').value
    let listaAmigos = document.getElementById('lista-amigos')
    if (listaAmigos.textContent.includes(nomeAmigo)){
        alert('Nome já incluido no sorteio, por favor digite um nome diferente.')
        document.getElementById('nome-amigo').value = ''
        return
    } else if(nomeAmigo == ''){
        alert('Por favor digite um nome.')
        return
    }
    
    
    document.getElementById('nome-amigo').value = ''
    //Deixando nome em amigo incluidos mais bonito
    if (lista.length == 0){
        listaAmigos.textContent = nomeAmigo
    } else {
    listaAmigos.textContent += `, ${nomeAmigo}`   
    }
  
    return lista.push(nomeAmigo)
}

let sorteando = []
let sorteado = []

function sortear(){
    let sorteio = document.getElementById('lista-sorteio')
    alert(lista.length)
    if (lista.length < 2){
        alert('Número de participantes invalidos.')
        return
    }
    let i = 0
    while(i <= lista.length - 1){
        let nomeSorteando = lista[numeroAleatorio(0, lista.length - 1)]
        let nomeSorteado = lista[numeroAleatorio(0, lista.length - 1)]
        while (nomeSorteado == nomeSorteando){
            nomeSorteado = lista[numeroAleatorio(0, lista.length - 1)]   
        }
        if(i == 0){
            sorteando.push(nomeSorteando)
            sorteado.push(nomeSorteado)
            sorteio.innerHTML = `<p id="lista-sorteio">${sorteando[i]} --> ${sorteado[i]}</p>`  
        }else {
            while (sorteando.includes(nomeSorteando) || nomeSorteando == nomeSorteado){
                nomeSorteando = lista[numeroAleatorio(0, lista.length - 1)]  
            }
            while (sorteado.includes(nomeSorteado) || nomeSorteado == nomeSorteando){
                nomeSorteado = lista[numeroAleatorio(0, lista.length - 1)]  
            }
            sorteando.push(nomeSorteando)
            sorteado.push(nomeSorteado)
            sorteio.innerHTML += `<p id="lista-sorteio">${sorteando[i]} --> ${sorteado[i]}</p>`  
        }
        i++
    }
    

}

function reiniciar(){
    lista = []  
    document.getElementById('lista-amigos').textContent = ''
    sorteando = []
    sorteado = []
    document.getElementById('lista-sorteio').textContent = ''

}
function numeroAleatorio(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

O código funciona, mas ocasionalmente a função sortear gera um looping infito, gostaria de saber o que está causando isso

1 resposta

Olá João!

O loop infinito ocorre porque você está verificando se o nomeSorteando é igual ao nomeSorteado antes de adicioná-los às listas sorteando e sorteado. Isso significa que, se a função gerar um par de nomes iguais (o que é possível, embora improvável), ela entrará em um loop infinito, pois a condição nunca será satisfeita.

Para resolver esse problema, você precisa garantir que a condição de parada do loop seja sempre satisfeita, mesmo que a função gere nomes iguais. Aqui está uma solução:

function sortear() {
  let sorteio = document.getElementById('lista-sorteio');
  if (lista.length < 2) {
    alert('Número de participantes invalidos.');
    return;
  }

  // Copia a lista para evitar modificá-la diretamente
  const listaSorteio = [...lista];
  sorteando = [];
  sorteado = [];

  while (listaSorteio.length > 0) {
    // Sorteia um nome da lista
    const indiceSorteando = numeroAleatorio(0, listaSorteio.length - 1);
    const nomeSorteando = listaSorteio[indiceSorteando];
    sorteando.push(nomeSorteando);
    listaSorteio.splice(indiceSorteando, 1); // Remove o nome da lista

    // Sorteia outro nome diferente do primeiro
    const indiceSorteado = numeroAleatorio(0, listaSorteio.length - 1);
    const nomeSorteado = listaSorteio[indiceSorteado];
    sorteado.push(nomeSorteado);
    listaSorteio.splice(indiceSorteado, 1); // Remove o nome da lista

    sorteio.innerHTML += `<p id="lista-sorteio">${nomeSorteando} --> ${nomeSorteado}</p>`;
  }
}

Alterações:

  1. Cópia da lista: Ao invés de trabalhar diretamente na lista original (lista), foi criada uma cópia (listaSorteio) para evitar modificá-la.
  2. Remoção de nomes: Após sortear um nome, ele é removido da lista listaSorteio usando splice(). Isso garante que cada nome seja sorteado apenas uma vez.
  3. Condição de parada: O loop continua até que a lista listaSorteio esteja vazia, o que garante que ele sempre termine.

Espero ter ajudado e bons estudos!