PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: Lottospiel


Gast
2005-11-24, 11:04:03
Hallo Leute,
Ich hab' mich mal wieder in die Java-Programmierung gehängt und habe nun eine Aufgabe gefunden, wo ich ein Lottospiel (6 aus 49) erstellen soll.

Bei mir werden allerdings pro Ziehung immer nur zufällig eine Anzahl zwischen 1 und 6 Zahlen ausgegeben; beim Lotto müssen aber ja immer 6 Zahlen generiert werden.

Ich finde den Fehler einfach nicht: Hier mal der Code


import java.io.*;

public class lotto {

public static void main (String [] args) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

int zahlenliste [] = new int [49];
int z=0;
int save;
boolean tausche;


// ZUFAELLIGES BESTIMMEN VON 6 ZAHLEN
for (int a=0;a<6;a++) {

int zahl = (int)(Math.random()*49);

for (int c=0; c<1; c++) {
if (zahl == zahlenliste [c])
{zahl = (int)(Math.random()*49);}
else {zahlenliste [a] = zahl;}
}
}

// SORTIEREN DER 6 ZAHLEN
do {
tausche=false;
for (int j=0; j<5; j++) {

if (zahlenliste [j] >zahlenliste [j+1]) {
save=zahlenliste[j];
zahlenliste[j]=zahlenliste[j+1];
zahlenliste [j+1]=save;
tausche=true;
}
}

} while (tausche);


// GENERIERTE ZAHLEN AUSGEBEN
System.out.println("Lottozahlengenerator:");

for (int g=0; g<=6; g++) {
for (int h=0; h<=6; h++) {
if (z+1 == zahlenliste[g]) {
System.out.print(zahlenliste[g]+" ");
}
else {
System.out.print("__"+" ");
}
z++;
}
System.out.println();
}
}
}


Ich hoffe ihr könnt mir helfen.


Gruss

noid
2005-11-24, 11:19:23
kannst du kurz erläutern (im quelltext) was das programm eigentlich tun sollte? mir kommen einige konstrukte sehr seltsam vor (sinnlose schleifen, etc.)

Gast
2005-11-24, 11:24:15
Gut, hier die Aufgabe:

Programmieren Sie einen Lottozahlengenerator (6 aus 49).
Gehen Sie bei der Implementierung so vor, dass Sie in einer Matrix die bereits ermittelten Zahlen markieren. Achten Sie ebenfalls darauf, dass Sie wirklich 6 verschiedene Zahlen ermitteln.
Bereiten Sie ihre Ausgabe ähnlich schmackhaft, wie folgende Beispielsausgabe auf:

Lottozahlengenerator:
01 __ 03 __ __ __ __
__ __ __ __ __ __ __
__ __ __ __ __ __ __
__ __ __ __ 26 __ __
__ __ __ __ 33 __ __
__ __ __ __ __ __ __
__ 44 __ __ __ 48 __


Mit meiner Variante werden halt nicht immer 6 Zahlen ausgegeben, sondern willkürlich Zahlen zwischen 0 und 6.

Trap
2005-11-24, 11:49:06
Dein Code hat gleich mehrere Probleme (aufsteigend sortiert):
1) Es wäre besser java.util.Random.nextInt(int n) zu benutzen im deine Zufallszahlen zu erzeugen
2) Du sortierst mit selbstgeschriebenem Bubblesort
3) Du erzeugst keine Zahlen von 1 bis 49 in Zahlenliste
4) Dein Algorithmus um 6 Zahlen aus 49 auszuwählen ist völlig falsch
5) Deine Ausgabealgorithmus auch

Monger
2005-11-24, 14:01:35
An deiner Stelle würde ich versuchen, das Verhalten einer Lottoziehung wirklich nachzubilden. Ich finde, gerade dieses Beispiel eignet sich besonders gut dafür...

Du hast irgendeinen "Eimer", indem sich 49 Kugeln befinden. Die Kugeln sind von 1 bis 49 beschriftet. Du greifst dir zufällig eine davon raus, und legst sie irgendwo ab.

Mein Ansatz sähe so aus:



// Eimer erzeugen und füllen

ArrayList<Kugel> eimer = new ArrayList<Kugel>();

for(int i = 1; i <=49; i++){

Kugel kugel = new Kugel(i);
eimer.add(kugel);
}

// 6 Kugeln ziehen, und geordnet ablegen

ArrayList<Kugel> kombination = new List<Kugel>();

for(int i = 1; i <= 6; i++){

int zufallsZahl = (int) Math.random() * eimer.size();
Kugel kugel = eimer.get(zufallsZahl);
eimer.remove(kugel);
kombination.add(kugel);
}

// Kombination sortieren

Collections.sort(kombination);

// Kombination ausgeben

for(Kugel kugel : kombination){
System.out.println(kugel.toString());
}

// Kugelklasse

class Kugel implements Comparable<Kugel>{

private int nummer;

public Kugel(int nummer){
this.nummer = nummer;
}

public int compareTo(Kugel anderekugel){
return this.nummer - anderekugel.nummer;
}
public String toString(){
return nummer;
}

}


So ganz zufrieden bin ich mit der Implementierung nicht, weil ein geordneter Eimer dem Lottosystem widerspricht. Eigentlich wäre ein "Set" die richtige Form der Sammlung, aber mir fällt so spontan nicht ein, wie ich per Zufallslosung daraus eine Kugel ziehen soll.

Trap
2005-11-24, 14:34:10
Du machst aus einem int eine Extraklasse mit 17 Zeilen? Ich würde einfach int[] benutzen und mir das Sortieren ganz sparen, sondern einfach jedesmal allen 6 Zahlen durchprobieren.

int[] n = new int[49];
for(int i=0;i<n.length;++i) n[i]=i+1;
Random r = new java.util.Random();
for(int i=0;i<6;++i)
swap(n[r.nextInt(49-i)+i],n[i]); // in java kann man so ein swap natürlich nicht schreiben (also stattdessen ein { int t;...} einfügen)

for(int i=1;i<=49;++i)
for(int j=0;j<6;++j) if(n[j]==i)
System.out.println(i+" ");
else if(j==5) System.out.println("__ ");
Achso, das ist ungetestet und absichtlich hässlich geschrieben ;)

Monger
2005-11-24, 14:42:53
Du machst aus einem int eine Extraklasse mit 17 Zeilen? Ich würde einfach int[] benutzen und mir das Sortieren ganz sparen, sondern einfach jedesmal allen 6 Zahlen durchprobieren.

...
Achso, das ist ungetestet und absichtlich hässlich geschrieben ;)

Du machst aus 17 Zeilen schönem Code 9 Zeilen die kein Mensch mehr lesen kann, inperformant sind und einfach nur "Quick n Dirty" rüberkommen? ;)

Die Kugelklasse ist im Prinzip überflüssig. Afaik macht die int Hüllklasse "Integer" all das und noch viel mehr, und kann genauso sortiert werden. ICh wollte nur mal überdeutlich zeigen, dass man reale Vorgänge sehr schön in objektorientierte Sprachen übertragen kann, ohne dass man völlig quer denken muss.

Dass ich eine ArrayList statt einem Array nehme, hat seinen Grund. Die einfachste Methode, ein ziehen ohne zurücklegen zu simulieren ist, tatsächlich aus einer Menge etwas rauszunehmen und nicht wieder zurückzulegen. In einem int [] musst du zwangsläufig eigenen Code schreiben, um irgendwie mit den entstandenen Lücken zurechtzukommen.

Senior Sanchez
2005-11-24, 14:45:37
An deiner Stelle würde ich versuchen, das Verhalten einer Lottoziehung wirklich nachzubilden. Ich finde, gerade dieses Beispiel eignet sich besonders gut dafür...

Du hast irgendeinen "Eimer", indem sich 49 Kugeln befinden. Die Kugeln sind von 1 bis 49 beschriftet. Du greifst dir zufällig eine davon raus, und legst sie irgendwo ab.

Mein Ansatz sähe so aus:



// Eimer erzeugen und füllen

ArrayList<Kugel> eimer = new ArrayList<Kugel>();

for(int i = 1; i <=49; i++){

Kugel kugel = new Kugel(i);
eimer.add(kugel);
}

// 6 Kugeln ziehen, und geordnet ablegen

ArrayList<Kugel> kombination = new List<Kugel>();

for(int i = 1; i <= 6; i++){

int zufallsZahl = (int) Math.random() * eimer.size();
Kugel kugel = eimer.get(zufallsZahl);
eimer.remove(kugel);
kombination.add(kugel);
}

// Kombination sortieren

Collections.sort(kombination);

// Kombination ausgeben

for(Kugel kugel : kombination){
System.out.println(kugel.toString());
}

// Kugelklasse

class Kugel implements Comparable<Kugel>{

private int nummer;

public Kugel(int nummer){
this.nummer = nummer;
}

public int compareTo(Kugel anderekugel){
return this.nummer - anderekugel.nummer;
}
public String toString(){
return nummer;
}

}


So ganz zufrieden bin ich mit der Implementierung nicht, weil ein geordneter Eimer dem Lottosystem widerspricht. Eigentlich wäre ein "Set" die richtige Form der Sammlung, aber mir fällt so spontan nicht ein, wie ich per Zufallslosung daraus eine Kugel ziehen soll.


Das wird krachen sobald deine Zufallszahl == 1 ist ;) Denn dann will er auf das Element eimer.size() zugreifen, aber da die Zählung bei 0 beginnt und bei size-1 endet, kracht es ;)

Gast
2005-11-24, 14:49:34
Danke zuerst für eure Mühen!
Ich bin leider noch nicht so weit in der Java-Programmierung, schlage mich immer noch mit Arrays etc. herum. Möchte deshalb meinen Code nicht vollständig perfekt gekürzt haben, und dann trotzdem nicht verstehen was ich da eigentlich habe.

Ich möchte daher das Lotto-Spiel auf meinem oberen Code basiert haben, auch wenn es nicht "schön" aussieht für den Programmier-Profi.

Was habe ich denn falsch, dass ich nicht immer 6 Zahlen erhalte? Das muss doch auffind -und lösbar sein.

Monger
2005-11-24, 14:49:42
Das wird krachen sobald deine Zufallszahl == 1 ist ;) Denn dann will er auf das Element eimer.size() zugreifen, aber da die Zählung bei 0 beginnt und bei size-1 endet, kracht es ;)
ups!

Aber wenn ich von 0 bis 48 gehe, müsste es eigentlich gehen - weil genau so habe ich die Zahlen ja auch abgelegt.

Also:



int zufallszahl = Math.random() * (eimer.size() - 1);

Aber toll finde ich diese Art von Zufallsfunktion immer noch nicht. Gegenvorschläge?

Trap
2005-11-24, 14:57:41
In einem int [] musst du zwangsläufig eigenen Code schreiben, um irgendwie mit den entstandenen Lücken zurechtzukommen.
Nein, muss ich nicht. Hab ich auch nicht. Ich teile das Array logisch in 2 Hälften: die ersten i sind die die ich gezogen hab und der Rest sind die aus denen ich ziehe. Ich ziehe eine Zahl an Stelle x indem ich sie mit der an Stelle i vertausche.

Ich hätte auch sortieren können mit Arrays.sort(n,0,6); aber dann muss man sich in der Ausgabeschleife merken welches Element man im Moment betrachtet (mehr Code => mehr mögliche Fehler).

(int)Math.random()*x.size() ist RICHTIG. Math.random() gibt nie 1 zurück.

Monger
2005-11-24, 15:05:21
Was habe ich denn falsch, dass ich nicht immer 6 Zahlen erhalte? Das muss doch auffind -und lösbar sein.

Erklär mir mal bitte ausführlich, was dein Code in den folgenden Zeilen macht, und warum:


for (int c=0; c<1; c++) {
if (zahl == zahlenliste [c])
{zahl = (int)(Math.random()*49);}
else {zahlenliste [a] = zahl;}
}

noid
2005-11-24, 15:45:56
Erklär mir mal bitte ausführlich, was dein Code in den folgenden Zeilen macht, und warum:


for (int c=0; c<1; c++) {
if (zahl == zahlenliste [c])
{zahl = (int)(Math.random()*49);}
else {zahlenliste [a] = zahl;}
}



das habe ich von anfang an gefordert - da würde dem ersteller sofort klar werden was er _nicht_ macht.

Gast
2005-11-24, 17:58:04
So, habe meinen Code nun mehr oder weniger komplett überarbeitet.
Sind zwar mehr Zeilen als in euren möglichen Varianten; funktioniert aber trotzdem.

Danke für eure Hilfe.



import java.io.*;

public class lotto {

public static void main (String [] args) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

// ZUFAELLIGES BESTIMMEN VON 6 ZAHLEN
int z1, z2, z3, z4, z5, z6;
z1 = (int)(Math.random()*48+1);
do {
z2 = (int)(Math.random()*48+1);
} while (z2 == z1);
do {
z3 = (int)(Math.random()*48+1);
} while (z3 == z1 || z3 == z2);
do {
z4 = (int)(Math.random()*48+1);
} while (z4 == z1 || z4 == z2 || z4 == z3);
do {
z5 = (int)(Math.random()*48+1);
} while (z5 == z1 || z5 == z2 || z5 == z3 || z5 == z4);
do {
z6 = (int)(Math.random()*48+1);
} while (z6 == z1 || z6 == z2 || z6 == z3 || z6 == z4 || z6 == z5);

int zahlenliste [] = { z1, z2, z3, z4, z5, z6 };

int a = 0, save;
boolean tausche;


// ZAHLEN SORTIEREN
do {
tausche = true;
for ( int i=0; i<(5-a); i++) {
if ( zahlenliste[i+1] < zahlenliste[i] ) {
save = zahlenliste[i];
zahlenliste[i] = zahlenliste[i+1];
zahlenliste[i+1]=save;
tausche = false;
}
}
a++;
} while ( !tausche );


// GENERIERTE ZAHLEN AUSGEBEN
System.out.println("Lottozahlengenerator:");

int counter=1;
int counter2=0;
for (int g=0; g<=6; g++)
{
for (int h=0; h<=6; h++)
{
if (counter == zahlenliste[counter2])
{
System.out.print(zahlenliste[counter2]+" ");
if(counter2 < 5) { counter2++; }
}
else {
System.out.print("__"+" ");
}
counter++;
}
System.out.println();
}
}
}

Trap
2005-11-24, 18:11:33
Sind zwar mehr Zeilen als in euren möglichen Varianten; funktioniert aber trotzdem.
Dein Code zieht nie eine 49.

redfalcon
2005-11-24, 18:14:38
So, habe meinen Code nun mehr oder weniger komplett überarbeitet.
Sind zwar mehr Zeilen als in euren möglichen Varianten; funktioniert aber trotzdem.

Danke für eure Hilfe.



Es muss
z1 = (int)(Math.random()*49+1);
heißen, sonst wird die 49 nicht gezogen.

/edit: Argh, Tab zu lang aufgelassen.

noid
2005-11-24, 20:14:24
So, habe meinen Code nun mehr oder weniger komplett überarbeitet.
Sind zwar mehr Zeilen als in euren möglichen Varianten; funktioniert aber trotzdem.

Danke für eure Hilfe.



import java.io.*;

public class lotto {

public static void main (String [] args) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

// ZUFAELLIGES BESTIMMEN VON 6 ZAHLEN
int z1, z2, z3, z4, z5, z6;
z1 = (int)(Math.random()*48+1);
do {
z2 = (int)(Math.random()*48+1);
} while (z2 == z1);
do {
z3 = (int)(Math.random()*48+1);
} while (z3 == z1 || z3 == z2);
do {
z4 = (int)(Math.random()*48+1);
} while (z4 == z1 || z4 == z2 || z4 == z3);
do {
z5 = (int)(Math.random()*48+1);
} while (z5 == z1 || z5 == z2 || z5 == z3 || z5 == z4);
do {
z6 = (int)(Math.random()*48+1);
} while (z6 == z1 || z6 == z2 || z6 == z3 || z6 == z4 || z6 == z5);

int zahlenliste [] = { z1, z2, z3, z4, z5, z6 };

int a = 0, save;
boolean tausche;


// ZAHLEN SORTIEREN
do {
tausche = true;
for ( int i=0; i<(5-a); i++) {
if ( zahlenliste[i+1] < zahlenliste[i] ) {
save = zahlenliste[i];
zahlenliste[i] = zahlenliste[i+1];
zahlenliste[i+1]=save;
tausche = false;
}
}
a++;
} while ( !tausche );


// GENERIERTE ZAHLEN AUSGEBEN
System.out.println("Lottozahlengenerator:");

int counter=1;
int counter2=0;
for (int g=0; g<=6; g++)
{
for (int h=0; h<=6; h++)
{
if (counter == zahlenliste[counter2])
{
System.out.print(zahlenliste[counter2]+" ");
if(counter2 < 5) { counter2++; }
}
else {
System.out.print("__"+" ");
}
counter++;
}
System.out.println();
}
}
}


das mit dem ziehen ist grauenhaft... sowas schreit nach ner schleife. das sortieren geht noch, aber die ausgabe entbehrt jedweder logischen strukur. du hast 2 ineinander verschachtelte schleifen.... prüfst aber dann kein einziges mal diesen index ab oder nutzt ihn - wofür sind dann die bedingten schleifen gut, wenn du deine bedingung eh in der schleife nochmal anders definierst?

ich hoffe, dass dein prof auch nicht begeistert ist. schliesslich geht es nicht darum code zu hacken der was macht...

Gast
2005-11-24, 21:16:17
class Lotto {

public static void main (String args[]) {

int x;
boolean a[] = new boolean[49];

System.out.println("Lottozahlengenerator:\n\n");

for (int i = 1; i <= 6; i++) {
do {

x = (int) (Math.random() * 49);

} while (a[x]);
a[x] = true;
}


for (int i = 0; i < 49; i++) {
System.out.print(" ");
if (!a[i]) {
System.out.print("__");
}
else {
if (i < 9) {
System.out.print("0");
}
System.out.print(i+1);
}
if ((i+1) % 7 == 0) {
System.out.println();
}
}
}

}


So, was lange währt wird endlich gut, besser krieg' ich es nicht mehr hin; ich warte auf Ihren Tadel, Herr Hauptmann noid.

Spasstiger
2005-11-24, 21:26:51
Müsst ihr eigentlich nicht objektorientiert programmieren? Bei uns wird für jeden dummen Vorgang eine neue Methode erstellt, es werden Klassen von Oberklassen abgeleitet, wo es nur geht, und Objekte werden auch überall reingepackt, wo die Verwendung eines solchen einigermaßen Sinn macht.
Du hast ja nur eine main-Methode und einen einzigen Konstruktoraufruf.

noid
2005-11-24, 22:20:50
class Lotto {

public static void main (String args[]) {

int x;
boolean a[] = new boolean[49];

System.out.println("Lottozahlengenerator:\n\n");

for (int i = 1; i <= 6; i++) {
do {

x = (int) (Math.random() * 49);

} while (a[x]);
a[x] = true;
}


for (int i = 0; i < 49; i++) {
System.out.print(" ");
if (!a[i]) {
System.out.print("__");
}
else {
if (i < 9) {
System.out.print("0");
}
System.out.print(i+1);
}
if ((i+1) % 7 == 0) {
System.out.println();
}
}
}

}


So, was lange währt wird endlich gut, besser krieg' ich es nicht mehr hin; ich warte auf Ihren Tadel, Herr Hauptmann noid.

irgendwann geht der tadel auch mir aus ;)

ich erinnere eben nur, dass es im grunde auch auf die eleganz und performanz ankommt. dein altes programm ist durch die häufige verwendung von überflüssigen schleifen nicht so schnell wie das jetzt. sowas kann bei größeren dingen ziemlich schnell auf die zeit gehen.

gruß noid, der immer schon gerne unschönen code kritisiert hat, und meistens einer meinung mit lehrern und profs war.

Monger
2005-11-25, 09:04:17
Müsst ihr eigentlich nicht objektorientiert programmieren? Bei uns wird für jeden dummen Vorgang eine neue Methode erstellt, es werden Klassen von Oberklassen abgeleitet, wo es nur geht, und Objekte werden auch überall reingepackt, wo die Verwendung eines solchen einigermaßen Sinn macht.
Du hast ja nur eine main-Methode und einen einzigen Konstruktoraufruf.
Unser Gast hat ja gesagt, dass sie noch nicht wesentlich mehr als Arrays durchgenommen haben.


Ich kenn das Konzept. Man nehme einen Lehrer, der 10 Jahre lang Pascal gelehrt hat, und lasse ihn Java unterrichten :(

So etwas kann einem den Spaß am programmieren verderben...

Trap
2005-11-25, 10:58:14
Ich bin der Überzeugung, dass Java allein völlig ausreichend ist einem den Spaß am Programmieren zu verderben. Schon allein, dass es sich weigert Funktionen mit Dead-Code zu kompilieren, regt mich jedesmal auf...