Methode mit einer Arraylist

Diskutiere Methode mit einer Arraylist im Java Basics - Anfänger-Themen Bereich.
N

Nesselbrand

Das kann man über einen getter aus der Klasse card machen oder ?
 
N

Nesselbrand

Die Karte habe ich in einem string zwischengespeichert ehe sie auf den Bildschirm ausgegeben wird.
 
J

JustNobody

Nunja, da sind wir beim Thema String. Zur Ausgabe macht es ja Sinn, aber erst zur Ausgabe. Bis dahin hast Du ja eine Card Instanz und die solltest Du erst einmal beibehalten. Wenn Du eine Karte ziehst, dann weißt Du ja noch nicht, was damit geschehen soll

Daher wäre es doch durchaus sinnvoll, dass CardDeck eine Methode zum Ziehen einer Karte bekommt, die eine Karte aus dem Stapel entfernt und dann zurück gibt. Methoden sollten ansonsten auch mit einem kleinen Buchstaben beginnen.

Und als Name macht es dann Sinn, etwas zu wählen, das verständlich ist, wie z.B. removeRandomCard. Rückgabe wäre dann Card. Ggf. Noch einbauen, dass es kein Problem gibt, wenn der Kartenstapel leer ist - das Verhalten kann man sich überlegen. Man könnte dann statt einer Karte null zurück geben. Man könnte aber auch eine Exception werfen.
 
N

Nesselbrand

Ich habe das so gemacht dass ich ein gui gemacht habe und dann bin ich gerade dabei dessen Funktionen zu programmieren.
Da braucht man eine Ausgabe.
 
J

JustNobody

Die Idee ist doch, dass man eine saubere Objektstruktur bekommt.

Und bei dem Spiel soll es doch auch nicht nur darum gehen, dass die Karte ausgegeben wird, oder? Also kommt da noch mehr Code ins Spiel.

Und vielleicht hast Du ja auch schon einmal gelesen, dass man ‚Business Logik‘ und ‚UI‘ getrennt halten soll?

Daher wäre es aus meiner Sicht unklug, da jetzt (ohne für mich erkennbaren Grund) die Methoden jetzt einzuschränken.
 
N

Nesselbrand

Habs doch nochmal anders gemacht, so wie dus gessagt hast. Ist schlauer.
Danke für den Tipp.
 
J

Javinner

Die Idee ist doch, dass man eine saubere Objektstruktur bekommt
Genau hier sollte man beginnen: ein Plan. Um das Vorhaben übersichtlicher zu machen würde ich fürs Erste auf GUI verzichten.
Lasse es einfach in der Konsole ablaufen, GUI ist später leicht hinzugefügt.

Die Klasse CardDeck würde ich umschreiben, in dem ich den Vorgang in eine Methode auslagere, denn wenn dein Deck, welcher aus 6x52 besteht, leer ist, soll ein neues geladen werden.
Java:
public CardDeck()
{
     cards = new ArrayList<>();
     for (CardColor color: CardColor.values()) {
          for (CardValue value: CardValue.values()) {
              cards.add(new Card(color, value));
          }
      }
}
Java:
public CardDeck()
{
     createCardDeck();
}

private void createCardDeck()
{
    //Dein Code
}

public Card getNextCard()
{
       if(cards.isEmpty())
       {
               createCardDeck();
        }
       Card card ...
}
Zudem erkenne ich den Sinn der derzeitigen toString()-Methode nicht, wozu?

Dann Spielerfrage: soll es Mitspieler geben? Ich hätte mich ganz klar dagegen entschieden, weil es die Sache unnötig kompliziert macht. Viel mehr würde ich mir die Struktur überlegen, wie ich ein ComputerPlayer von einem HumanPlayer trenne. Als Extra kannst du dir überlegen, wie du das Geschlecht implementierst.
Als Beispiel:
Java:
public String createName(boolean gender)
{
     if(gender)
     {
          //Men
      } else
      {
           //Women
       }
}

String name = NameCreator.createName(false);
Player p = new ComputerPlayer(name);

public class ComputerPlayer
{
     public ComputerPlayer(String name)
     {
          super(name);
      }
}
Der Unterschied von beiden kann in der Prozedur des Kartengebens liegen. Während du für dich entscheidest und es mehrere Menschen geben kann, wird der Prozess für ein ComputerPlayer automatisiert durchgeführt.
 
N

Nesselbrand

Ich kann jetzt BlackJack gegen den Compute spielen :cool::cool:. Hat alles geklappt. Danke für die viele Hilfe
 
N

Nesselbrand

Ich habe aber leider schon das nächste Problem:oops::oops:.
Ich habe einen Automaten programmiert, wo wenn man 4 einser zieht, dass man dann Geld gewinnt. Ich wollte nun einen Automatikmodus einbauen, der jede sekunde nochmal Spielt und testet ob man gewinnt. Dass habe ich mit der Klasse One_Sec_CLock gemacht. Aber das Gui wird nicht geupdatet. Der Rest, also das man Geld gewinnt etc funktioniert. Ich habe dass mit System.out.println() (Steht auch im Code drinnen) geprüft. Kann mir jamand sagen wie ich das mit dem Gui fixen kann?
Das Gui:
Code:
        autoButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                One_Sec_Clock.ThreadStarten();
            }
        });
    }
    public void Auto ()
    {
        System.out.println("a");
        if (Main.balance == 0)
        {
            JOptionPane.showMessageDialog(null,"Sie haben nicht genügend Geld");
            One_Sec_Clock.ThreadStoppen();
            return;
        }
        Main.balance = Main.balance - 1;
        balance.setText("" + Main.balance);
        Automat automat1 = new Automat();
        automat1.getRandomNr();
        w1.setText("" + Automat.w1);
        w2.setText("" + Automat.w2);
        w3.setText("" + Automat.w3);
        w4.setText("" + Automat.w4);
        if (Automat.w1 == Automat.w2 && Automat.w2 == Automat.w3 && Automat.w3 == Automat.w4 && Automat.w4 == 1)
        {
            Main.balance = Main.balance + 100;
            balance.setText("" + Main.balance);
        }
        System.out.println("b");
Automat ist eine Klasse in der die Methode ist die die Zahlen zufällig auswählt usw.
w1 etz sind Variablen für die einzelnen "Walzen" also die Zahlen die zufällig ausgewählt werden.

Klasse mit dem Thread:
Code:
public class One_Sec_Clock
{
    public static class Thread1 extends Thread
    {
        public void run()
        {
            MainGui o = new MainGui();
            while(true)
            {
                System.out.println("test1");
                try {Thread.sleep(1000); }
                catch (Exception e1) {
                    System.out.println("return");
                    return;
                }
                System.out.println("test2");
                o.Auto();
                System.out.println("test3");
            }
        }
    }

    public static void ThreadStarten()
    {
        Thread thread = new Thread1();
        thread.start();
    }

    public static void ThreadStoppen()
    {
        Thread.currentThread().stop();
    }
}
 
Zuletzt bearbeitet:
J

JustNobody

Du erzeugst eine neue GUI in dem Thread und die aktualisierst du. Du musst dem Thread natürlich eine Referenz auf deine UI geben.

Und du nutzt noch einiges an static Variablen scheint mir. Das solltest Du nicht so machen... statt dessen halt das arbeiten mit Referenzen...

Das Thread.currentThread ist auch so eine Sache, die ich nicht nutzen würde....
 
J

JustNobody

Also meine ganz eindringliche Bitte ist wirklich: Nutze überhaupt kein static - außer eben bei der main Methode.

Das mit dem Thread könnte man so bauen:
Code:
public class OneSecClock implements Runnable // Statt von Thread ableiten einfach Runnable implementieren.
{
  private Thread thread = null;  // Wir speichern den erzeugten Thread für später.
  private MainGui mainGui;  // Wir speichern die MainGui - gefällt mir vom Design noch nicht, aber erst mal egal!
 
  public OneSecClock(final MainGui mainGui) {  // Konstruktor setzt die MainGui!
    this.mainGui = mainGui;
  }
 
  // Run Methode von Runnable.
  public void run()
  {
    MainGui o = new MainGui();
    while(true) {
      System.out.println("test1");
      try {Thread.sleep(1000); }
      catch (Exception e1) {
        System.out.println("return");
        return;
      }
      System.out.println("test2");
      mainGui.Auto();  // Auto ist eine Methode und muss klein geschrieben werden!
      System.out.println("test3");
    }
  }

  public void start() {
    // Check if thread already exists.
    if (thread != null && thread.isAlive()) return;
    
    Thread thread = new Thread(this);
    thread.start();
  }

  public void stop() {
    if (thread == null || !thread.isAlive()) return;
    
    thread.stop();
  }
}
Da sind jetzt viele Dinge rein gekommen:
- Schreibweise - Methoden werden klein geschrieben, Klassen groß. Dann gibt es keine _ in den Namen.
- static wurde komplett heraus genommen. Jetzt ist da eine Klasse, von der Du eine Instanz erzeugen musst um dann die Instanz zu nutzen.
- Stoppen stoppt nicht einfach den aktuellen Thread - denn das muss ja nicht zwangsläufig der eigene Thread sein!
- Der Status vom thread wird abgefragt. Wenn ein Thread schon läuft, dann wird kein anderer mehr gestartet.

Das Design ist aber immer noch nicht gut. Eine Klasse, die nur jede Sekunde etwas machen soll, muss doch nichts über eine MainGui wissen. Das kann man also gut entkoppeln.
Man könnte also z.B. eine Instanzvariable vom Typ Consumer<OneSecClock> haben, die man setzen kann. Dann würde diese Klasse die MainGui nicht kennen. Und jede Sekunde würde dann einfach geprüft, ob diese Variable nicht null ist um dann accept(this) darauf aufzurufen.
MainGui würde dann eine Instanz erzeugen und dann einen Consumer bereit stellen (Das ginge über Lambda Ausdrücke ganz einfach mit e->Auto() oder falls man Auto noch ein OneSecClock Parameter gibt, dann ist this::Auto als Parameter möglich.
Der Konstruktor nimmt evtl. noch das gewünschte Intervall, so dass dann ein universeller Timer entsteht.

==> Man kann hier aber natürlich auch einen beliebigen vorhandenen Timer nutzen statt einen eigenen zu bauen...
 
N

Nesselbrand

Welche vorhandene Timer gibt es denn?
Als ich im Internet gesucht habe habe ich nur diese Mehtode gefunden.
 
N

Nesselbrand

wie kann ich die methode dann in meinem actionlistener aufrufen?
da wenn ich ein neues objekt der Klasse onesectimer erstelle gibt es mir den Fehler aus dass "() cannot be applied to (MainGui)"
bei One_Sec_Clock o = new One_Sec_Clock();
 
N

Nesselbrand

Code:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainGui
{
    private JPanel Jpanel;
    private JLabel w1;
    private JLabel w2;
    private JLabel w3;
    private JButton PlayButton;
    private JLabel balance;
    private JButton InsertMoneyButton;
    private JTextField InsertMoneyValue;
    private JButton autoButton;
    private JLabel w4;

    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Einarmiger Bandit");
        frame.setContentPane(new MainGui().Jpanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public MainGui()
    {
        InsertMoneyButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                Main.balance = Main.balance + Integer.parseInt(InsertMoneyValue.getText());
                balance.setText("" + Main.balance);
                InsertMoneyValue.setText("0");
            }
        });
        PlayButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if (Main.balance == 0)
                {
                    JOptionPane.showMessageDialog(null,"Sie haben nicht genügend Geld");
                    return;
                }
                Main.balance = Main.balance - 1;
                balance.setText("" + Main.balance);
                Automat automat1 = new Automat();
                automat1.getRandomNr();
                w1.setText("" + Automat.w1);
                w2.setText("" + Automat.w2);
                w3.setText("" + Automat.w3);
                w4.setText("" + Automat.w4);
                if (Automat.w1 == Automat.w2 && Automat.w2 == Automat.w3 && Automat.w3 == Automat.w4 && Automat.w4 == 1)
                {
                    JOptionPane.showMessageDialog(null,"Sie haben Gewonnen!");
                    Main.balance = Main.balance + 100;
                    balance.setText("" + Main.balance);
                }
            }
        });
        autoButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {

            }
        });
    }
    public void auto ()
    {
        System.out.println("a");
        if (Main.balance == 0)
        {
            JOptionPane.showMessageDialog(null,"Sie haben nicht genügend Geld");
            //TODO Thread stoppen muss geschrieben und hier implementiert werden
            return;
        }
        Main.balance = Main.balance - 1;
        balance.setText("" + Main.balance);
        Automat automat1 = new Automat();
        automat1.getRandomNr();
        w1.setText("" + Automat.w1);
        w2.setText("" + Automat.w2);
        w3.setText("" + Automat.w3);
        w4.setText("" + Automat.w4);
        if (Automat.w1 == Automat.w2 && Automat.w2 == Automat.w3 && Automat.w3 == Automat.w4 && Automat.w4 == 1)
        {
            Main.balance = Main.balance + 100;
            balance.setText("" + Main.balance);
        }
        System.out.println("b");
    }
}
Code:
public class One_Sec_Clock implements Runnable
{
    private Thread thread = null;
    private MainGui mainGui;

    public One_Sec_Clock(MainGui mainGui)
    {
        this.mainGui = mainGui;
    }

    public void run()
    {
        while(true)
        {
            System.out.println("test1");
            try {Thread.sleep(1000); }
            catch (Exception e1) {
                System.out.println("return");
                return;
            }
            System.out.println("test2");
            mainGui.auto();
            System.out.println("test3");
        }
    }
    public void threadstarten()
    {
        thread.start();
    }
    public void threadstoppen()
    {

    }

}
Code:
public class Walze
{
    /*Eine Walze hat 9 Möglichkeiten zu stehen von 1 bis 9*/

    public static int number;

    public int RandomNumber()
    {
        int temp = (int) (Math.random() * 9 + 1);
        return temp;
    }
}




public class Automat
{
    public static int w1;
    public static int w2;
    public static int w3;
    public static int w4;

    public void getRandomNr()
    {
        Walze w = new Walze();
        w1 = w.RandomNumber();
        w2 = w.RandomNumber();
        w3 = w.RandomNumber();
        w4 = w.RandomNumber();
    }
}
 
J

JustNobody

Also in dem Code sehe ich jetzt keine Stelle mit One_Sec_Clock o = new One_Sec_Clock();.

Aber der Konstruktor von One_Sec_Clock will ja ein MainGui als Parameter. Also innerhalb von MainGui wäre das dann z.B.:
One_Sec_Clock o = new One_Sec_Clock(this);
 
Thema: 

Methode mit einer Arraylist

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben