Beginnercode: Pokerdealer Programm

fk1

Mitglied
Wurde da jemand etwa mit einem Tablet beschert? Welches tablet nutzt du denn?

Ich hatte gedacht, dass die blueDeck.toString(); Methode fester Bestandteil durch die ArrayList ist. Als ich ausgeschlafen heute morgen deinen Post gelesen hatte, wusste ich, das war Quatsch :D Ich habe gestern anscheinend einfach wieder zu lange vor dem Rechner gesessen.

Java:
import java.util.*;

public class Deck{
 
    ArrayList<Card> deck = new ArrayList<Card>();
 
    public void createDeck(){
        for(Ranks rank : Ranks.values()){
            for (Suits suit : Suits.values()){
                deck.add(new Card(rank, suit));
            }
        }
    }
 
    public String toString(){
        return String.format("%s", deck);
     
    }
}

Jetzt liefert die test.class folgendes:

[Ac, As, Ad, Ah, 2c, 2s, 2d, 2h, 3c, 3s, 3d, 3h, 4c, 4s, 4d, 4h, 5c, 5s, 5d, 5h, 6c, 6s, 6d, 6h, 7c, 7s, 7d, 7h, 8c, 8s, 8d, 8h, 9c, 9s, 9d, 9h, Tc, Ts, Td, Th, Jc, Js, Jd, Jh, Qc, Qs, Qd, Qh, Kc, Ks, Kd, Kh]

:)
 

fk1

Mitglied
Wäre es besser, die methode createDeck() als Konstruktor für die Klasse Deck zu nutzen? Bzw. ergibt es mehr Sinn in Anbetracht von OOP? zumindest spare ich mir dann in der Test class die createDeck line und die Deck.class hat dann einen Konstruktor:

Java:
import java.util.*;

public class Deck{
   
    ArrayList<Card> deck = new ArrayList<Card>();
   
    public Deck(){
        for(Ranks rank : Ranks.values()){
            for (Suits suit : Suits.values()){
                deck.add(new Card(rank, suit));
            }
        }
    }
   
    public String toString(){
        return String.format("%s", deck);
       
    }
}
Java:
public class Test {
   
    public static void main(String[] args) {
        Deck blueDeck = new Deck();
        System.out.print(blueDeck.toString());
    }

}
 

Jardcore

Top Contributor
Ja, das kannst du machen. Und du kannst dir den Aufruf bei blueDeck.toString() sparen, die toString() Methode wird explizit aufgerufen wenn du ein Objekt als String ausgeben willst. Also System.out.println(blueDeck); reicht.

Du kannst übrigens noch einen ziemlich advanced Trick anwenden. Und zwar die "deck" variable aus Deck löschen und dafür dein Deck von ArrayList<Card> extenden. Dann bräuchtest du vllt noch einen DeckBuilder bzw den Dealer und der bekommt dann Methoden wie createDeck() oder getCard().

Achja der Vorteil übrigens der ArrayList ist das du durch den Aufruf Collections.shuffle(deck) dein Deck mischen kannst. Da dein Deck nun eine Liste ist die von Collections erbt kannst du auch die Hilfsklasse Collections benutzen um einige Operationen auszuführen.
Wurde da jemand etwa mit einem Tablet beschert? Welches tablet nutzt du denn?
Ne das hab ich schon seit 2013, Samsung Galaxy 10.1 Tablet
 

fk1

Mitglied
Auf die Möglichkeit, auf .toString(); zu verzichten, bin ich gerade eben zufälligerweise selbst gekommen, als ich mich mit Collection.shuffle herumgetestet habe. ^^

Zu deinem Vorschlag: Meinst du das so? Ich nutze erstmal Test, bis ich mir Gedanken um eine neue Klasse Dealer/DeckCreator o.Ä. gemacht habe:

Java:
public class Deck extends Test{
   

   
    public Deck(){
        for(Ranks rank : Ranks.values()){
            for (Suits suit : Suits.values()){
                deck.add(new Card(rank, suit));
            }
        }
    }
   
    public String toString(){
        return String.format("%s", deck);
       
    }
}
Java:
import java.util.ArrayList;
import java.util.Collections;

public class Test{
   
    ArrayList<Card> deck = new ArrayList<Card>();
   
    public static void main(String[] args) {
        Deck blueDeck = new Deck();
        Collections.shuffle(blueDeck.deck);
        System.out.println(blueDeck);
    }
}
 

Jardcore

Top Contributor
Java:
public class Deck extends ArrayList<Card> {

    private static final int FIRST_CARD = 0;

    public Deck(){
        for(Ranks rank : Ranks.values()){
            for (Suits suit : Suits.values()){
                this.add(new Card(rank, suit));
            }
        }
    }

    public Card getCard() {
        return remove(FIRST_CARD);
    }

    public void shuffle() {
        Collections.shuffle(this);
    }
}

Alles ausm Kopf geschrieben, aber so sollte das funktionieren.
Man müsste bei getCard() noch gucken ob es überhaupt noch Karten gibt.

P.S: So braucht man auch nicht unbedingt ein Dealer, außer man braucht mehr Funktionalität, z.B.: Karten verteilen usw.
 
Zuletzt bearbeitet:

fk1

Mitglied
OK, dann muss ich jetzt nochmal nachlesen bzgl ArrayLists extenden, dachte es geht nur mit Klassen EDIT: Achja lol, ArrayLists sind ja definiert als Klassen wenn ich mich recht erinnere.

return remove(0); muss ich auch noch überdenken. Verstehe es jetzt so, dass das erste Objekt mit dem index 0 aus der ArrayList returned wird und dann auch direkt aus dem Array entfernt(remove) ?!

Mal wieder allgemein gefragt:

Sind die Methoden shuffle() und getCard() Fähigkeiten, die ich später besser in der Dealer class definiere? Passen imho besser dahin, denn der Dealer mischt ja die Karten oder zieht eine Karte, die er verteilt.
 
Zuletzt bearbeitet:

fk1

Mitglied
Ich glaube ich habe noch den Code gesehen, bevor du ihn editiert hast:

Hast du die int FIRST_CARD editiert um eine magicnumber zu vermeiden? :p

Eclipse hat noch wegen einer UID gemeckert daher habe ich eine generieren lassen. So sieht die extra line aus:

Code:
private static final long serialVersionUID = 4287793858292977743L;
 

fk1

Mitglied
Ich habe mir Gedanken um die Problematik gemacht, wenn alle Karten ausgeteilt sind. Ich habe mal testweise 53 karten ausgeben lassen und Eclipse wirft auch, wie von @Jardcore erwartet, Fehler.

Dann habe ich mir überlegt, die getCard() Methode mit einer if Bedingung zu beschränken. Ich habe die Idee dann wieder verworfen, weil ich meine mich zu erinnern, dass in solche get-Methoden lediglich eine return Zeile stehen soll, sonst nichts.

Dann habe ich mir überlegt: Ich erstelle eine zusätzlich Methode die prüft, ob Karten übrig sind. Wenn ich später dann eine Karte ziehen will bzw. Deck.getCard() benutze, prüfe ich vorher, ob überhaupt Karten übrig sind.

Zusätzliche Methode in der Deck.class:

Java:
    public boolean checkIfDeckEmpty(){
        if(this.get(FIRST_CARD)==null){
            return true;
        }else{
            return false;
        }
    }

Hiermit wollte ich folgendes realisieren: Prüfen ob Deck leer -> falls leer, kein neues Objekt erzeugen. Klappt aber trotzdem nicht so wirklich, ich kriege weiterhin Errors

Test.class:

Java:
public class Test{
   
    public static void main(String[] args) {
        Deck blueDeck = new Deck();
        Card blueCard;
       
        for(int i=0; i<53; i++){
           
            if(blueDeck.checkIfDeckEmpty() == true){
                blueCard = null;
            }else{
                blueCard = blueDeck.getCard();
            }   
       
        System.out.println(blueCard);
        }
    }
}

Ich habe die Vermutung das die Prüfung der Bedingung if(this.get(FIRST_CARD)==null) nicht das macht, was ich glaube. Ich weiss aber auch nicht, wie ich das überprüfe. Vielleicht weiss ich es ja morgen. :D Hänge anscheinend wieder viel zu lange vor dem Rechner...
 

Jardcore

Top Contributor
Hast du die int FIRST_CARD editiert um eine magicnumber zu vermeiden? :p
Jep :)
Dann habe ich mir überlegt, die getCard() Methode mit einer if Bedingung zu beschränken
Also das ist grundsätzlich löblich, aber an dieser Stelle ist das kein richtiger Getter, weil du nicht auf ein Attribut von Deck.class zugreifst. Hier ist nur das get im Name weil ich dachte... könnte passen :p Also kannst du die Abfrage dort machen. Da du hier von ArrayList erbst hast du übrigens schon die Methode isEmpty() mitgeerbt. Benutze mal den shortcut Strg+Leertaste außerhalb einer Methode, dann siehst du was für mögliche Methoden du noch alles hast. Für dein Problem könntest du nun sowas machen:
Java:
public Card getCard() {
    if(isEmpty()) { 
        return null;
    }
    return remove(FIRST_CARD);
}
Und später kannst du dann in deinem Programm darauf reagieren, dass bei null keine Karte mehr gegeben werden konnte.
Aufjedenfall kannst du jetzt auch von 0-1000 zählen bekommst dann halt nur 52 Karten
und dann nur noch null als Ausgabe :)

Hiermit wollte ich folgendes realisieren: Prüfen ob Deck leer -> falls leer, kein neues Objekt erzeugen. Klappt aber trotzdem nicht so wirklich, ich kriege weiterhin Errors
Finds cool das du schreibst was du realisieren wolltest, das hilft mir zu verstehen was du vorhast... mehr davon :)

Hänge anscheinend wieder viel zu lange vor dem Rechner...
<--- deshalb Tablet XD Eclipse wäre noch super, aber man kann nicht alles haben :(
 

fk1

Mitglied
Wenn das kein richtiger Getter ist, schlage ich vor die Methode in drawCard umzubenennen. Bzgl. Tablet: ich selber finde man ist am laptop produktiver, allein schon wegen dem Keyboard. Aber wenn du Eclipse auf dem Tablet haben willst: Teamviewer funzt super! Laptop an, Teamviewer starten und am Tablet coden ;)
 

fk1

Mitglied
Sooo... vor zwei Wochen kam ich hier mit meinem ersten eigenen Java "Script" hier her. Jetzt haben wir die gleiche Funktion OO gestaltet. Außerdem kommt ein wenig Neues hinzu, aber immer der Reihe nach.

Ich habe zur Übersicht mal ein neues Diagramm mit ObjectAid erstellt:

x62an8pf.png


Jetzt zur Erklärung: Ich habe eine Klasse Dealer erstellt um ein paar Sachen zu ordnen. Der Dealer hat folgendes:

- Er kennt die Anzahl der auszuteilenden holecards (die versteckten Karten eines Spielers)
- er hat ein aktives Deck Karten
- er hat eine aktuell gezogene Karte currentCard, die er verteilen soll

Zusätzlich bekommt er zwei Methoden. Wer schonmal ein Turnier gespielt hat, kennt vielleicht den berühmten Satz, den Turnierveranstalter zum eröffnen des Turniers bekannt geben: "Shuffle up and deal!"

Also soll unser Dealer folgendes können: Ein Deck in die Hand nehmen und mischen (shuffle up) und dann Karten austeilen (deal). In unserem Fall soll er pro Spieler zwei Karten austeilen.

Da wir zunächst der einzige Spieler sind, reicht die for-schleife, die ich nutze. Wenn da mehr Spieler hinzukommen, muss man die nochmal überdenken. Um da hin zu kommen, wo ich vor zwei Wochen war, reicht das erstmal.

Code:
public class Dealer {
   
    private static final int numHolecardsHoldem = 2; //Anzahl holecards pro Spieler
    private Deck activeDeck; 
    private Card currentCard;
   
    public void shuffleUp(){
        activeDeck = new Deck();
        activeDeck.shuffle();
    }
   
    public void dealHoldem(Holecards seatNum){
        for(int i=0; i<numHolecardsHoldem; i++){
            currentCard = activeDeck.drawCard();
            seatNum.addHolecard(currentCard); // seatNum erkläre ich im Beitrag noch
        }
    }
}

die Methode dealHoldem bekommt Holecards seatNum übergeben. Dazu kommen wir daher als nächstes.

Für die holecards nutze ich im Grunde die gleiche Idee, wie für das Deck. wholecards sind im Grunde auch nur ein Stapel aus Karten, die der Spieler bekommt. In diesem Fall ein Stapel aus zwei Karten. Also eine extended class Holecards:

Java:
import java.util.ArrayList;

public class Holecards extends ArrayList<Card> {

    private static final long serialVersionUID = -2278901932251803755L; //Wird von Eclipse gewünscht bzw. generiert
   
    public void addHolecard(Card holecard){
        this.add(holecard);
    }
}

Vorteil in Form einer ArrayList ist wohl die flexible Größe: Denke ich an die Variante Omaha mit vier statt zwei holecards, muss ich dem Dealer nur die Anzahl für Omaha bei bringen und dementsprechend eine andere Methode.

Bezüglich dem Übergabewert seatNum: Ich plane später eine Klasse Seat zu erzeugen. Zu einem Seat gehören dann z.B. die holecards, relative Spielpositionen, Chipstacks, etc.

Da das aber noch Zukunftsmusik ist und ich die holecards eines Spielers nicht der Dealer.class zuweisen möchte, bediene ich mich bisher noch folgender Lösung:

Java:
public class Test{
   
    private static Dealer dealer1 = new Dealer(); 
    private static Holecards hcseat1 = new Holecards();

    public static void main(String[] args) {
        dealer1.shuffleUp();
        dealer1.dealHoldem(hcseat1);
       
        System.out.println("Preflop: Your holecards: " + hcseat1);

Führe ich das alles aus, bekomme ich nun immer zwei Karten in der Konsole ausgeteilt. Also wie vor zwei Wochen, dank eurer Hilfe nun aber OO. :)

Mein nächstes Ziel: Flop, Turn & River austeilen. Anschließend die Regeln für Pokerhände deklarieren und dementsprechend eine Pokerhand aus den ausgeteilten Karten bestimmen.

Also z.B. die Konsole spuckt aus:

Preflop: Your holecards: AcAh
Flop: AsKc2d
Turn: 3h
River: 7s

Your Hand: AcAhAsKc7s (Three of a kind, Aces)

Ideen, das umzusetzen, habe ich auch schon :) Ein paar Ideen werde ich mal kurz anschneiden:

- Für Flop, Turn und River erzeuge ich eine neue ArrayList namens CommunityCards

- Die Test.class muss ja mal irgendwie, irgendwann so etwas wie eine main class werden. Ich denke, das realisiert man am besten mit einer class Table. Wer schon mal online gepokert hat, weiss, das jede Runde an einem Tisch realisiert wird. ich denke daher auch das die programmierer der online Casinos ähnlich vorgehen, also das ganze Spiel mit allem drum und dran unter einem Tisch ablaufen lassen

- Wie bereits erwähnt eine Klasse Seat mit Stacksizes, holecards für jeden Spieler und relativer Spielposition. eine Table.class ruft dann dementsprechend z.B. max 9 seats für 9 Spieler auf

Aber das sind erstmal nur Ideen. Ich konzentriere mich als nächstes auf das Bestimmen von Pokerhands, das wird erstmal seine zeit dauern.

Bis hierhin nochmal danke an eure Hilfe, besonders @Jardcore! Wenn ich mich euch auch mal irgendwie helfen kann, helf ich gerne :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Batchdatei, Prüfe ob Programm X läuft Softwareentwicklung 2
N Pop-up Programm mit Live-Video Softwareentwicklung 7
C Programm "Road Chat" realisierbar? Softwareentwicklung 2
J Suche noch eine Loesung fuer Kommunikation zwischen Webserver und ein Programm Softwareentwicklung 0
P Benutzeroberfläche Programm Bewertung Softwareentwicklung 2
KranzKrone Architektur für einfaches Gui Programm Softwareentwicklung 6
G Make or Buy? - Tagging-Programm Softwareentwicklung 4
G Linux: Programm mit UI einmalig beim Systemstart ausführen Softwareentwicklung 3
B WHILE und GOTO Programm Softwareentwicklung 32
I Tool / Programm etc. zur Testdokumentation gesucht Softwareentwicklung 2
T Kommerziellen Programm unter Verwendung div. Libraries mit div. Lizenzen Softwareentwicklung 7
Airwolf89 Java-Programm in C++ portieren Softwareentwicklung 4
Steev Javaprogram aus C/AL-Programm ansteuern Softwareentwicklung 13
clupus Verbindung mit c-Programm Softwareentwicklung 4
V AGB's in Programm einbauen? Softwareentwicklung 3
J Design Patterns in Programm hineinfließen lassen Softwareentwicklung 23
sparrow Welche Lizenz für ein offenes Programm Softwareentwicklung 2
G Suche Programm für Masken Design für Pflichtenheft Softwareentwicklung 5
T Programm mit Passwort schützen. Softwareentwicklung 44
J Finde Fehler im Programm nicht (Klasse Kreis) Softwareentwicklung 1
E Java Programm distributen Softwareentwicklung 35
X Möglichst unverständliches Programm Softwareentwicklung 13
P Grafik-Programm mit JAVA? Softwareentwicklung 21
F Kleines Programm für Windows Softwareentwicklung 2
M Kurvendiskussion, Funktions-Plotter, Mathe-Programm. Softwareentwicklung 3
W Herangehensweise an ein Java Programm Softwareentwicklung 4

Ähnliche Java Themen

Neue Themen


Oben