2016-03-17 1 views
-1
JButton[][] buttons = new JButton[20][20]; 
public void mines(){ 
    ArrayList<Integer> x = new ArrayList<>(); 
    ArrayList<Integer> y = new ArrayList<>(); 
    for(int a=0;a<20;a++){ 
     x.add(a); 
     y.add(a); 
    } 
    for(int i=0;i<30;i++){ 
    int random_x = x.get(new Random().nextInt(x.size())); 
    int random_y = y.get(new Random().nextInt(y.size())); 
    x.remove(random_x); 
    y.remove(random_y); 
    buttons[random_x][random_y].setText("X"); 
    } 
} 

Je veux créer des mines au hasard pour un dragueur de mines game..can quelqu'un dire ce que je fais mal? Si je lance le programme, il ne sera pas me montrer 30 mines au hasardcréer des mines au hasard pour un jeu de démineur

+0

est-ce pas un NPE? A moins que les valeurs de 'buttons' ne soient initialisées quelque part. – bcsb1001

+0

Pourquoi traitez-vous x et y séparément? Sûrement vous voulez enlever 30 paires aléatoires, pas 30 coordonnées x aléatoires et 30 coordonnées y aléatoires. –

+0

ils sont initialisés quelque part –

Répondre

0

Essayez cette méthode:

public static void mines(JButton[][] buttons) 
{ 
    Random rand = new Random(); 
    int mineCount = 0; 
    while (mineCount < 30) 
    { 
     int randomInteger = (int) (rand.nextDouble() * buttons.length); 
     int randomInteger2 = (int) (rand.nextDouble() * buttons[0].length); 
     if (buttons[randomInteger][randomInteger2].getText().equals("X")) 
      continue; 
     else 
     { 
      buttons[randomInteger][randomInteger2].setText("X"); 
      mineCount++; 
     } 
    } 

} 

.nextDouble() La méthode renvoie une valeur double inférieure à 1,0. Mais nous avons besoin d'un entier aléatoire entre 0 et 19 (qui est buttons.length -1). Nous multiplions donc cette double valeur aléatoire par la taille de la liste des boutons, qui est 20, et nous la transformons en int. Nous pouvons donc obtenir des valeurs comprises entre 0 et 19.La différence entre buttons.length et buttons[0].length est, avec le premier vous obtenez la longueur de la première dimension (c'est un tableau à deux dimensions, comme vous le savez) et le second donne la longueur de la deuxième dimension. Donc, vous obtenez le nombre dynamiquement et multipliez avec le nombre aléatoire, pour éviter l'exception ArrayIndexOutOfBounds.

Vous pouvez utiliser cette méthode avec n'importe quelle taille de tableau de boutons en deux dimensions, cela fonctionnera. Mais attention, si vous utilisez un tableau qui a moins de 30 boutons, alors boucle continuera pour toujours, car vous ne pouvez pas obtenir 30 mines :)

Une façon d'améliorer cette méthode serait de paramétrer mineCount, donc vous pouvez changer la méthode comme public static void mines(JButton[][] buttons, int mineCount) de sorte que vous pouvez définir le nombre de mines sur appel de méthode.

+0

cela ne fonctionne pas –

+0

J'ai fait mettre à jour le code 2 fois. Êtes-vous sûr d'avoir essayé le dernier? Et, je ne pense pas que cela ne marche pas, quelle erreur obtenez-vous? – ferit

+0

ne peut pas trouver la méthode length() .. boutons de variable de type JButtons [] [] –

0

Ce ici:

for (int i = 0; i < 30; i++) { 
    int random_x = x.get(new Random().nextInt(x.size())); 
    int random_y = y.get(new Random().nextInt(y.size())); 
    x.remove(random_x); 
    y.remove(random_y); 
.... 

va générer un IndexOutOfBoundsException certains quand ....

Votre liste ont 20 éléments et vous êtes re en déplaçant 30 fois l'élément ...

+0

Pourquoi est-ce? .. dans la console il ne dit rien sur IndexOutOfBoundsException –

+0

hmmm ... peut-être parce que je l'ai à prendre 30 mines .. mais dans l'arraylist de x et yi ont seulement 20 ints et chaque fois qu'il faut un ça l'élimine ... à un moment donné, l'arrayliste sera vide? –

0

Vos coordonnées aléatoires peuvent être plus grandes que la taille de votre grille. Si la taille de x est 20, et votre random_x est également 20, vous aurez un IndexOutOfBoundsException.

Modifier à:

int random_x = x.get(new Random().nextInt(x.size() - 1)); 
int random_y = y.get(new Random().nextInt(y.size() - 1)); 

qui vous donnera un nombre aléatoire entre 0 et 19, si la taille est 20.

De plus, parce que votre liste est de type Integer, l'appel x.remove(random_x) est l'interpréter comme l'index dans la liste, pas l'objet lui-même.

Pour résoudre ce problème, utilisez un Integer et non un int lorsque vous appelez remove(). Tels que:

x.remove(Integer.valueOf(random_x)); 

Edit: Pour améliorer encore/fixer le générateur aléatoire, changez-le:

int random_x = x.get(new Random().nextInt(x.size() == 1 ? 1 : x.size() - 1)); 

Lors d'un essai avec l'extrait suivant:

Test t = new Test(); 
t.mines(); 

for (int i = 0; i < 20; i++) 
{ 
    for (int j = 0; j < 20; j++) 
    { 
     if ("X".equals(t.buttons[i][j].getText())) { 
      System.out.println("x:" + i + ", y:" + j); 
     } 
    } 
} 

Donne la sortie: x: 0, y: 18 x: 1, Y: 5 x 2, y: 1 x 3, y 3 x 4, y: 9 x: 5, y: 15 x : 6, y: 14 x: 7, y: 10 x: 8, y: 8 x: 9, y: 11 x: 10, y: 16 x: 11, y: 17 x: 12 , y: 0 x: 13, y: 7 x: 14, y: 4 x: 15, y: 12 x: 16, y: 2 x: 17, y: 6 x: 18, y : 13 x: 19, y: 19

+0

J'ai essayé encore ne change pas le texte des boutons en X donc je suppose que cela ne fonctionne pas –

+0

@BaiRadule Si le texte ne change pas, alors je soupçonne que le problème est ailleurs. – starf

+0

je vois .. chose intéressante avec la suppression de la valeur..Merci! –

1

Vous avez choisi un modèle inhabituel pour conserver des informations sur l'emplacement des mines. Bien que vous résolviez probablement le problème immédiat grâce à un débogage judicieux, je m'attends à ce que cela vous cause d'autres problèmes en cours de route.

Je suggère de changer votre modèle à quelque chose de plus direct, comme:

class Cell { 
    private final JButton button = new JButton(); 
    private boolean mine = false; 
    private boolean hidden = true; 

    public Cell() { 
     button.setText(" "); 
    } 

    public void setMine() { 
     assert hidden; 
     mine = true; 
    } 

    public boolean hasMine() { 
     return mine; 
    } 

    public void reveal() { 
     hidden = false; 
     button.setText(mine ? "X" : "-"); 
    } 

    public boolean isHidden() { 
     return hidden; 
    } 
} 

class Field { 
    public static final int SIZE = 20; 

    private final Cell[][] cells = new Cell[SIZE][SIZE]; 

    public Field(int minesToAdd) { 
     for (int x = 0; x < SIZE; ++) { 
      for (int y = 0; y < SIZE; y++) { 
       cells[x][y] = new Cell(); 
      } 
     } 
     Random random = new Random(); 
     while (minesToAdd > 0) { 
      Cell cell = cells[random.nextInt(SIZE)][random.nextInt(SIZE)]; 
      if (!cell.hasMine()) { 
       cell.setMine(); 
       minesToAdd--; 
      } 
     } 
    } 

    public JPanel getButtonPanel() { 
     .... 
    } 
} 

Je crois que ferait votre intention plus claire. Il y a quelques problèmes avec ceci comme le lien étroit entre le modèle et la présentation (JButton) mais c'est entièrement fixable avec différents modèles de conception.

0

Vous pouvez essayer avec ceci:

int x = 20; 
int y = 20; 
JButton[][] buttons = new JButton[x][y]; 

public void mines(){ 
    int mines = 30; 
    Random rand = new Random() 
    while(mines>0){ 
     int random_x = rand.nextInt(x); 
     int random_y = rand.nextInt(y); 
     if(buttons[random_x][random_y]!=null){ 
      buttons[random_x][random_y] = new Button(); 
      buttons[random_x][random_y].setText("X") 
      mines--; 
     } 
    } 
}