1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Frustração/Nervos com Sorteio em ActionScript

Discussão em 'Programação' iniciada por Rexobias, 16 de Abril de 2008. (Respostas: 23; Visualizações: 1664)

  1. Rexobias

    Rexobias Power Member

    Olá malta.

    Escrevo isto neste momento muito frustrado. Fiquei em fazer uma pequena aplicação em Flash/ActionScript que consiste num sorteio de 16 equipas por 4 grupos.

    A verdade é que pensava terminar isto em pouco tempo, mas a verdade é bem pior. Tenho a certeza que o algoritmo está bem, assim como o código parece-me bem, e não encontro qualquer razão para não trabalhar ... a verdade é que o FlashPlayer tem dado o aviso de ciclo infinito, e não consigo perceber o porque do mesmo.

    O programa tem 16 Dynamic Text Box's (cada uma para guardar o nome das equipas que resultam do sorteio, e cada uma com uma var atribuida no respectivo campo - pos1, pos2, etc...), e um botão que é que faz o sorteio começar. Como tal, o botão é o único que tem código, sendo este o seguinte:

    ----------------------------------------------------------

    Código:
    on (release){[/FONT][/I]
    [i][FONT=Arial] var sort, aleat, ver, i: Number;
     var posicao = new Array();
     var teste = new Array();
     var equipas = new Array();
     
     equipas[0] = "FC Porto";
     equipas[1] = "SL Benfica";
     equipas[2] = "Sporting";
     equipas[3] = "Manchester Utd.";
     equipas[4] = "Arsenal";
     equipas[5] = "Chelsea";
     equipas[6] = "AC Milan";
     equipas[7] = "Inter";
     equipas[8] = "Juventus";
     equipas[9] = "Barcelona";
     equipas[10] = "Real Madrid";
     equipas[11] = "PSG";
     equipas[12] = "O.Lyon";
     equipas[13] = "Bayern Munchen";
     equipas[14] = "Werder Bremen";
     equipas[15] = "Celtic";
     sort = 0;
     i = 0;
     
     while (i < 16)
      {
      teste[i] = 20;
      i = i + 1;
      }
     
     while (sort < 16)
      { 
      ver = 0;
      i = 0;
      aleat = Math.floor(Math.random()*16); 
      teste[sort] = aleat;
      //Verifica se uma equipa já foi anteriormente sorteada
      
      [B]while (i < 16)
       {
       if (aleat == teste[I]){
        {
        ver = ver + 1;
        }
       i = i + 1;
       }
    [/I][/B][I]    
     [B] if (ver == 0)
       {
    [/B]   posicao[sort] = aleat;
       sort = sort + 1;
      [B] }
      }
    [/B] }[/I][/FONT]
    [I][FONT=Arial] pos1 = equipas[posicao[0]];
     pos2 = equipas[posicao[1]];
     pos3 = equipas[posicao[2]];
     pos4 = equipas[posicao[3]];
     pos5 = equipas[posicao[4]];
     pos6 = equipas[posicao[5]];
     pos7 = equipas[posicao[6]];
     pos8 = equipas[posicao[7]];
     pos9 = equipas[posicao[8]];
     pos10 = equipas[posicao[9]];
     pos11 = equipas[posicao[10]];
     pos12 = equipas[posicao[11]];
     pos13 = equipas[posicao[12]];
     pos14 = equipas[posicao[13]];
     pos15 = equipas[posicao[14]];
     pos16 = equipas[posicao[15]];
     
    }


    ----------------------------------------------------------

    Se retirar o código a negrito, que é responsável por fazer uma verificação ao valor gerado para evitar que uma equipa seja sorteada mais do que uma vez, o sorteio funciona, mas como é óbvio eu preciso de fazer a filtragem.

    array teste - guarda os valores gerados para verificar a repetição dos mesmos
    pos1, pos2, pos3, etc... - Variáveis atribuidas ás Dynamic Text's
     
    Última edição pelo moderador: 21 de Abril de 2008
  2. andrepadez

    andrepadez Power Member

    Visto não perceber muito de Action Script, não consigo perceber onde é criado o loop infinito;
    Não percebi este ciclo, se me puderes explicar:
    Código:
    while (i < 16)
    {
    teste[i] = 20;
    i = i + 1;
    }

    No entanto proponho-te uma solução um pouco diferente, mas que funcionará às mil maravilhas:

    Crias um segundo array com a mesma dimensão (sorteado[]) para depositar as equipas sorteadas.

    Fazes o ciclo para o random, e deposita no array sorteado, a equipa sorteada, colocando de seguida esse índice do array equipas a Null;
    Qualquer coisa do género:

    Código:
     
    i = 0;
    while (i<16)
    {
        aleat = random 16;
        if equipes[aleat] != Null
        {
                sorteado[aleat] = equipes[aleat];
                equipes[aleat] = Null;
                i++;
        }
    }
    
    (não ligues à sintaxe pois não é action Script, mas é facil de transpores)

    Por fim preenches as tuas textboxes com os valores do sorteado[]
    Assim condensas tudo na mesma repetição, o teste e a atribuição.

    Espero que tenha ajudado.

    Bom coding
     
  3. Rexobias

    Rexobias Power Member

    Esse ciclo while que referes era para preencher o array que guarda os valores com os quais vou comparar o valor gerado. Preencho o mesmo para evitar problemas ao comparar registos vazios...de qualquer maneira, esse array teste só está a ocupar espaço pois podia usar o posicao, mas mesmo assim devia funcionar.

    Eu que percebo algumca coisa de ActionScript, não apanho de forma alguma o problema, o código parece-me correcto.

    Vou exprementar a tua proposta, obrigado pela atenção.
     
  4. andrepadez

    andrepadez Power Member

    Desculpa, mas penso que tudo o que estás a fazer nesse while é atribuir o valor 20 a todos os indices do array. Correct me if i'm wrong
     
  5. Rexobias

    Rexobias Power Member

    Estás correcto.

    Faço isso que é para mais tarde quando faço a comparação de valores gerados com os valores do array evitar que aconteçam eventuais erros ao testar com indices vazios.
     
  6. Rexobias

    Rexobias Power Member

    Aqui fica uma actualização do código com lixo eliminado e devidamente comentado ... mas infelizmente o Flash Player continua a avisar sobre um ciclo infinito.

    Código:
    on (release){
     
    //Declaração de variáveis
    var sort, ver, i: Number;
    var posicao = new Array();
    var equipas = new Array();
     
    //Iniciação de variáveis
    equipas[0] = "FC Porto";
    equipas[1] = "SL Benfica";
    equipas[2] = "Sporting";
    equipas[3] = "Manchester Utd.";
    equipas[4] = "Arsenal";
    equipas[5] = "Chelsea";
    equipas[6] = "AC Milan";
    equipas[7] = "Inter";
    equipas[8] = "Juventus";
    equipas[9] = "Barcelona";
    equipas[10] = "Real Madrid";
    equipas[11] = "PSG";
    equipas[12] = "O.Lyon";
    equipas[13] = "Bayern Munchen";
    equipas[14] = "Werder Bremen";
    equipas[15] = "Celtic";
    sort = 0;
    i = 0;
     
    //Preenche o array posicao com o valor 20 em 16 indices para evitar 
    //problemas ao comparar com campos vazios mais tarde. O valor escolhido 
    //foi 20 para assim não estar no intervalo que será gerado evitando 
    //qualquer problema com os primeiros valores gerados
    while (i < 16)
    {
    posicao[i] = 20;
    i = i + 1;
    }
     
    //Ciclo que gera um valor aleatório para sortear as equipas
    //e faz a verificação de equipas repetidas
    while (sort < 16)
    { 
    ver = 0;
    i = 0;
    posicao[sort] = Math.floor(Math.random()*16); 
     
    //Verifica se uma equipa já foi anteriormente sorteada comparando 
    //o índice em análise do array posicao com todos os índices existentes 
    //do mesmo array. A variável ver vai registar a quantidade de vezes 
    //que a equipa foi encontrada 
    while (i < 16)
    {
    if (posicao[sort] == posicao[i])
    {
    ver = ver + 1;
    }
    i = i + 1;
    }
     
    //Analisa o resultado do contador ver. Se o valor for zero significa 
    //que o valor gerado é novo e será registado, incrementando um valor 
    //no contador do while, fazendo com que o programa avance um índice. 
    //Caso este seja superior, o contador não sofre qualquer aletração 
    //obrigando o ciclo a repetir-se e assim gerar outro valor
    if (ver == 0)
    {
    sort = sort + 1;
    }
    }
    //Regista os resultados do array posicao que teoricamente devem ter 
    //todos um valor único entre 0 e 15 
    pos1 = equipas[posicao[0]];
    pos2 = equipas[posicao[1]];
    pos3 = equipas[posicao[2]];
    pos4 = equipas[posicao[3]];
    pos5 = equipas[posicao[4]];
    pos6 = equipas[posicao[5]];
    pos7 = equipas[posicao[6]];
    pos8 = equipas[posicao[7]];
    pos9 = equipas[posicao[8]];
    pos10 = equipas[posicao[9]];
    pos11 = equipas[posicao[10]];
    pos12 = equipas[posicao[11]];
    pos13 = equipas[posicao[12]];
    pos14 = equipas[posicao[13]];
    pos15 = equipas[posicao[14]];
    pos16 = equipas[posicao[15]];
     
    }
    
    Não consigo perceber o que está errado :(

    P.S: andre, tentei o teu código mas não compreendi aquilo do Null :( e de qualquer maneira quero saber porque que este não funciona...
     
    Última edição pelo moderador: 17 de Abril de 2008
  7. Baderous

    Baderous Banido

    Código:
      while (sort < 16)
      { 
      ver = 0;
      i = 0;
      posicao[sort] = Math.floor(Math.random()*16);
    Não estás a incrementar o sort.
     
  8. andrepadez

    andrepadez Power Member

    Bons olhos Baderous, deve ser da MJ hehehe.

    De qualquer maneira, com o algorítmo que te dei ficas com código mais simples.
     
  9. Rexobias

    Rexobias Power Member

    Baderous, estou a incrementar no final. Só incremento após o valor gerado ter sido introduzido com sucesso. :( Infelizmente ao fazer copy/paste ele retirou as tabulações o que dificulta a leitura do código, mas com os comentários penso que se percebe a lógica.

    andre, será que podias passar o pseudocódigo (ou o código bem comentado) para eu tentar perceber, é que sinceramente não percebi antes :(
     
  10. andrepadez

    andrepadez Power Member

    Código:
     i = 0;
    while (i<16) //com este while executas o bloco, tantas vezes qtas forem necessárias              //até ele preencher as 16 equipes no novo vector sorteado[]
    {
        aleat = random 15; // aqui atribuis à variável aleat, um valor inteiro aleatório de 0 a 15
        if equipes[aleat] != Null //Testa se o índice aleat do array equipes não é um valor vazio
        {
                //Tinha-me enganado no código inicial. repara no vermelho
                sorteado[i] = equipes[aleat]; //atribuis a equipe seleccionada aleatóriamente ao indice [i] do array sorteado
                //Quando uma equipe passa para o array Sorteado, deixa de ter interesse no original, a linha seguinte apaga-a
                //permite também o teste do IF em cima
                equipes[aleat] = Null;
                //Incrementas o indice i, se e só se atribuiste uma equipe ao novo array
                i++;
        }
    }
    
    
    Assim funciona certamente, qq dúvida apita
     
  11. Rexobias

    Rexobias Power Member

    andre, muito obrigado, agora percebi, só há um problema ... não sei usar o Null em ActionScript (nada que ao googlar nao se resolva - edit: já googlei e é como em C).

    Se isto funcionar (e parece-me que sim, o código está bem mais optimizado), tenho que te pagar uma cerveja, aliás, mesmo senão funcionar tenho que pagar-te na mesma como agradecimento pelo apoio.

    O problema na questão é que não vejo razão para que o código que fiz não funcionar
     
  12. anjo2

    anjo2 Power Member

    Código:
    on (release){
     
    //Declaração de variáveis[INDENT] var sort, ver, i: Number;
    var posicao = new Array();
    var equipas = new Array();
    [/INDENT]//Iniciação de variáveis[INDENT] equipas[0] = "FC Porto";
    equipas[1] = "SL Benfica";
    equipas[2] = "Sporting";
    equipas[3] = "Manchester Utd.";
    equipas[4] = "Arsenal";
    equipas[5] = "Chelsea";
    equipas[6] = "AC Milan";
    equipas[7] = "Inter";
    equipas[8] = "Juventus";
    equipas[9] = "Barcelona";
    equipas[10] = "Real Madrid";
    equipas[11] = "PSG";
    equipas[12] = "O.Lyon";
    equipas[13] = "Bayern Munchen";
    equipas[14] = "Werder Bremen";
    equipas[15] = "Celtic";
    sort = 0;
    i = 0;
    [/INDENT]//Preenche o array posicao com o valor 20 em 16 indices para evitar 
    //problemas ao comparar com campos vazios mais tarde. O valor escolhido 
    //foi 20 para assim não estar no intervalo que será gerado evitando 
    //qualquer problema com os primeiros valores gerados[INDENT] while (i < 16) {[INDENT] posicao[i] = 20;
    i++;
    [/INDENT]}
    [/INDENT]//Ciclo que gera um valor aleatório para sortear as equipas
    //e faz a verificação de equipas repetidas[INDENT] while (sort < 16) {[INDENT] ver = 0;
    i = 0;
    posicao[sort] = (int) (Math.random()*16); 
    [/INDENT]//Verifica se uma equipa já foi anteriormente sorteada comparando 
    //o índice em análise do array posicao com todos os índices existentes 
    //do mesmo array. A variável ver vai registar a quantidade de vezes 
    //que a equipa foi encontrada[INDENT] while (i < sort) {[INDENT] if (posicao[sort] == posicao[i]) {[INDENT] ver++;
    break;
    [/INDENT]}
    [/INDENT]i++;
    }
    [/INDENT]//Analisa o resultado do contador ver. Se o valor for zero significa 
    //que o valor gerado é novo e será registado, incrementando um valor 
    //no contador do while, fazendo com que o programa avance um índice. 
    //Caso este seja superior, o contador não sofre qualquer aletração 
    //obrigando o ciclo a repetir-se e assim gerar outro valor[INDENT] if (ver == 0) {[INDENT] sort++;
    [/INDENT]}
    [/INDENT]}
    [/INDENT]//Regista os resultados do array posicao que teoricamente devem ter 
    //todos um valor único entre 0 e 15[INDENT] pos1 = equipas[posicao[0]];
    pos2 = equipas[posicao[1]];
    pos3 = equipas[posicao[2]];
    pos4 = equipas[posicao[3]];
    pos5 = equipas[posicao[4]];
    pos6 = equipas[posicao[5]];
    pos7 = equipas[posicao[6]];
    pos8 = equipas[posicao[7]];
    pos9 = equipas[posicao[8]];
    pos10 = equipas[posicao[9]];
    pos11 = equipas[posicao[10]];
    pos12 = equipas[posicao[11]];
    pos13 = equipas[posicao[12]];
    pos14 = equipas[posicao[13]];
    pos15 = equipas[posicao[14]];
    pos16 = equipas[posicao[15]];
    [/INDENT]}
    Nunca usei ActionScript, mas diria que assim deveria funcionar.
    PS.: Quando ele vai ver se já existe, não precisa de ver as posições à frente do sort. NEM a do Sort (obviamente vai ser igual e nunca sai!)
    Problema resolvido.
    ex.: posicao[0] = 10
    posicao[0] == posicao[0] ? Obvio que sim, e nunca vai sair do while.
     
    Última edição pelo moderador: 21 de Abril de 2008
  13. Rexobias

    Rexobias Power Member

    anjo2, muito obrigado pela ajuda, mas é ActionScript e não JavaScript :D

    andre, apliquei o teu código e nada, dá o mesmo aviso de ciclo infinito. Nesse aviso posso escolher para cancelar ou continuar ... a primeira cancela e se escolher a segunda, bloqueia...

    Código:
    on (release){
     
     //Declaração de variáveis
     var sort, aleat, i: Number;
     var sorteado = new Array();
     var equipas = new Array();
     
     //Iniciação de variáveis
     equipas[0] = "FC Porto";
     equipas[1] = "SL Benfica";
     equipas[2] = "Sporting";
     equipas[3] = "Manchester Utd.";
     equipas[4] = "Arsenal";
     equipas[5] = "Chelsea";
     equipas[6] = "AC Milan";
     equipas[7] = "Inter";
     equipas[8] = "Juventus";
     equipas[9] = "Barcelona";
     equipas[10] = "Real Madrid";
     equipas[11] = "PSG";
     equipas[12] = "O.Lyon";
     equipas[13] = "Bayern Munchen";
     equipas[14] = "Werder Bremen";
     equipas[15] = "Celtic";
     sort = 0;
     i = 0;
     
     while (i < 16)
      {
      aleat = Math.floor(Math.random()*15); 
         if (equipas[aleat] != null)
          {
                sorteado[i] = equipas[aleat]; 
                equipas[aleat] = null;
                i = i + 1;
          }
      }
     //Regista os resultados do array posicao que teoricamente devem ter 
     //todos um valor único entre 0 e 15 
     pos1 = sorteado[0];
     pos2 = sorteado[1];
     pos3 = sorteado[2];
     pos4 = sorteado[3];
     pos5 = sorteado[4];
     pos6 = sorteado[5];
     pos7 = sorteado[6];
     pos8 = sorteado[7];
     pos9 = sorteado[8];
     pos10 = sorteado[9];
     pos11 = sorteado[10];
     pos12 = sorteado[11];
     pos13 = sorteado[12];
     pos14 = sorteado[13];
     pos15 = sorteado[14];
     pos16 = sorteado[15];
     
    }
    Tou a começar a pensar que deve ser alguma limitação ou diferença de syntax's no Flash/ActionScript (embora o compilador do Flash dizer que está tudo correcto), pois ambos os algoritmos estão correctos e deviam funcionar.
     
    Última edição pelo moderador: 21 de Abril de 2008
  14. andrepadez

    andrepadez Power Member

    Tens a certeza que isto está correcto???

    Código:
     
    aleat = Math.floor(Math.random()*15); 
    
    não consigo encontrar nada ali que gere um ciclo infinito. e este random, é o único elemento comum
     
  15. anjo2

    anjo2 Power Member

    Tinha-me enganado no nome, mas o que dei não funciona?!?!?!?

    O que estás a por não vai fazer o trabalho, mas se quiseres posso-te dar outra solução...
     
  16. Karski

    Karski Power Member

    Só um aparte. Quando geras um numero aleatorio, vais ter de comparar com os que já sairam. Não podes tirar 2 vezes a mesma equipa :)

    Em relação ao código não conheço muito bem Actionscript, mas eu mudava os While para Ciclos For, pois assim garantes que sais sempre dos ciclos.
     
  17. Rexobias

    Rexobias Power Member

    andre, sim está correcto, pois já testei e foi copiado de um outro trabalho meu :D

    anjo2, terei que adaptar e ver, mas se o meu e o do andre não funcionam sem razão aparente. Amanha expremento.

    Karski, é isso mesmo que é feito. Em relação aos For, os While vão dar ao mesmo penso eu), mas amanha expremento...
     
  18. anjo2

    anjo2 Power Member

    Não pode, porque se já existir, vai ter que gerar outro e ver de novo se já existe.
     
  19. Mitnick

    Mitnick Power Member

    Muda o Math.floor para Math.random... Ele da-te ciclo infinito porque com o Math.floor nunca te vai gerar a posicao 0.
     
  20. anjo2

    anjo2 Power Member

    Leste o meu post? Eu disse onde o teu ficava, nem sai da posição 0.
     

Partilhar esta Página