# Game of Life: Was mache ich falsch?



## Big_Reddy (10. Okt 2016)

Ich finde Conway's Game of Life sehr faszinieren und wollte deshalb es mal selbst in Java umsetzten. Doch beim Ausführen habe ich gemerkt, dass statt der schönen Muster und Formen, sich meine Zellen einfach nur ausbreiten.
Ich kann den Fehler nicht finden und fände es toll, wenn ihr mir sagen könntet was ich falsch mache...

```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

@SuppressWarnings("serial")
public class GameOfLife extends JFrame {
  
    private BufferedImage img;
    private int black;
    private int white;
  
    public GameOfLife() {
        super("");
        //setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setSize(200, 200);
        setUndecorated(true);
        img = new BufferedImage(getWidth(), getHeight(), 1);
        black = new Color(0,0,0).getRGB();
        white = new Color(255,255,255).getRGB();
        for(int x = 0; x < getWidth(); x++) {
            for(int y = 0; y < getHeight(); y++) {
                img.setRGB(x, y, Math.random()*5 > 1 ? black : white);
                //img.setRGB(x, y, black);
            }
        }
        setCursor(getToolkit().createCustomCursor(new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB), new Point(0, 0),"null"));
        setVisible(true);
    }
  
    private void run() {
        do {
            repaint();
            try {
                Thread.sleep(100);
            } catch(Exception e) {
              
            }
        } while(true);
    }
  
    public void paint(Graphics g) {
        super.paint(g);
        BufferedImage temp = img.getSubimage(0, 0, img.getWidth(), img.getHeight());
        for(int x = 0; x < getWidth(); x++) {

            for(int y = 0; y < getHeight(); y++) {
                int c = getNeigbours(x, y);
                int col;
                if(img.getRGB(x, y) == white) {
                    if(c == 2 || c == 3) {
                        col = white;
                    } else {
                        col = black;
                    }
                } else {
                    if(c == 3) {
                        col = white;
                    } else {
                        col = black;
                    }
                }
                temp.setRGB(x, y, col);
            }
        }
        img = temp.getSubimage(0, 0, temp.getWidth(), temp.getHeight());
        g.drawImage(img, 0, 0, this);
    }
  
    private int getNeigbours(int x, int y) {
        int count = 0;
        for(int i = x-1; i <= x+1; i++) {
            if(i < 0 || i > getWidth()-1) {
                return 8;
            }
            for(int j = y-1; j <= y+1; j++) {
                if(j < 0 || j > getHeight()-1) {
                    return 8;
                }
                if(img.getRGB(i, j) == white) {
                    count++;
                }
            }
        }
        return count;
      
    }
  
    public static void main(String[] args) {
        new GameOfLife().run();
    }
}
```


----------



## fhoffmann (10. Okt 2016)

Hallo,

du beginnst schon damit, Felder umzufärben, wenn du die Felder noch für die Untersuchung benötigst.

Gruß
Fritz


----------



## Jardcore (10. Okt 2016)

Außerdem vermischt du hier Logik Daten und die Darstellung miteinander. GameOfLife ist ein gutes Lehrprojekt um die Modularisierung von Code zu lernen. Schau dir dazu mal https://de.wikipedia.org/wiki/Model_View_Controller an.
Wieso erbst du von JFrame, erben heißt das man etwas erweitert und nicht das man es nur benutzen will. Dafür hättest du in der GameOfLife Klasse auch einfach ein Attribut vom Typ JFrame hinzufügen können.
Spontan habe ich dazu das hier gefunden: https://wiki.byte-welt.net/wiki/Warum_man_nicht_von_JFrame/JDialog_erben_sollte

Generell sollten sich deine Probleme von ganz alleine beheben wenn du deinen Code ordentlich strukturierst.

Ich würde GameOfLife erstmal so implementieren das die Logik und das Model funktioniert und später die GUI basteln. Und für das Spielfeld des Models reicht hier ein einfaches boolean[] Array


----------



## RalleYTN (11. Okt 2016)

Jardcore hat gesagt.:


> ... Wieso erbst du von JFrame, erben heißt das man etwas erweitert und nicht das man es nur benutzen will. ...


Wahrscheinlich weil viele Lehrer, Lehrbücher und YouTuber es so zeigen. Ist natürlich unsinnig wird aber so in die Köpfe der Anfänger gehämmert. Hatte es als ich mit GUIs angefangen habe auch so gemacht.

@Big_Reddy Als ich mal die Aufgabe bekommen habe Game Of Life zu programmieren habe ich das mit einem zweidimensionalen Array von Booleans gelöst.
true = lebend
false = tot

Und.... ehrlich.... erstell nicht in jedem Durchlauf ein neues Bild.
Hier mal ein kleiner Codeschnipsel für dauerhaft aktualisierende Fenster.

```
public class Program {
    public static void main(String[] args) {
        Canvas canvas = new Canvas();
        JFrame frame = new JFrame("Conways Game of Life");
        frame.setSize(200, 200);
        frame.setLocationRelativeTo(null); // zentriert das Fenster auf dem Desktop
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(canvas);
        frame.setVisible(true);

        new Thread(new Runnable() {
            @Override
            public void run() {
                // Berechnungen hier
                canvas.repaint();
            }
        }).start();
    }

    private class Canvas extends JPanel {
        @Override
        public void paintComponent(Graphics graphics) {
            super.paintComponent(graphics)

            // Graphikoperationen kommen hier rein. Du kannst direkt auf das Graphics Objekt zeichnen
            // Beispiel: Ich mache die gesamte Fläche rot
            graphics.setColor(Color.RED);
            graphics.fillRect(0, 0, this.getWidth(), this.getHeight());
        }
    }
}
```


----------

