Kartenspiel problem mit compareTo

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Kartenspiel problem mit compareTo

    Hi Leute!

    Ich habe hier eine Übungsaufgabe in dem ich ein Kartenspiel programmieren soll ... was ich auch getan habe nun möchte ich aber eine methode schreiben die mein Array mit den Kartenobjekten soriteirt und das sollte möglichst mit compareTo geschehen hab aber leider keine ahnung wie das funzen soll :( mein code sieht folgendermaßen aus :

    zu erst die Klasse Karte :

    Quellcode

    1. [/code
    2. public class Karte {
    3. public enum Farbe{
    4. KREUZ(3),
    5. PIK(2),
    6. KARO(0),
    7. HERZ(1);
    8. private int farbewert;
    9. private Farbe(int ordnungswert) // constructor zum übergeben des Ordnungswertes
    10. {
    11. farbewert=ordnungswert;
    12. }
    13. }
    14. //declaration of new Datatype und zuweisung von Ordnungswerten
    15. enum Wert {
    16. SIEBEN,
    17. ACHT,
    18. NEUN ,
    19. ZEHN,
    20. BUBE,
    21. DAME,
    22. KOENIG,
    23. ASS;
    24. }
    25. private Farbe farbe; //Instanzvariabel
    26. private Wert wert;
    27. public Karte (Farbe f, Wert w){ // Constructor
    28. this.farbe = f;
    29. this.wert= w;
    30. }
    31. public int compareTo( int farbewert){
    32. if (this.farbe.ordinal()==this.farbe.ordinal()){
    33. return 0;
    34. }
    35. if (this.farbe.ordinal()<this.farbe.ordinal()){
    36. return 1;
    37. }
    38. if (this.farbe.ordinal()>this.farbe.ordinal()){
    39. return -1;
    40. }
    41. }
    42. public String toString(){ // String Method
    43. return " " + this.farbe.toString() + " " +this.wert.toString();
    44. }
    45. }
    Alles anzeigen




    2.ten die Klasse Kartenspiel: (hier sind sämtliche funktionen )

    Quellcode

    1. public class Kartenspiel {
    2. Karte[] karte; //deklaration Array
    3. //String ausgabe="";
    4. public Kartenspiel(int n){ //Constructor
    5. karte = new Karte[n]; //initalisirung Array mit n Plätzen
    6. for(int i=0; i<n;i++){ //Schleife schreibt Objekte in Array
    7. int ranfarbe=(int)(Math.random() *4); //erzeugen von Zufallszahlen die für Farben stehen
    8. int ranwert=(int)(Math.random() *8); //erzeugen von Zufallszahlen die für Werte stehen
    9. karte[i]= new Karte(Karte.Farbe.values()[ranfarbe] , Karte.Wert.values()[ranwert]);
    10. //erzeuge an nter stelle Objekt Karte in Array (Karte.Farbe.usw Pfadangabe)
    11. //ausgabe+=karte[i].toString()+"\n";
    12. }
    13. }
    14. public String toString(){ //String Method
    15. String rückgabe = "";
    16. for( int i=0; i<karte.length; i++){
    17. rückgabe += karte[i].toString()+"\n";
    18. }
    19. return ""+rückgabe;
    20. }
    21. public void mischen(){
    22. Karte temp;
    23. for (int i=0; i<karte.length*10;i++){
    24. int karteran=(int)(Math.random()*karte.length);
    25. int stelleran=(int)(Math.random()*karte.length);
    26. temp=karte[karteran];
    27. karte[karteran]=karte[stelleran];
    28. karte[karteran]= temp;
    29. }
    30. }
    31. }
    Alles anzeigen




    3ten: Die Klasse Kartetest (main methode)


    Quellcode

    1. public class Kartetest {
    2. public static void main(String [] args){
    3. int n =Console.readInt();
    4. Kartenspiel test=new Kartenspiel(n);
    5. System.out.print(test.toString());
    6. }
    7. }
    Alles anzeigen



    1.Frage: was muss ich in der Klasse Karte in der Singnatur compareTo übergeben ???.... farbwert ist aufjeden fall falsch so wie ich das mitbekommen habe:(

    2. Frage: wie muss ich das genau mit der if schleife und dem vergleichen aufbauen ist mein ansatz wenigst schon in der richtigen richtung ????

    3. Frage: wie bring ich nun Array.sort() daszu das Array nach der Ordnungswerten die ich festgelegt habe zu sortieren also wie muss ich die übergeben ????

    4. Frage: wie rufe ich Array.sort() in der Main auf

    5. Frage: sind noch andere Fehler zu endecken die verbessert werden müssten ?

    6. Frage: Vieleicht kann mir noch jemand einen kurzen ansatz für aufgabe e zeigen ?



    Aufgabenstellung:

    Karten in diesem Spiel haben die Farben „kreuz“, „pik“, „herz“ ,„karo“

    sowie die Kartenwerte: „7“, „8“, „9“, „10“, „bauer“, „dame“, „koenig“ , „ass“.

    a. Implementieren Sie eine Klasse Karte, die die Karten des Kartenspiels
    repräsentieren kann. Dazu definieren Sie

    - einen Konstruktor Karte (Farbe f, Wert w), wobei Farbe und
    Wert die jeweiligen Werte als enum definieren

    - eine toString Methode

    b. Implementieren Sie eine Klasse Kartenspiel, die aus Karten besteht. Dazu
    definieren Sie

    - einen Konstruktor Kartenspiel(int n), wobei n die Anzahl der Karten
    in diesem Kartenspiel definiert

    - eine toString Methode

    c. Ergänzen Sie Kartenspiel um eine Methode void mischen(), die die
    Karten des Kartenspiels zufällig mischt. Verwenden Sie hierzu die bekannte
    Klasse Math.random.


    d. Ergänzen Sie das Kartenspiel um eine Methode void sort(), die die Karten
    des Kartenspiels sortiert. Verwenden Sie dazu Arrays.sort.
    Lösungshinweis: Damit Karten sich sortieren lassen, müssen Sie eine
    Ordnung für Karten definieren. Sie müssen also für Karten die compareTo
    Methode implementieren. Die Ordnung für Karten ist nur über die Farben
    definiert (die Werte können Sie ignorieren): Karo < Herz < Pik < Kreuz.
    Tipp: Um enum werte zu vergleichen, machen Sie sich mit der Methode
    ordinal() für enums vertraut.

    e. Ergänzen Sie das Kartenspiel um eine Methode
    kartenspielHinzufuegen(Kartenspiel neu), mit der neue Karten
    dem Kartenspiel hinzugefügt werden. Verwenden Sie hierzu die Methode
    Systems.arraycopy.


    Vielen Dank schonmal im Vorraus.... GreetZ....the.old.Pirate ;)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von the_old_Pirate ()

  • 1.Frage: was muss ich in der Klasse Karte in der Singnatur compareTo übergeben ???.... farbwert ist aufjeden fall falsch so wie ich das mitbekommen habe


    Du musst das Interface Comparable implementieren

    Quellcode

    1. class Karte implements Comparable {


    Quellcode

    1. public int compareTo( Object other )
    2. {
    3. Karte otherKarte = (Karte) other;
    4. return this.farbe.compareTo( otherKarte.farbe );
    5. }
  • Hallo,
    zu 1.) Deine Klasse Karte soll das Comparable-Interface implementieren
    Die Methode compareTo bekommt dann eine Karte als Parameter übergeben.

    Quellcode

    1. public class Karte implements Comparable<Karte> {
    2. .
    3. .
    4. public int compareTo(Karte o){
    5. if (this.farbe.ordinal()==o.farbe.ordinal()){ //auf der linken Seite die Ordnungsnummer des aufrufenden, und rechts des aufgerufenen
    6. return 0;
    7. }
    8. if (this.farbe.ordinal()<o.farbe.ordinal()){
    9. return 1;
    10. }
    11. if (this.farbe.ordinal()>o.farbe.ordinal()){
    12. return -1;
    13. }
    14. else throw new ClassCastException("Das zu vergleichende Objekt ist keine Karte");
    15. }
    16. //Aufgerufen wird sie dann mit z.B.
    17. Vergleichsergebnis = karten[i].compareTo(karten[i+1])
    18. aber das erledigt später das Arrays.sort(Object[] o);
    Alles anzeigen


    2. Frage: wie muss ich das genau mit der if schleife und dem vergleichen aufbauen ist mein ansatz wenigst schon in der richtigen richtung ????

    Ich denke das sieht gut aus, eine compareTo gibt immer 0,1 oder -1 zurück, aber es gibt keine "if-Schleifen" ;) und falls das zu vergleichende Objekt nicht
    vom Typ Karte ist, hast Du keinen default Rückgabetyp, habe da eine Exception geschmissen, man könnte bestimmt auch "return 2;" machen.

    5. Frage: sind noch andere Fehler zu endecken die verbessert werden müssten ?

    In der Methode mischen() der Klasse Kartenspiel tauscht Du nur einmal im Kreis:

    Quellcode

    1. public void mischen(){
    2. Karte temp;
    3. for (int i=0; i<karte.length*10;i++){
    4. int karteran=(int)(Math.random()*karte.length);
    5. int stelleran=(int)(Math.random()*karte.length);
    6. temp=karte[karteran];
    7. karte[karteran]=karte[stelleran];
    8. karte[karteran]= temp; // Hier muss es karte[stelleran]=temp; sein
    9. }
    10. }
    Alles anzeigen


    Was mir noch aufgefallen ist: Bei der Erzeugung deines Kartenspiels kann es vorkommen, dass zwei oder mehr identische Karten
    vorhanden sind. Ich will ja nicht erschossen werden, weil ich drei Kreuz Asse auf der Hand habe. 8|

    3. Frage: wie bring ich nun Array.sort() daszu das Array nach der Ordnungswerten die ich festgelegt habe zu sortieren also wie muss ich die übergeben ????


    Die Ordnungswerte in deinem Enum Farbe musst du in die richtige Reihenfolge bringen:

    Quellcode

    1. public enum Farbe{
    2. KARO(0),
    3. HERZ(1),
    4. PIK(2),
    5. KREUZ(3);


    Jetzt kannst du in der Klasse Kartenspiel eine sort-Methode schreiben, und darin Arrays.sort(Objekt[] o) aufrufen.
    Durch das implementierte Comparable-Interface und deren compareTo-Methode ist die Ordnung definiert.

    Quellcode

    1. public void mysort(Karte[] karte) {
    2. Arrays.sort(karte);
    3. }


    In deiner main rufst Du auf: test.mysort(test.karte);
    Bei mir klappt es, hoffe ich konnte helfen.
    Vorher
    HERZ ZEHN
    KREUZ DAME
    PIK KOENIG
    KARO BUBE
    HERZ ACHT
    KREUZ ASS
    KARO DAME
    KREUZ SIEBEN
    HERZ ZEHN
    KREUZ SIEBEN
    Nachher
    KREUZ DAME
    KREUZ ASS
    KREUZ SIEBEN
    KREUZ SIEBEN
    PIK KOENIG
    HERZ ZEHN
    HERZ ACHT
    HERZ ZEHN
    KARO BUBE
    KARO DAME
  • wie kann ich denn verhindern das 2 mal die selben Karten erstellt werden ?

    Prüfe vor dem Einfügen einer neuen Karte ob diese bereits vorhanden ist..
    Alternativ könnte man auch statt eines Arrays eine andere Datenstruktur nutzen:
    "Set" aus den JAVA Collections z.B. lässt keine doppelten Elemente zu.
    Da müsstest Du aber einiges umbauen, ist glaube ich nicht im Sinne der Aufgabenstellung.

    zu Teilaufgabe e:
    Hab da mal was gebastelt, bin mir aber nicht sicher ob das elegant und sinnvoll ist, aber es funzt..

    Quellcode

    1. public void kartenspielHinzufuegen(Kartenspiel alt, int inc) {
    2. int srcPos=0; //Startpunkt des Kopiervorgangs im Quellarray
    3. int destPos=0; //Startpunkt des Kopiervorgangs im Zielarray
    4. Kartenspiel neu =new Kartenspiel(inc); //die neuen Karten
    5. Karte[] karteneu = new Karte[alt.karte.length+inc]; //das neue Karten-Array
    6. //System.arraycopy(Quelle,Startposition,Ziel,Startposition,Anzahl der zu kopierenden Elemente);
    7. System.arraycopy(alt.karte, srcPos, karteneu, destPos, alt.karte.length);
    8. System.arraycopy(neu.karte, srcPos, karteneu, alt.karte.length, neu.karte.length);
    9. alt.karte=karteneu;
    10. }
    Alles anzeigen

    Selbst wenn Du im Konstruktor doppelte Elemente verhinderst, hast Du mit dieser Methode natürlich wieder
    das Problem der doppelten Einträge..
  • the_old_Pirate schrieb:


    nun funzt alles :) hab aber noch eine Frage wie kann ich denn verhindern das 2 mal die selben Karten erstellt werden ????
    und wie setze ich Teilaufgabe e um ??? habe echt keine idee .... ?



    Aufgabenstellung

    Karten in diesem Spiel haben die Farben „kreuz“, „pik“, „herz“ ,„karo“

    sowie die Kartenwerte: „7“, „8“, „9“, „10“, „bauer“, „dame“, „koenig“ , „ass“.

    b. Implementieren Sie eine Klasse Kartenspiel, die aus Karten besteht. Dazu
    definieren Sie

    - einen Konstruktor Kartenspiel(int n), wobei n die Anzahl der Karten
    in diesem Kartenspiel definiert


    Die Festlegung der Anzahl Karten als Konstruktor-Parameter ist für
    ein gesamtes Kartenspiel Unsinn.
    Die Anzahl ist schon durch Anzahl Farben * Anzahl Werte festgelegt.

    Wenn nur ein Teil des Kartenspiels erzeugt werden soll,
    könntest Du folgendermassen vorgehen:

    Das Kartenspiel komplett erzeugen.

    Dann das Kartenspiel mischen.

    Einen Teil des Kartenspiels Ausschneiden.

    Quellcode

    1. import java.util.Arrays;
    2. import java.util.Collection;
    3. import java.util.Collections;
    4. import java.util.List;
    5. public class Kartenspiel
    6. {
    7. enum Farbe
    8. {
    9. KARO(0),
    10. HERZ(1),
    11. PIK(2),
    12. KREUZ(3);
    13. private int farbewert;
    14. private Farbe(int ordnungswert) // constructor zum übergeben des Ordnungswertes
    15. {
    16. farbewert=ordnungswert;
    17. }
    18. }
    19. enum Wert
    20. {
    21. SIEBEN,
    22. ACHT,
    23. NEUN ,
    24. ZEHN,
    25. BUBE,
    26. DAME,
    27. KOENIG,
    28. ASS;
    29. }
    30. static class Karte
    31. {
    32. final Farbe farbe;
    33. final Wert wert;
    34. /**
    35. * Konstruktor.
    36. *
    37. * @param farbe
    38. * @param wert
    39. */
    40. public Karte(
    41. final Farbe farbe ,
    42. final Wert wert )
    43. {
    44. this.farbe = farbe;
    45. this.wert = wert;
    46. }
    47. }
    48. Karte[] karten;
    49. //Constructor
    50. public Kartenspiel(int n)
    51. {
    52. /*
    53. * alle Karten initialisieren
    54. */
    55. final Karte[] tmpKarteArr =
    56. new Karte[ Farbe.values().length * Wert.values().length ];
    57. int j = 0;
    58. for ( int iFarbe = 0 ; iFarbe < Farbe.values().length ; iFarbe++ )
    59. {
    60. for ( int iWert = 0 ; iWert < Wert.values().length ; iWert++ )
    61. {
    62. tmpKarteArr[ j++ ] =
    63. new Karte(
    64. Farbe.values()[ iFarbe ] ,
    65. Wert.values()[ iWert ] );
    66. }
    67. }
    68. /*
    69. * Karten mischen
    70. */
    71. final List<Karte> tmpKarteList =
    72. Arrays.asList( tmpKarteArr );
    73. Collections.shuffle(
    74. tmpKarteList );
    75. final Karte[] shuffledTmpKarteArr =
    76. tmpKarteList.toArray(
    77. new Karte[ tmpKarteList.size() ]);
    78. /*
    79. * Teil-Kartenspiel ausschneiden
    80. */
    81. this.karten =
    82. new Karte[ n ];
    83. System.arraycopy(
    84. shuffledTmpKarteArr ,
    85. 0 ,
    86. this.karten ,
    87. 0 ,
    88. n );
    89. }
    90. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von JavaProfi ()

  • Commander Perkins schrieb:

    und falls das zu vergleichende Objekt nicht
    vom Typ Karte ist, hast Du keinen default Rückgabetyp, habe da eine Exception geschmissen, man könnte bestimmt auch "return 2;" machen.

    Excepgtion werfen ist richtig. Lauf spezifikation gibt compareTo eine Wert kleiner 0, 0 oder größer 0 aus, um zu sagen ob es in der Reihenfolge vor gleich oder nach dem anderen Objekt kommt. Das kann, muss aber nicht -1, 0, 1 sein, der Test bei compareTo auf <0, ==0 und >0 ist legitim, deswegen is die Rückgabe des Wertes 2 keine gute Idee, da es größer 0 ist und damit fälschlicherweise eine Angabe zu einer Sortierreihenfolge machen zwischen zwei Dingen die gar nicht verglichen werden dürfen. Das sind immer die Fehler die man niemals findet, deswegen bei sowas immer Exception werfen.
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]