Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
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 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);
}
}
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());
}
}
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.
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);
}
}
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.
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.
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. Hänge anscheinend wieder viel zu lange vor dem Rechner...
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 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:
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
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
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:
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