Erro ao utilizar sequencia de números aleatórios - RESOLVIDO

3 respostas
E

Boa noite
Comecei a fazer um jogo (spider solitaire) em J2ME. Para tanto, criei um método que gera uma sequencia de números inteiros aleatórios sem repetição (geraSeqAleatoria()). Dentro do método run eu tenho o método inicializaJogo que chama o método geraSeqAleatoria(). Estou usando o NetBeans. O problema é que a lista de aleatórios não é passada de um método para o outro. Se eu faço no eclipse (J2SE) dá certo. Não aparece nenhum erro, simplesmente não é impressa na tela. Tenho a impressão de ser algum problema relacionado à capacidade de memória (me corrijam se eu estiver falando besteira). Já fiz diversas tentativas e nem sei onde atacar.

Se alguém puder testar pra mim, eu envio a imagem do sprite por e-mail ([email removido])

Vou postar o código juntamente com toda a configuração que utilizei:

Netbeans 6.7 - J2ME - CLDC 1.1 MIDP - 2.0

ClasseMeuCanvas.java

import java.io.IOException;
import java.util.Random;
import javax.microedition.lcdui.game.*;
import javax.microedition.lcdui.*;

public class ClasseMeuCanvas extends GameCanvas implements Runnable {

    Thread meuThread;
    Graphics meuGrafico = this.getGraphics();
    Image baralho;
    Sprite[] carta = new Sprite[56];
    LayerManager meuLayerManager;

    public ClasseMeuCanvas() {
        super(false);
        meuThread = new Thread(this);
        meuThread.start();
    }

    public void determinaCartas() {
        try {
            baralho = Image.createImage("/images/baralho.png");
             int[] sprite = new int[55];
            for (int i = 0; i <= 54; i++) {
                sprite[i] = i;
            }            for (int j = 0; j <= 5; j++) {

                for (int i = 0; i <= 9; i++) {

                    carta[j * 10 + i] = new Sprite(baralho, 15, 20);
                    carta[j * 10 + i].setFrameSequence(sprite);
                    carta[j * 10 + i].setFrame(j * 10 + i);

                    if (j * 10 + i > 52) {
                        break;
                    }
                }
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public int[] geraSeqAleatoria(int tamanho) {
        Random random = new Random();
        int i = 0;
        int aux = 0;

        int[] seqAleatoria = new int[tamanho]; //array vazia {0,0,0,.....}
        while (i <= tamanho) {
            boolean repete = false;
            aux = random.nextInt(tamanho);   //gera um número aleatório, por ex.  3

            for (int j = 0; j <= tamanho - 1; j++) { //percorre a seqAleatorio pra ver se tem o 3
                if (aux == seqAleatoria[j]) {
                    repete = true;
                    break;                      // se encontra sai do laço
                } else {
                    continue;   //se não encontra percorre a array até o final e repete é false
                }
            }

            if (repete == false) {
                seqAleatoria[i] = aux;
                System.out.println(seqAleatoria[i]);
                i++;
            }

        }
        System.out.println(seqAleatoria);
        return seqAleatoria;
    }

    public void inicializaJogo() {
        meuLayerManager = new LayerManager();
        meuLayerManager.append(carta[1]);
        carta[1].setPosition(10, 10);
        geraSeqAleatoria(10);

    }

    public void run() {

        determinaCartas();
        inicializaJogo();

        boolean fimDeJogo = false;
        while (fimDeJogo == false) {
            try {
                meuLayerManager.paint(meuGrafico, 0, 0);
                meuThread.sleep(50);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } finally {

                flushGraphics();
            }
        }
    }
}

Midlet.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.*;

/**
 * @author Professor
 */
public class Midlet extends MIDlet {

    Display meuDisplay = Display.getDisplay(this);
    ClasseMeuCanvas meuCanvas = new ClasseMeuCanvas();

    public void startApp() {
        meuDisplay.setCurrent(meuCanvas);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

3 Respostas

V

Esse método está extremamente ineficiente. Ele percorre a lista várias vezes, e pode ser que demore muito até sortear um número que não esteja nela, principalmente quando a lista estiver praticamente cheia.

Eis uma versão muitíssimo mais eficiente dele. Nela é garantido que a lista será percorrida exatamente duas vezes:

public int[] geraSeqAleatoria(int tamanho) {
      Random random = new Random();

      // Array em ordem
      int[] seqAleatoria = new int[tamanho];
      for (int i = 0; i < tamanho; i++) {
         seqAleatoria[i] = i;
      }

      // Embaralhamos o array
      for (int i = 0; i < tamanho - 1; i++) {
         int max = tamanho - i - 1;
         int ind = random.nextInt(max);

         int aux = seqAleatoria[ind];
         seqAleatoria[ind] = seqAleatoria[max];
         seqAleatoria[max] = aux;
      }
      return seqAleatoria;
   }

Basicamente a modificação é gerar uma sequencia em ordem e embaralha-la através do seguinte algoritmo:

1. Sorteie um número do indice 0 até o tamanho da sequencia ordenada-2;
2. Troque esse número com o do último índice. O do último índice agora está embaralhado;
3. Repita o passo 1 até a sequencia estar toda embaralhada;

Exemplo: Para a sequencia de 10 números:
[color=brown]0 1 2 3 4 5 6 7 8 9[/color] -> Sorteamos um número de 0 até 9 -> 4
0 1 2 3 [color=red]4[/color] 5 6 7 8 [color=blue]9[/color] -> Trocamos o elemento 4 com o último índice ordenado ( 9 )
0 1 2 3 9 5 6 7 8 [color=green]4[/color] -> O último índice encontra-se embaralhado
[color=brown]0 1 2 3 9 5 6 7 8[/color] 4 -> Sorteamos um número de 0 até 8 -> 1
0 [color=red]1[/color] 2 3 9 5 6 7 [color=blue]8[/color] 4 -> Trocamos o elemento 1 com o último índice ordenado ( 8 )
0 8 2 3 9 5 6 7 [color=green]8 4[/color] -> Os últimos índices encontram-se embaralhados.

Repetimos o processo até percorrermos o array todo. Isso garante muito mais performance e boa distribuição.

Talvez o problema seja que num dispositivo lento, seu método está demorando demais a executar. Tente substituir por essa versão bem mais rápida e teste. Não coloquei dentro do método o println que imprime a sequencia.

E

então era o problemas de memória mesmo por ineficiência do código. Nem sei como agradecer Vini. Muito obrigada mesmo!

Esther :smiley:

V

Memória não era, era só velocidade de execução mesmo.

Mas que bom que o problema foi resolvido. :slight_smile:

Criado 24 de janeiro de 2011
Ultima resposta 24 de jan. de 2011
Respostas 3
Participantes 2