# Zufallsgenerator   nicht richtig



## Borsty (14. Juni 2004)

Hallo, wir ich bin dabei ein kleines "Schatzsuche" spiel zu programmieren und will 40 Schätze auf ein Spielfeld von 15x15 verteilen!

Jedoch werden die Schätze zwar in zufälliger y Werte eingetragen , doch sind die X-Were immer gleich. So entstehen immer senkrechte Reihen mit Schätzen. Wo steckt der Fehler

```
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import java.math.*;


public class Schatzsuche_02 extends Applet
{
  Button startBut;
  final int sand                = 0;
  final int kein_schatz         = 1;
  final int schatz              = 2;
    
  final int felderPS            = 15;
  final int pixelPS             = 450;
  final int pixelPF             = 30;
  

  int xzuf = 0;
  int yzuf = 0;
  
  int y = 0;
  int x = 0;
  
  int xpos = 0;
  int ypos = 0;
  
  int x30 = 0;
  int y30 = 0;
  
  int xposfeld = 0;
  int yposfeld = 0;
  
  int yposm3 = 0;
  int xposm3 = 0;

  
  public int xposm = 0;
  public int yposm = 0;
  
  Graphics g0;

  Random Zufallsgenerator = new Random();
    
  int feld[][]  = new int [felderPS][felderPS];

  Image sand_img;
  Image kein_sand_img;
  Image schatz_img;
    
//Felder füllen mit Bildern
  public void init () {
    startBut = new Button(" Start ");
  add(startBut);
    g0 = getGraphics();
    sand_img           = getImage(getCodeBase(), "bilder/sand.gif");
    kein_sand_img      = getImage(getCodeBase(), "bilder/nicht_sand.gif");
    schatz_img         = getImage(getCodeBase(), "bilder/schatz.gif");
    
    startBut.addActionListener(new ActionListener()
    {
    public void actionPerformed (ActionEvent e) {

    for (x=0; x < 40; x++) {
    int xzufall1 = (int) (14* Math.random());
    int yzufall1 = (int) (14* Math.random());
    
    int yzuffall = yzufall1;
    int xzuffall = xzufall1;
    

    if (feld[yzufall][xzufall] == 2) {
       x--;
   }
    else
       feld[yzufall][xzufall] = 2;
   }
   for (yzuf=0; yzuf < 14; yzuf++){
     for (xzuf=0; xzuf < 14; xzuf++) {
       if (feld[yzuf][xzuf] != 2) {
          feld[yzuf][xzuf] = 1;
       }
     }
   }
   }

    });

    
     addMouseListener(new MouseAdapter()
    {
     public void mousePressed(MouseEvent e)
  {
    xposm = e.getX();
    yposm = e.getY();


    test();

    }


  });
    }



     public void paint(Graphics g) {


    int xpos, ypos;
    Dimension d = this.getSize();

    for (x=0; x < felderPS; x++) {
      for (y=0; y < felderPS; y++) {
      xpos = x * pixelPF;
      ypos = y * pixelPF;

         g.drawImage(sand_img, xpos, ypos, this);
         


     }
   }
 }
 


 public void test()
 {

   xposfeld = xposm/pixelPF;
   yposfeld = xposm/pixelPF;
   
   if(feld[xposfeld][yposfeld] == 2)
    {
     xposm3 = xposm/pixelPF;
     yposm3 = yposm/pixelPF;

     xposm3 = xposm3*pixelPF;
     yposm3 = yposm3*pixelPF;
    
     g0.drawImage(schatz_img, xposm3, yposm3, this);

    }
   else
    {
     xposm3 = xposm/pixelPF;
     yposm3 = yposm/pixelPF;

     xposm3 = xposm3*pixelPF;
     yposm3 = yposm3*pixelPF;

     g0.drawImage(kein_sand_img, xposm3, yposm3, this);
    }
  }

}
```

Ich freue mich über jeden Hinweis

Danke im voraus


----------



## Borsty (14. Juni 2004)

Eine Zip datei mit passenden Bildern habe ich euch mal angehängt


----------



## Franz Degenhardt (14. Juni 2004)

Hallo!

Ich hab deine actionPerfomed etwas umgeschrieben und mit Ausgaben getestet ob alles stimmt.

```
public void actionPerformed(ActionEvent e) {

				for (x = 0; x < 40; x++) {
					int xzufall = Zufallsgenerator.nextInt(14);
					int yzufall = Zufallsgenerator.nextInt(14);
					while (feld[yzufall][xzufall] == 2) {
						xzufall = Zufallsgenerator.nextInt(14);
						yzufall = Zufallsgenerator.nextInt(14);

					}
					feld[yzufall][xzufall] = 2;
					
				}
				for (yzuf = 0; yzuf < 14; yzuf++) {
					for (xzuf = 0; xzuf < 14; xzuf++) {
						if (feld[yzuf][xzuf] != 2) {
							feld[yzuf][xzuf] = 1;
						}
						//System.out.print(" "+ feld[yzuf][xzuf] + " ");
					}
					//System.out.print("\n");
				}
			}
```

Wahrscheinlich war die Logik vorher schon richtig. Der Fehler liegt in 

```
public void test()
 {

   xposfeld = xposm/pixelPF;
   yposfeld = xposm/pixelPF;
 ...
```
Da muss natürlich '   yposfeld = *y*posm/pixelPF;' hin.

Entwirf beim nächsten mal bessere Testcases um den Fehler einzugrenzen. War ja nix schwieriges. Den restlichen Code hab ich nur überflogen. Da scheinen mir einige Variablen zu viel drinn zu sein. Je weniger Variable du benutzt, desto leichter sind nacher Grösse usw zu ändern.

Grüsse TrueSun


----------



## Franz Degenhardt (14. Juni 2004)

Hey!

Leicht verbesserte Version. Wie dir sicher aufgefallen ist, hat ein repaint dir immer das ganze Feld kaputt gemacht. Dazu hab ich die Methode update überschrieben.


```
import java.applet.Applet;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

public class Schatzsuche_02 extends Applet {
	private Button startBut;
	private final int sand = 0;
	private final int kein_schatz = 1;
	private final int schatz = 2;

	private final int pixelPS = 450;
	private final int pixelPF = 30;

	private final int anzSchaetze = 40;
	private final int rows = 15;
	private final int colums = 15;

	private Graphics g;
	private Random Zufallsgenerator = new Random();
	private int feld[][] = new int[rows][colums];
	private Image sand_img, kein_sand_img, schatz_img;
	private boolean isNew = true;

	//Felder füllen mit Bildern
	public void init() {
		setSize(rows * pixelPF, colums * pixelPF);
		g = getGraphics();
		startBut = new Button(" restart ");
		add(startBut);
		sand_img = getImage(getCodeBase(), "bilder/sand.gif");
		kein_sand_img = getImage(getCodeBase(), "bilder/nicht_sand.gif");
		schatz_img = getImage(getCodeBase(), "bilder/schatz.gif");

		startBut.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				isNew = true;
				initField();
				repaint();
			}
		});

		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				isNew = false;
				test(e.getX(), e.getY());
			}
		});
		initField();
	}

	public void initField() {
		for (int i = 0; i < anzSchaetze; i++) {
			int xzufall = Zufallsgenerator.nextInt(rows);
			int yzufall = Zufallsgenerator.nextInt(colums);
			while (feld[yzufall][xzufall] == schatz) {
				xzufall = Zufallsgenerator.nextInt(rows);
				yzufall = Zufallsgenerator.nextInt(colums);
			}
			feld[yzufall][xzufall] = schatz;
		}
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < colums; j++) {
				if (feld[i][j] != schatz) {
					feld[i][j] = kein_schatz;
				}
				//System.out.print(" "+ feld[yzuf][xzuf] + " ");
			}
			//System.out.print("\n");
		}
	}

	public void update(Graphics _g) {
		if (isNew) {
			paint(_g);
		}
	}

	public void paint(Graphics g) {

		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < colums; j++) {
				g.drawImage(sand_img, i * pixelPF, j * pixelPF, this);
			}
		}
	}

	public void test(int _x, int _y) {
		int posX = _x / pixelPF;
		int posY = _y / pixelPF;
		if (feld[posX][posY] == schatz) {
			g.drawImage(schatz_img, posX * pixelPF, posY * pixelPF, this);
		} else {
			g.drawImage(kein_sand_img, posX * pixelPF, posY * pixelPF, this);
		}
	}
}
```

Was sonst noch auffällt, es werden nun keine sogennanten "magic numbers" mehr benutzt. D.h. es wird innerhalb der Methoden nur noch auf Variablen zugegriffen, so laufen die Schleifen nun nicht mehr bis zu einem 'harten' endwert.

hf TrueSun


----------



## Borsty (15. Juni 2004)

WOW, geil, und auch noch soo schnell

Danke an euch beide


----------



## Franz Degenhardt (15. Juni 2004)

Nett das du mich in der Mehrzahl anredest 

Gern geschehen.


----------

