Einfaches Würfelprogramm in Java

5 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Die Chance ist so ziemlich gleich.

Computer kennen keinen Zufall. Das was du als Math.random() benutzt ist eigentlich die aktuelle Systemzeit, die mathematisch so verunstaltet wurde, dass man sie als pseudozufällige Zahl verwenden kann.

Ich finde deinen Code übrigens sehr ineffizient.


suppenfisch1999  01.11.2013, 16:59

Na ja, das mit der verunstalteten aktuellen Zeit stimmt nicht ganz. Schließlich tritt Math die Funktion an Random ab und der arbeitet mit Seeds. Und den Seed kann man auch unabhängig von der Zeit setzten

0

Ja, ist ja nicht mal ne Zufallszahl sondern die Systemzeit . dein code ist übrigens schwer verbesserungswürdig . das leichteste wäre wohl Zahl + " gewürfelt"


PerfectMuffin  31.10.2013, 17:31

System.out.println(1); druckt aber nicht "eins", weißt du? :P

Man könnte es aber mit Arrays machen.

0
procoder42  31.10.2013, 18:28
@PerfectMuffin

Ich könnte auch ne hashmap dafür nehmen weist du . um das ganze schöner zu machen würde ich die 1 Stadt der eins in Kauf nehmen

0

Die anderen Antwortenden hier unterschätzen die Arbeitsweise der Math.random()-Funktion. Klar, es ist eine Pseudo-Zufallszahl, das heißt aber, dass eine sehr sehr lange Reihe von gleichverteilten Zufallszahlen zwischen 0 und 1 entsteht. Die könnte man zwar theoretisch zurückberechnen, praktisch entwickelst du aber keine sicherheitskritische Anwendung, kannst also ganz beruhigt weiter zu Math.random greifen - schon allein, weil die Funktion performanter arbeitet als andere Verfahren. Die lange Reihe ist auch kein Problem, da müsstest du schon ein paar Milliarden mal würfeln, bis sich die Zahlen wiederholen. Es gibt zwar auch Methoden zur Erzeugung wirklich zufälliger Zahlen (etwa ein Zugriff auf die Daten von random.org oder unter Linux-System etwa dev/random oder dev/urandom), aber das muss dich bei deinem Stand nicht weiter interessieren, nimm weiter Math.random!

Lösen würde ich das Problem aber auch mit einem Array

String[] worte = {"Eins","Zwei","Drei","Vier","Fünf","Sechs"};
int zahl = (int)(Math.random()*6);
System.out.println(worte[zahl]+" gewürfelt");

ich hätte es so gemacht:

int x = new Random.nextInt(6); //Zufallszahl zwischen 0 und einschließlich 5
String[] zahlen = { "Eins","Zwei","Drei","Vier","Fünf","Sechs" };
System.out.println(zahlen[x] + " gewürfelt");

Die Klasse Random ist für Zufallszahlen viel besser als Math, da Math nur einen Double von null bis eins liefert.

Deine Version geht auch, ist aber komplizierter. Ob der Würfel "gezinkt" ist, kann ich dir nicht 100%ig mit nein beantworten (meine Vermutung ist, dass du das Zeichen "<=" verwenden solltest, da wenn x 1 ist fällt 1*6 < 6 durch), aber mit Random ist er es auf jeden fall nicht;

Zu Random. Random verwendet "Seeds" wenn du den Seed 0 eingeibst (new Random(0)), und 20 mal random.nextInt(6) ausgibst, erhälst du jedes Mal eine andere (zufällige) Zahl, aber wenn du das Programm startest, wird er jedes Mal die gleichen "Zufallszahlen" ausgeben. Daher wird im Standartkonstruktor einfach die aktuelle Zeit als Seed gesetzt, wodurch du bei jedem Start einen anderen Seed hast.

Im Endefekt sind es keine "echten" Zufallszahlen, aber der Würfel (jedenfalls mit der Random-Klasse) ist garantiert nicht gezinkt (habs getestet)


suppenfisch1999  01.11.2013, 16:33

Hier ist das Programm um das zu testen. Der Code ist sehr alt und kommt noch aus Anfängerzeiten. Die Zeitberechnung bitte ignorieren:)

Zum Benutzen: Kompilieren, einen Würfel auswählen und 1.000.000 Versuche machen. Schau dann mal, wie oft welche Zahl gewürfelt wurde

import java.util.*;
import java.awt.*;

class Analyst {
public static void main(String[] args) {

Scanner scan = new Scanner( System.in );
Random rnd = new Random();
int rand;
int anzwuerfel = 0;
int anzwuerfe = 0;    
int [] stats;
int i = 0;
int j = 0;
int k = 0;
int l = 0;
int temp = 0;

long first;
long last;
long [] diff;
long diffsumme;
double schnitt;
double teilschnitt;
double rundschnitt;

double min = 0;
double sek = 0;
double zeit = 0;
long mingerundet;

boolean std = true;

System.out.println("Wie viele Wuerfel sollen verwendet werden? (1-6) ");
anzwuerfel = scan.nextInt();

System.out.print("Wie viele Versuche? (1 - 1.000.000) ");
anzwuerfe = scan.nextInt();
first = System.nanoTime();
last = first; 

stats = new int[anzwuerfe * 6 + 1];
diff = new long[anzwuerfe + 1]; 

schnitt = 0;
teilschnitt = 0;
k = 0;
l = 994;
rundschnitt = 0.0f;
diffsumme = 0;

while (i < anzwuerfe) {    //Schleife für Versuche
  diff[i] = System.nanoTime() - last;      
  last = System.nanoTime();
  if (i > 5 && anzwuerfe >= 10) {
    diffsumme = 0;
    while (k <= i) { 
      diffsumme += diff[k];
      k++;
    } // end of while
    schnitt = diffsumme / i;
    k = 5;
  } // end of if
  if(l == 1000) {
    rundschnitt = schnitt;
    l = 0; 
  }
  l++;
  while (j < anzwuerfel) {
    temp += (rnd.nextInt(6)+1);
    j++;        
  } // end of for
  min = ((rundschnitt * (anzwuerfe - i))/1000000000) / 60;
  sek = ((rundschnitt * (anzwuerfe - i))/1000000000);
  if(min >= 5) { 
    zeit = Math.round(min*100)/100.0;
    System.out.println("Anteil: " + i*100/anzwuerfe + "%\tGeworfen: " + temp + "\tStats: " + stats [temp] + "\tRestzeit: " + zeit + " Minuten");
  } else {
    zeit = Math.round(sek);
    System.out.println("Anteil: " + i*100/anzwuerfe + "%\tGeworfen: " + temp + "\tStats: " + stats [temp] + "\tRestzeit: " + zeit + " Sekunden");
  }

  stats [temp] += 1; 
  j=0;    
  temp = 0;
  i++;
}
System.out.println("\n\n\n\nAuswertung:\tWuerfe: " +anzwuerfe + " \tWuerfel: " + anzwuerfel);
System.out.println("\tBenoetigte Zeit: " + (System.nanoTime()-first)/1000000000 + " Sekunden\tIn Minuten: " + Math.round(((System.nanoTime()-first)/10000000)/60)/100 + " Minuten");
System.out.println("\tDurchschnittszeit pro Rechendurchgang: " + schnitt + " Nanosekunden\n\tDas sind " + schnitt/1000000 + " Sekunden pro 1000 Rechendurchgaenge\n");
//System.out.println("\tBenoetigte Zeit: " + schnitt/1000000000) + "Sekunden");


i = 0;
while (i <= (anzwuerfel*6)) {
  if (i >= anzwuerfel) {
    System.out.println("Zahl: " + i + " \tGeworfen: " + stats[i] + "x \tAnteil: " + (100 * stats [i] / anzwuerfe) + "%");
  }
  i++;
} // end of while

}
}
0
suppenfisch1999  01.11.2013, 16:36

PS: Ich hab grad nachgeschaut. Hier die random()-Funktion aus der Klasse Math:

public static double random() {
    Random rnd = randomNumberGenerator;
    if (rnd == null) rnd = initRNG();
    return rnd.nextDouble();            //<--- Das da
}
0

Naja die random-Funktion ist halt nicht "echt" zufällig. Außerdem wäre Dein Code noch zu vereinfachen, indem Du die 6 Schritte in eine Schleife packst.


gamler95 
Beitragsersteller
 31.10.2013, 11:01

Was meinst du mit sie ist nicht "echt" zufällig? Dass man sie noch vereinfachen kann weiß ich. Aber ist die Chance bei jeder Zahl gleich?

0