summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2015-12-03 04:34:54 +0000
committerGregor Kleen <gkleen@yggdrasil.li>2015-12-03 04:34:54 +0000
commit0ad31dcca37df9891ed5d5b70f12a966fc821c6d (patch)
tree2689bed05d601540496bdb08970f6394fce85d1f
parent08df57dfae088db5a94fc6b1a23935e19e204c1b (diff)
downloaduni-0ad31dcca37df9891ed5d5b70f12a966fc821c6d.tar
uni-0ad31dcca37df9891ed5d5b70f12a966fc821c6d.tar.gz
uni-0ad31dcca37df9891ed5d5b70f12a966fc821c6d.tar.bz2
uni-0ad31dcca37df9891ed5d5b70f12a966fc821c6d.tar.xz
uni-0ad31dcca37df9891ed5d5b70f12a966fc821c6d.zip
EiP - 07
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Ansicht.java64
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/GraphicsWindow.java393
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Main.java25
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Param.java25
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Position.java27
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spieler.java80
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spielfeld.java198
-rw-r--r--ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Zelle.java35
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Ansicht.java64
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/GraphicsWindow.java393
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Main.java25
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Param.java26
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Position.java27
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spieler.java79
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spielfeld.java198
-rw-r--r--ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Zelle.java47
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Ansicht.java99
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/GraphicsWindow.java393
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Hexagon.java76
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Main.java25
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Param.java25
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Position.java31
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spieler.java81
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spielfeld.java205
-rw-r--r--ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Zelle.java47
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Ansicht.java64
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/GraphicsWindow.java393
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Main.java25
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Param.java26
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Position.java27
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Spieler.java79
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Spielfeld.java198
-rw-r--r--ws2015/eip/blaetter/07/de/lmu/tcs/Zelle.java47
-rw-r--r--ws2015/eip/blaetter/07/manifest3
34 files changed, 3550 insertions, 0 deletions
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Ansicht.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Ansicht.java
new file mode 100644
index 0000000..f643974
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Ansicht.java
@@ -0,0 +1,64 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * View
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Ansicht {
11
12 private final GraphicsWindow fenster;
13 private final int max_x; //Breite
14 private final int max_y; //Höhe
15 private final int skalierung;
16
17
18 public Ansicht(int x, int y, int skalierung) {
19 this.max_x = x;
20 this.max_y = y;
21 this.skalierung = skalierung;
22 this.fenster = new GraphicsWindow(max_x * skalierung, max_y * skalierung);
23 }
24
25 public void zeichenZelle(Zelle zelle) {
26 Position pos = zelle.getPosition();
27 Rectangle box = new Rectangle(pos.getX() * skalierung, pos.getY() * skalierung, skalierung - 1, skalierung - 1);
28 if (zelle.istLebendig()) {
29 fenster.setColor(Param.FARBE_LEBENDIG);
30 } else {
31 fenster.setColor(Param.FARBE_TOT);
32 }
33 fenster.fill(box);
34 }
35
36 public void zeichneSpielfeld(Zelle[][] feld) {
37 fenster.clear();
38
39// for (int x = 0; x < max_x; x++) {
40// for (int y = 0; y < max_y; y++) {
41// zeichenZelle(feld[x][y]);
42// }
43// Äquivalente Alternative ohne explizite Indizes:
44 for (Zelle[] zeile : feld) {
45 for (Zelle zelle : zeile) {
46 zeichenZelle(zelle);
47 }
48 }
49 }
50
51 public Position getClick() {
52 Point point = fenster.mouseClick();
53 Position result = new Position(point.x / skalierung, point.y /skalierung);
54 return result;
55 }
56
57 public void sleep(long delay) {
58 fenster.sleep(delay);
59 }
60
61 public void setText(String message) {
62 fenster.setText(message);
63 }
64}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/GraphicsWindow.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/GraphicsWindow.java
new file mode 100644
index 0000000..a1f90bf
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/GraphicsWindow.java
@@ -0,0 +1,393 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4import java.util.ArrayList;
5import javax.swing.JFrame;
6import javax.swing.JPanel;
7import javax.swing.Timer;
8
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.awt.event.MouseEvent;
15import java.awt.geom.RectangularShape;
16import java.awt.geom.GeneralPath;
17
18/**
19 Eine Klasse zu pädagogischen Zwecken.
20 Erlaubt die Eingabe von Punktkoordinaten
21 mittels Mausklicks, das Zeichnen einfacher
22 2D Objekte (java.awt.Shape), sowie die
23 Ausgabe von Texten in einer Statuszeile.
24 @version 3.043
25 @author Martin Hofmann und die EiP-Teams verschiedener Jahre
26 */
27
28public class GraphicsWindow {
29
30 private int width;
31 private int height;
32 private JFrame dasFenster;
33 private static int fensterZahl;
34 private static int fensterNr;
35 private Label label;
36 private GraphicsWindowPanel panel;
37 private Point mousePos;
38 private Color activeColor = Color.BLACK;
39 final private Color backColor = Color.WHITE;
40 MyMouseAdapter mouseListener;
41
42 /**
43 Erzeugt ein Fenster der Größe 640 auf 480 mit Textausgabe, Mauseingabe und Grafikausgabe.
44 */
45 public GraphicsWindow() {
46 this(640, 480);
47 }
48
49 /**
50 Erzeugt ein Fenster in vorgegebener Größe mit Textausgabe, Mauseingabe und Grafikausgabe.
51 @param width Breite des Fensters
52 @param height Höhe des Fensters
53 */
54 public GraphicsWindow(int width, int height) {
55 this.width = width;
56 this.height = height;
57 dasFenster = new JFrame();
58 dasFenster.setTitle("Grafikfenster " + ++fensterNr);
59 fensterZahl++;
60 dasFenster.setLocationByPlatform(true);
61 dasFenster.setSize(width,height+50);
62 dasFenster.getContentPane().setPreferredSize(new Dimension(width, height+50));
63 dasFenster.pack();
64 dasFenster.addWindowListener(new WindowAdapter(){
65 public void windowClosing(WindowEvent e) {
66 dasFenster.dispose(); // nicht gleich alle Fenster abschiessen
67 if (--fensterZahl<1) System.exit(0);
68 }
69 });
70
71 label = new Label("Statuszeile...");
72 label.setFont(new Font("Helvetica", Font.PLAIN, 12));
73 dasFenster.getContentPane().add(label,"North" );
74 panel = new GraphicsWindowPanel();
75 //panel.setBackground(Color.cyan);
76 panel.addCommand(new SetColor(activeColor));
77 dasFenster.getContentPane().add(panel,"Center");
78 mousePos = new Point();
79 mouseListener = new MyMouseAdapter();
80 panel.addMouseListener(mouseListener);
81 clear();
82 dasFenster.setVisible(true);
83 }
84
85 /**
86 Gibt eine Zeichenkette oben im Fenster aus.
87 @param text diese Zeichenkette
88 */
89 public void setText(String text) {
90 label.setText(text);
91 }
92 /**
93 Liest den oben im Fenster angezeigten Text aus.
94 @return den Text
95 */
96 public String getText() {
97 return label.getText();
98 }
99 /**
100 Wartet auf einen Mausklick. Die Methode blockiert das
101 aufrufende Programm solange bis der Mausklick erfolgt ist.
102 @return die Koordinaten des angeklickten Punkts
103 */
104
105 public Point mouseClick() {
106 try{
107 synchronized(mouseListener){mouseListener.wait();}
108 }
109 catch(InterruptedException e){
110 e.printStackTrace();
111 }
112 return mousePos;
113 }
114
115 class MyMouseAdapter extends MouseAdapter {
116
117 /**
118 Beendet das Warten auf den Mausklick und verwertet die Koordinaten.
119 Diese Methode ist nicht für den Anwender bestimmt.
120 */
121
122 synchronized public void mouseClicked(MouseEvent e){
123 mousePos = e.getPoint();
124 notifyAll();
125 }
126 }
127
128
129 /**
130 Schaltet die Zeichenfarbe auf die Hintergrundfarbe um. Dies ist
131 das Mittel, um gezeichnete Linien wieder zu löschen.
132 */
133 public void switchToBackgroundColor(){
134 activeColor = backColor;
135 panel.addCommand(new SwitchToBackgroundColor(activeColor));
136 panel.repaint();
137 }
138
139 /**
140 Schaltet die Zeichenfarbe auf Schwarz um.
141 */
142 public void switchToForegroundColor(){
143 activeColor = Color.BLACK;
144 panel.addCommand(new SetColor(activeColor));
145 panel.repaint();
146 }
147
148
149 /** Liefert die aktuelle Zeichenfarbe.
150 @return die aktuelle Zeichenfarbe des GraphicsWindow. */
151 public Color getColor() {
152 // return panel.getGraphics().getColor(); // getGraphics() has unpleasant side-effects. :(
153 /* Fixed by adding another instance variable activeColor for now. */
154 return activeColor;
155 }
156
157 /**
158 Zeichnet eine Linie in der aktuellen Zeichenfarbe.
159 @param x Anfangspunkt
160 @param y Endpunkt
161 */
162 public void drawLine(Point x, Point y){
163 // Odering points reduces the amount of graphical artifacts in rendering the same object in different ways
164 Point x1 = x;
165 Point y1 = y;
166 if ((x.x > y.x) || ((x.x == y.x) && (x.y > y.y))) {
167 x1 = y;
168 y1 = x;
169 }
170 panel.addCommand(new DrawLine(x1,y1));
171 panel.repaint();
172 }
173
174 /**
175 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
176 @param p Punkt
177 */
178 public void drawPoint(Point p){
179 drawLine(p, p);
180 }
181
182 /**
183 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
184 @param p Punkt
185 */
186 public void drawStringAt(String s, Point p){
187 Command c = new DrawString(s,p);
188 panel.addCommand(c);
189 panel.repaint();
190 }
191
192 /**
193 Zeichnet ein geometrisches Objekt.
194 */
195 public void draw(Shape s) {
196 panel.addCommand(new Draw(s));
197 panel.repaint();
198 }
199
200 /**
201 Füllt ein geometrisches Objekt aus.
202 */
203 public void fill(Shape s) {
204 panel.addCommand(new Fill(s));
205 panel.repaint();
206 }
207
208 /** Das aufrufende Programm wird für ein gegebene Zeitspanne blockiert.
209 @param millis Die Zeitspanne in Millisekunden*/
210 public void sleep(long millis) {
211 try {Thread.sleep(millis);} catch (Exception e){}
212 }
213
214 /** Setzt die Zeichenfarbe. */
215 public void setColor(Color d) {
216 activeColor = d;
217 panel.addCommand(new SetColor(activeColor));
218 panel.repaint();
219 }
220
221 /**
222 Setzt die Zeichenfarbe auf einen Grauwert
223 @param shade Grauwert zwischen 0(schwarz) und 255(weiß)
224 */
225 public void setGrayColor(int shade) {
226 setColor(new Color(shade, shade, shade));
227 }
228
229 /**
230 Setzt die Zeichenfarbe für die Mandelbrot-Aufgabe
231 @param n Anzahl der Iterationen, die durch die Farbe symboliziert werdem soll
232 */
233 public void setMandelColor(int n) {
234 float r = (float) Math.min(1.0,((double) n / 9.0) );
235 float g = (float) Math.min(1.0,((double) n / 99.0) );
236 float b = (float) Math.min(1.0,((double) n / 999.0) );
237 setColor(new Color(r, g, b));
238 }
239
240 /** Löscht das Bild */
241 public void clear() {
242// Color oldActive = activeColor;
243 panel.clearAll();
244// this.switchToBackgroundColor();
245// fill(new Rectangle(0,0,width,height));
246// setColor(oldActive);
247 }
248
249 public void killIn(int secs) {
250 Timer t = new Timer(1000*secs, new ActionListener(){
251 @Override
252 public void actionPerformed(ActionEvent e) {dasFenster.dispose();}
253 }
254 );
255 t.setRepeats(false);
256 t.start();
257 }
258}
259
260
261class GraphicsWindowPanel extends JPanel
262{
263 private static final long serialVersionUID = 1L;
264 private ArrayList<Command> cl = new ArrayList<Command>();
265
266 public void paintComponent(Graphics g)
267 {
268 super.paintComponent(g);
269 Graphics2D g2D = (Graphics2D)g;
270
271 ArrayList<Command> cl = this.cl; // Kopie wegen Nebenläufigkeit von Swing
272 int size = cl.size();
273 for (int i=0; i<size; i++) {
274 Command c = cl.get(i);
275 if (c != null) c.execute(g2D);
276 }
277 }
278
279 void addCommand(Command c)
280 {
281 cl.add(c);
282 }
283
284 void clearAll()
285 {
286// try {
287// SwingUtilities.invokeAndWait(new Runnable() {
288// @Override
289// public void run() {
290 cl = new ArrayList<Command>();
291// }
292// });
293// } catch (InterruptedException e) {
294// // TODO Auto-generated catch block
295// e.printStackTrace();
296// } catch (InvocationTargetException e) {
297// // TODO Auto-generated catch block
298// e.printStackTrace();
299// }
300 }
301}
302
303
304abstract class Command //implements Serializable
305{
306 abstract void execute(Graphics2D g2D);
307
308 /** Clone a shape. This method is needed because Shape
309 * does not define clone(), although many shape classes do.
310 * Kopiert aus jsky-2.6 auf ftp.eso.org */
311 static Shape cloneShape(Shape s) {
312 // FIXME Add more specific shapes
313 if (s instanceof RectangularShape) {
314 return (RectangularShape) ((RectangularShape) s).clone();
315 } else {
316 return new GeneralPath(s);
317 }
318 }
319
320}
321
322class DrawLine extends Command {
323 Point von;
324 Point bis;
325 DrawLine(Point von, Point bis) {
326 /* Clonen der Punkte essentiell um Aliasingeffekte beim Redraw zu verhindern */
327 this.von = new Point(von);
328 this.bis = new Point(bis);
329 }
330 void execute(Graphics2D g2D)
331 {
332 g2D.drawLine(this.von.x,this.von.y,this.bis.x,this.bis.y);
333 }
334}
335
336class SwitchToForegroundColor extends Command {
337 SwitchToForegroundColor() {}
338 void execute(Graphics2D g2D) {
339 g2D.setColor(Color.black);
340 }
341}
342
343class SwitchToBackgroundColor extends Command {
344 Color backcolor;
345 SwitchToBackgroundColor(Color backcolor) {this.backcolor = backcolor;}
346 void execute(Graphics2D g2D) {
347 g2D.setColor(backcolor);
348 }
349}
350
351class SetColor extends Command {
352 Color color;
353 SetColor(Color color) {this.color = color;}
354 void execute(Graphics2D g2D) {
355 g2D.setColor(this.color);
356 }
357}
358
359
360class Draw extends Command {
361 Shape shape;
362 Draw(Shape shape) {this.shape = cloneShape(shape);}
363 void execute(Graphics2D g2D) {
364 g2D.draw(this.shape);
365 }
366}
367
368class Fill extends Command {
369 Shape shape;
370 Fill(Shape shape) {this.shape = cloneShape(shape);}
371 void execute(Graphics2D g2D) {
372 g2D.fill(this.shape);
373 }
374}
375
376class DrawString extends Command {
377 String string;
378 Point position;
379 DrawString(String string, Point position) {this.string = string; this.position = position;}
380 @Override
381 void execute(Graphics2D g2D) {
382 g2D.drawString(string, position.x, position.y);
383 }
384}
385
386
387
388
389
390
391
392
393
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Main.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Main.java
new file mode 100644
index 0000000..4177aca
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Main.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3
4/**
5 * Game of Life nach der Idee von John Horton Conway
6 *
7 * Fallstudie für Objektorientiertes Design nach MVC Entwurfswuster
8 * im Rahmen der
9 * "Einführung in die Programmierung" WS2015/16
10 *
11 * Lehrstuhl für Theoretische Informatik
12 * LMU München
13 *
14 * Prof Martin Hofmann, Dr Steffen Jost
15 *
16 * Created by jost on 24.11.15.
17 */
18public class Main {
19
20 public static void main(String[] args) {
21 Spieler spieler = new Spieler();
22 spieler.spielDurchführen();
23 System.exit(0);
24 }
25}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Param.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Param.java
new file mode 100644
index 0000000..5b42421
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Param.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * Sammlung aller extern festgelegten Konstanten
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Param {
11
12 // Konstanten für das Spiel
13 public static final int SPIEL_HÖHE = 50;
14 public static final int SPIEL_BREITE = 80;
15
16 // Konstanten für die View
17 public static final Color FARBE_LEBENDIG = Color.RED;
18 public static final Color FARBE_TOT = Color.WHITE;
19 public static final int SKALIERUNG = 10;
20
21 // Konstanten für Durchführung
22 public static final long RUNDENZEIT = 120;
23 public static final int RUNDENZAHL = 1000;
24
25}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Position.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Position.java
new file mode 100644
index 0000000..546da7f
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Position.java
@@ -0,0 +1,27 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Position {
11
12 private final int x;
13 private final int y;
14
15 public Position(int x, int y) {
16 this.x = x;
17 this.y = y;
18 }
19
20 public int getX() {
21 return this.x;
22 }
23
24 public int getY() {
25 return this.y;
26 }
27}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spieler.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spieler.java
new file mode 100644
index 0000000..12f2a0e
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spieler.java
@@ -0,0 +1,80 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4
5/**
6 * Controller
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Spieler {
11
12 private final Spielfeld spiel;
13 private final Ansicht ansicht;
14
15 public Spieler() {
16 this.spiel = new Spielfeld(Param.SPIEL_BREITE,Param.SPIEL_HÖHE);
17 this.ansicht = new Ansicht( Param.SPIEL_BREITE,Param.SPIEL_HÖHE,Param.SKALIERUNG);
18 ansicht.zeichneSpielfeld(spiel.getFeld());
19 ansicht.setText("Außerhalb Spielfeld klicken zum Beenden");
20
21 // Benutzer setzt Anfangspostionen
22 boolean nichtzuende = true;
23 do {
24 Position p = ansicht.getClick();
25 Zelle zelle = new Zelle(p, Zelle.LEBENDIG);
26 nichtzuende = spiel.setZelle(zelle);
27 if (nichtzuende) {
28 ansicht.zeichenZelle(zelle);
29 }
30 } while (nichtzuende);
31 }
32
33 public void spielDurchführen() {
34 for (int runde=0; runde < Param.RUNDENZAHL; runde++){
35 this.rundeDurchführen();
36 ansicht.setText("Runde "+runde);
37 ansicht.sleep(Param.RUNDENZEIT);
38 }
39 }
40
41
42 public void rundeDurchführen() {
43 ArrayList<Zelle> änderungen = new ArrayList<Zelle>();
44 // Änderungen anhand altem Zustand feststellen
45 for (Zelle zelle : spiel.getZellen()) {
46// ArrayList<Zelle> nachbarn = spiel.getNachbarn(zelle);
47 Zelle[] nachbarn = spiel.getNachbarnAryWrapped(zelle);
48 int lebendigeNachbarn = 0;
49 for (Zelle nachbar : nachbarn) {
50 if (nachbar.istLebendig()) lebendigeNachbarn++;
51 }
52 // if (zelle.istLebendig()) {
53 // if (lebendigeNachbarn <= 1 || lebendigeNachbarn >=4) {
54 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.TOT);
55 // änderungen.add(neu);
56 // }
57 // } else { // eventuell zu einem if umbauen, welches Zustand ins Gegenteil verkehrt
58 // if (lebendigeNachbarn == 3) {
59 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
60 // änderungen.add(neu);
61 // }
62 // }
63 Zelle neu;
64 if (zelle.istLebendig() && lebendigeNachbarn % 2 == 0)
65 neu = new Zelle(zelle.getPosition(),Zelle.TOT);
66 else if (! zelle.istLebendig() && lebendigeNachbarn % 2 == 1)
67 neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
68 else
69 neu = null;
70 if (neu != null)
71 änderungen.add(neu);
72 }
73 // Erkannte Änderungen nun einpflegen
74 for (Zelle zelle : änderungen) {
75 spiel.setZelle(zelle);
76 ansicht.zeichenZelle(zelle);
77 }
78 }
79
80}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spielfeld.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spielfeld.java
new file mode 100644
index 0000000..7b9ec60
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Spielfeld.java
@@ -0,0 +1,198 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4import java.util.Collections;
5
6/**
7 * Model
8 *
9 * Created by jost on 24.11.15.
10 */
11public class Spielfeld {
12
13 private final Zelle[][] feld;
14 private final int max_x; //Breite
15 private final int max_y; //Höhe
16
17 public Spielfeld(int breite, int höhe) {
18 this.max_x = breite;
19 this.max_y = höhe;
20 feld = new Zelle[this.max_x][this.max_y];
21 for (int x=0;x<max_x;x++) {
22 for (int y = 0; y < max_y; y++) {
23 final Position p = new Position(x, y);
24 feld[x][y] = new Zelle(p, Zelle.TOT);
25 }
26 }
27 }
28
29 /**
30 * Liefert Zelle des Spielfelds an einer Position.
31 * @param p Position, der Zelle ausgelesen werden soll
32 * @return Zelle des Spielfelds an dieser Position, falls vorhanden; sonst null.
33 */
34 public Zelle getZelle(Position p) {
35 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
36 return feld[p.getX()][p.getY()];
37 } else {
38 return null;
39 }
40 }
41
42 /**
43 * Setzt eine gegebene Zelle ins Spielfeld ein.
44 * Überschreibt vorherige Zelle.
45 *
46 * @param zelle Einzusetzende Zelle
47 * @return Ob die Position der Zelle im Spielfeld enthalten ist (false bedeutuet ungültig).
48 */
49 public boolean setZelle(Zelle zelle) {
50 final Position p = zelle.getPosition();
51 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
52 feld[p.getX()][p.getY()] = zelle;
53 return true;
54 } else {
55 return false;
56 }
57 }
58
59 /**
60 * Liefert das gesamte Spielfeld direkt aus;
61 * nicht so schöne, da interne Repräsentierung offenbart wird
62 * und das Array von aussen verändert werden kann! Autsch!
63 *
64 * @return Alle Zellen des Felds im 2D array
65 */
66 public Zelle[][] getFeld() {
67 return feld;
68 }
69
70 /**
71 * BESSERE ALTERNATIVE zu getter-Methode getFeld():
72 * Liefert alle Zellen des Spielfeldes aus. Vorteile:
73 * 1) Interne Repräsentation bleibt versteckt.
74 * 2) Da die Zellen immutable sind, kann hier das
75 * Spielfeld auch nicht woanders manipuliert werden.
76 *
77 * @return Alle Zellen des Spielfeldes als ArrayList
78 */
79 public ArrayList<Zelle> getZellen() {
80 ArrayList<Zelle> result = new ArrayList<>(max_x*max_y);
81 for (int x=0;x<max_x;x++) {
82 for (int y = 0; y < max_y; y++) {
83 result.add(feld[x][y]);
84 }
85 }
86
87 return result;
88 }
89
90 /**
91 * Genau wie getZellen, nur mit echtem Array anstatt ArrayList.
92 * Vorteile bleiben erhalten!
93 *
94 * @return Alle Zellen des Spielfeldes als Array
95 */
96 public Zelle[] getZellenAry() {
97 Zelle[] result = new Zelle[max_x*max_y];
98 int i = 0;
99 for (int x=0;x<max_x;x++) {
100 for (int y = 0; y < max_y; y++) {
101 result[i] = feld[x][y];
102 i++;
103 }
104 }
105 return result;
106 }
107
108 /**
109 * Berechnet alle Nachbarn einer Zelle.
110 *
111 * @param zelle deren Nachbarn berechnet werden sollen
112 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
113 */
114 public ArrayList<Zelle> getNachbarn(Zelle zelle) {
115 ArrayList<Zelle> result = new ArrayList<>();
116 Position pos = zelle.getPosition();
117 for (int x=-1; x<=1; x++) {
118 for (int y = -1; y <= 1; y++) {
119 if (x!=0 || y!=0) {
120 Zelle nachbar = this.getZelle(new Position(pos.getX() + x, pos.getY() + y));
121 if (nachbar != null) {
122 result.add(nachbar);
123 }
124 }
125 }
126 }
127 return result;
128 }
129
130 /**
131 * Berechnet alle Nachbarn einer Zelle.
132 * Variante von getNachbar mit Array anstatt ArrayList
133 *
134 * @param zelle deren Nachbarn berechnet werden sollen
135 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
136 */
137 public Zelle[] getNachbarnAry(Zelle zelle) {
138 Position pos = zelle.getPosition();
139 int minx = Math.max(pos.getX() - 1, 0);
140 int maxx = Math.min(pos.getX() + 1, this.max_x);
141 int miny = Math.max(pos.getY() - 1, 0);
142 int maxy = Math.min(pos.getY() + 1, this.max_y);
143 Zelle[] result = new Zelle[maxx - minx * maxy - miny];
144 int i = 0;
145 for (int x = minx; x <= maxx; x++) {
146 for (int y = miny; y <= maxy; y++) {
147 if (x!=0 || y!=0) {
148 result[i] = feld[x][y];
149 i++;
150 }
151 }
152 }
153 return result;
154 }
155
156 /**
157 * Berechnet alle Nachbarn einer Zelle auf Wrap-Around Spielfeld..
158 *
159 * @param zelle deren Nachbarn berechnet werden sollen
160 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
161 */
162 public ArrayList<Zelle> getNachbarnWrapped(Zelle zelle) {
163 ArrayList<Zelle> result = new ArrayList<Zelle>(8);
164 Position pos = zelle.getPosition();
165 for (int x = -1; x <= 1; x++) {
166 for (int y = -1; y <= 1; y++) {
167 if (x!=0 || y!=0) {
168 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
169 result.add(z);
170 }
171 }
172 }
173 return result;
174 }
175
176 /**
177 * Berechnet alle Nachbarn einer Zelle auf Warap-Around Spielfeld.
178 * Variante von getNachbarWrapped mit Array anstatt ArrayList
179 *
180 * @param zelle deren Nachbarn berechnet werden sollen
181 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
182 */
183 public Zelle[] getNachbarnAryWrapped(Zelle zelle) {
184 Zelle[] result = new Zelle[8];
185 Position pos = zelle.getPosition();
186 int i = 0;
187 for (int x = -1; x <= 1; x++) {
188 for (int y = -1; y <= 1; y++) {
189 if (x!=0 || y!=0) {
190 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
191 result[i] = z;
192 i++;
193 }
194 }
195 }
196 return result;
197 }
198}
diff --git a/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Zelle.java b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Zelle.java
new file mode 100644
index 0000000..01ac446
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1A/de/lmu/tcs/Zelle.java
@@ -0,0 +1,35 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Zelle {
11
12 public final static int TOT=0;
13 public final static int LEBENDIG=1;
14
15 private final Position position;
16 private final int zustand;
17
18 public Zelle(Position position, int zustand) {
19 this.position = position;
20 this.zustand = zustand;
21 }
22
23 public Position getPosition() {
24 return position;
25 }
26
27 public boolean istLebendig() {
28 return zustand==LEBENDIG;
29 }
30
31 public boolean istTot() {
32 return zustand==TOT;
33 }
34
35}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Ansicht.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Ansicht.java
new file mode 100644
index 0000000..49d3375
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Ansicht.java
@@ -0,0 +1,64 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * View
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Ansicht {
11
12 private final GraphicsWindow fenster;
13 private final int max_x; //Breite
14 private final int max_y; //Höhe
15 private final int skalierung;
16
17
18 public Ansicht(int x, int y, int skalierung) {
19 this.max_x = x;
20 this.max_y = y;
21 this.skalierung = skalierung;
22 this.fenster = new GraphicsWindow(max_x * skalierung, max_y * skalierung);
23 }
24
25 public void zeichenZelle(Zelle zelle) {
26 Position pos = zelle.getPosition();
27 Rectangle box = new Rectangle(pos.getX() * skalierung, pos.getY() * skalierung, skalierung - 1, skalierung - 1);
28 if (zelle.istTot()) {
29 fenster.setColor(Param.ZELLENFARBE[0]);
30 } else {
31 fenster.setColor(Param.ZELLENFARBE[Math.min(zelle.alter() + 1, Param.ZELLENFARBE.length - 1)]);
32 }
33 fenster.fill(box);
34 }
35
36 public void zeichneSpielfeld(Zelle[][] feld) {
37 fenster.clear();
38
39// for (int x = 0; x < max_x; x++) {
40// for (int y = 0; y < max_y; y++) {
41// zeichenZelle(feld[x][y]);
42// }
43// Äquivalente Alternative ohne explizite Indizes:
44 for (Zelle[] zeile : feld) {
45 for (Zelle zelle : zeile) {
46 zeichenZelle(zelle);
47 }
48 }
49 }
50
51 public Position getClick() {
52 Point point = fenster.mouseClick();
53 Position result = new Position(point.x / skalierung, point.y /skalierung);
54 return result;
55 }
56
57 public void sleep(long delay) {
58 fenster.sleep(delay);
59 }
60
61 public void setText(String message) {
62 fenster.setText(message);
63 }
64}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/GraphicsWindow.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/GraphicsWindow.java
new file mode 100644
index 0000000..a1f90bf
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/GraphicsWindow.java
@@ -0,0 +1,393 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4import java.util.ArrayList;
5import javax.swing.JFrame;
6import javax.swing.JPanel;
7import javax.swing.Timer;
8
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.awt.event.MouseEvent;
15import java.awt.geom.RectangularShape;
16import java.awt.geom.GeneralPath;
17
18/**
19 Eine Klasse zu pädagogischen Zwecken.
20 Erlaubt die Eingabe von Punktkoordinaten
21 mittels Mausklicks, das Zeichnen einfacher
22 2D Objekte (java.awt.Shape), sowie die
23 Ausgabe von Texten in einer Statuszeile.
24 @version 3.043
25 @author Martin Hofmann und die EiP-Teams verschiedener Jahre
26 */
27
28public class GraphicsWindow {
29
30 private int width;
31 private int height;
32 private JFrame dasFenster;
33 private static int fensterZahl;
34 private static int fensterNr;
35 private Label label;
36 private GraphicsWindowPanel panel;
37 private Point mousePos;
38 private Color activeColor = Color.BLACK;
39 final private Color backColor = Color.WHITE;
40 MyMouseAdapter mouseListener;
41
42 /**
43 Erzeugt ein Fenster der Größe 640 auf 480 mit Textausgabe, Mauseingabe und Grafikausgabe.
44 */
45 public GraphicsWindow() {
46 this(640, 480);
47 }
48
49 /**
50 Erzeugt ein Fenster in vorgegebener Größe mit Textausgabe, Mauseingabe und Grafikausgabe.
51 @param width Breite des Fensters
52 @param height Höhe des Fensters
53 */
54 public GraphicsWindow(int width, int height) {
55 this.width = width;
56 this.height = height;
57 dasFenster = new JFrame();
58 dasFenster.setTitle("Grafikfenster " + ++fensterNr);
59 fensterZahl++;
60 dasFenster.setLocationByPlatform(true);
61 dasFenster.setSize(width,height+50);
62 dasFenster.getContentPane().setPreferredSize(new Dimension(width, height+50));
63 dasFenster.pack();
64 dasFenster.addWindowListener(new WindowAdapter(){
65 public void windowClosing(WindowEvent e) {
66 dasFenster.dispose(); // nicht gleich alle Fenster abschiessen
67 if (--fensterZahl<1) System.exit(0);
68 }
69 });
70
71 label = new Label("Statuszeile...");
72 label.setFont(new Font("Helvetica", Font.PLAIN, 12));
73 dasFenster.getContentPane().add(label,"North" );
74 panel = new GraphicsWindowPanel();
75 //panel.setBackground(Color.cyan);
76 panel.addCommand(new SetColor(activeColor));
77 dasFenster.getContentPane().add(panel,"Center");
78 mousePos = new Point();
79 mouseListener = new MyMouseAdapter();
80 panel.addMouseListener(mouseListener);
81 clear();
82 dasFenster.setVisible(true);
83 }
84
85 /**
86 Gibt eine Zeichenkette oben im Fenster aus.
87 @param text diese Zeichenkette
88 */
89 public void setText(String text) {
90 label.setText(text);
91 }
92 /**
93 Liest den oben im Fenster angezeigten Text aus.
94 @return den Text
95 */
96 public String getText() {
97 return label.getText();
98 }
99 /**
100 Wartet auf einen Mausklick. Die Methode blockiert das
101 aufrufende Programm solange bis der Mausklick erfolgt ist.
102 @return die Koordinaten des angeklickten Punkts
103 */
104
105 public Point mouseClick() {
106 try{
107 synchronized(mouseListener){mouseListener.wait();}
108 }
109 catch(InterruptedException e){
110 e.printStackTrace();
111 }
112 return mousePos;
113 }
114
115 class MyMouseAdapter extends MouseAdapter {
116
117 /**
118 Beendet das Warten auf den Mausklick und verwertet die Koordinaten.
119 Diese Methode ist nicht für den Anwender bestimmt.
120 */
121
122 synchronized public void mouseClicked(MouseEvent e){
123 mousePos = e.getPoint();
124 notifyAll();
125 }
126 }
127
128
129 /**
130 Schaltet die Zeichenfarbe auf die Hintergrundfarbe um. Dies ist
131 das Mittel, um gezeichnete Linien wieder zu löschen.
132 */
133 public void switchToBackgroundColor(){
134 activeColor = backColor;
135 panel.addCommand(new SwitchToBackgroundColor(activeColor));
136 panel.repaint();
137 }
138
139 /**
140 Schaltet die Zeichenfarbe auf Schwarz um.
141 */
142 public void switchToForegroundColor(){
143 activeColor = Color.BLACK;
144 panel.addCommand(new SetColor(activeColor));
145 panel.repaint();
146 }
147
148
149 /** Liefert die aktuelle Zeichenfarbe.
150 @return die aktuelle Zeichenfarbe des GraphicsWindow. */
151 public Color getColor() {
152 // return panel.getGraphics().getColor(); // getGraphics() has unpleasant side-effects. :(
153 /* Fixed by adding another instance variable activeColor for now. */
154 return activeColor;
155 }
156
157 /**
158 Zeichnet eine Linie in der aktuellen Zeichenfarbe.
159 @param x Anfangspunkt
160 @param y Endpunkt
161 */
162 public void drawLine(Point x, Point y){
163 // Odering points reduces the amount of graphical artifacts in rendering the same object in different ways
164 Point x1 = x;
165 Point y1 = y;
166 if ((x.x > y.x) || ((x.x == y.x) && (x.y > y.y))) {
167 x1 = y;
168 y1 = x;
169 }
170 panel.addCommand(new DrawLine(x1,y1));
171 panel.repaint();
172 }
173
174 /**
175 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
176 @param p Punkt
177 */
178 public void drawPoint(Point p){
179 drawLine(p, p);
180 }
181
182 /**
183 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
184 @param p Punkt
185 */
186 public void drawStringAt(String s, Point p){
187 Command c = new DrawString(s,p);
188 panel.addCommand(c);
189 panel.repaint();
190 }
191
192 /**
193 Zeichnet ein geometrisches Objekt.
194 */
195 public void draw(Shape s) {
196 panel.addCommand(new Draw(s));
197 panel.repaint();
198 }
199
200 /**
201 Füllt ein geometrisches Objekt aus.
202 */
203 public void fill(Shape s) {
204 panel.addCommand(new Fill(s));
205 panel.repaint();
206 }
207
208 /** Das aufrufende Programm wird für ein gegebene Zeitspanne blockiert.
209 @param millis Die Zeitspanne in Millisekunden*/
210 public void sleep(long millis) {
211 try {Thread.sleep(millis);} catch (Exception e){}
212 }
213
214 /** Setzt die Zeichenfarbe. */
215 public void setColor(Color d) {
216 activeColor = d;
217 panel.addCommand(new SetColor(activeColor));
218 panel.repaint();
219 }
220
221 /**
222 Setzt die Zeichenfarbe auf einen Grauwert
223 @param shade Grauwert zwischen 0(schwarz) und 255(weiß)
224 */
225 public void setGrayColor(int shade) {
226 setColor(new Color(shade, shade, shade));
227 }
228
229 /**
230 Setzt die Zeichenfarbe für die Mandelbrot-Aufgabe
231 @param n Anzahl der Iterationen, die durch die Farbe symboliziert werdem soll
232 */
233 public void setMandelColor(int n) {
234 float r = (float) Math.min(1.0,((double) n / 9.0) );
235 float g = (float) Math.min(1.0,((double) n / 99.0) );
236 float b = (float) Math.min(1.0,((double) n / 999.0) );
237 setColor(new Color(r, g, b));
238 }
239
240 /** Löscht das Bild */
241 public void clear() {
242// Color oldActive = activeColor;
243 panel.clearAll();
244// this.switchToBackgroundColor();
245// fill(new Rectangle(0,0,width,height));
246// setColor(oldActive);
247 }
248
249 public void killIn(int secs) {
250 Timer t = new Timer(1000*secs, new ActionListener(){
251 @Override
252 public void actionPerformed(ActionEvent e) {dasFenster.dispose();}
253 }
254 );
255 t.setRepeats(false);
256 t.start();
257 }
258}
259
260
261class GraphicsWindowPanel extends JPanel
262{
263 private static final long serialVersionUID = 1L;
264 private ArrayList<Command> cl = new ArrayList<Command>();
265
266 public void paintComponent(Graphics g)
267 {
268 super.paintComponent(g);
269 Graphics2D g2D = (Graphics2D)g;
270
271 ArrayList<Command> cl = this.cl; // Kopie wegen Nebenläufigkeit von Swing
272 int size = cl.size();
273 for (int i=0; i<size; i++) {
274 Command c = cl.get(i);
275 if (c != null) c.execute(g2D);
276 }
277 }
278
279 void addCommand(Command c)
280 {
281 cl.add(c);
282 }
283
284 void clearAll()
285 {
286// try {
287// SwingUtilities.invokeAndWait(new Runnable() {
288// @Override
289// public void run() {
290 cl = new ArrayList<Command>();
291// }
292// });
293// } catch (InterruptedException e) {
294// // TODO Auto-generated catch block
295// e.printStackTrace();
296// } catch (InvocationTargetException e) {
297// // TODO Auto-generated catch block
298// e.printStackTrace();
299// }
300 }
301}
302
303
304abstract class Command //implements Serializable
305{
306 abstract void execute(Graphics2D g2D);
307
308 /** Clone a shape. This method is needed because Shape
309 * does not define clone(), although many shape classes do.
310 * Kopiert aus jsky-2.6 auf ftp.eso.org */
311 static Shape cloneShape(Shape s) {
312 // FIXME Add more specific shapes
313 if (s instanceof RectangularShape) {
314 return (RectangularShape) ((RectangularShape) s).clone();
315 } else {
316 return new GeneralPath(s);
317 }
318 }
319
320}
321
322class DrawLine extends Command {
323 Point von;
324 Point bis;
325 DrawLine(Point von, Point bis) {
326 /* Clonen der Punkte essentiell um Aliasingeffekte beim Redraw zu verhindern */
327 this.von = new Point(von);
328 this.bis = new Point(bis);
329 }
330 void execute(Graphics2D g2D)
331 {
332 g2D.drawLine(this.von.x,this.von.y,this.bis.x,this.bis.y);
333 }
334}
335
336class SwitchToForegroundColor extends Command {
337 SwitchToForegroundColor() {}
338 void execute(Graphics2D g2D) {
339 g2D.setColor(Color.black);
340 }
341}
342
343class SwitchToBackgroundColor extends Command {
344 Color backcolor;
345 SwitchToBackgroundColor(Color backcolor) {this.backcolor = backcolor;}
346 void execute(Graphics2D g2D) {
347 g2D.setColor(backcolor);
348 }
349}
350
351class SetColor extends Command {
352 Color color;
353 SetColor(Color color) {this.color = color;}
354 void execute(Graphics2D g2D) {
355 g2D.setColor(this.color);
356 }
357}
358
359
360class Draw extends Command {
361 Shape shape;
362 Draw(Shape shape) {this.shape = cloneShape(shape);}
363 void execute(Graphics2D g2D) {
364 g2D.draw(this.shape);
365 }
366}
367
368class Fill extends Command {
369 Shape shape;
370 Fill(Shape shape) {this.shape = cloneShape(shape);}
371 void execute(Graphics2D g2D) {
372 g2D.fill(this.shape);
373 }
374}
375
376class DrawString extends Command {
377 String string;
378 Point position;
379 DrawString(String string, Point position) {this.string = string; this.position = position;}
380 @Override
381 void execute(Graphics2D g2D) {
382 g2D.drawString(string, position.x, position.y);
383 }
384}
385
386
387
388
389
390
391
392
393
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Main.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Main.java
new file mode 100644
index 0000000..4177aca
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Main.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3
4/**
5 * Game of Life nach der Idee von John Horton Conway
6 *
7 * Fallstudie für Objektorientiertes Design nach MVC Entwurfswuster
8 * im Rahmen der
9 * "Einführung in die Programmierung" WS2015/16
10 *
11 * Lehrstuhl für Theoretische Informatik
12 * LMU München
13 *
14 * Prof Martin Hofmann, Dr Steffen Jost
15 *
16 * Created by jost on 24.11.15.
17 */
18public class Main {
19
20 public static void main(String[] args) {
21 Spieler spieler = new Spieler();
22 spieler.spielDurchführen();
23 System.exit(0);
24 }
25}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Param.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Param.java
new file mode 100644
index 0000000..88f8248
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Param.java
@@ -0,0 +1,26 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * Sammlung aller extern festgelegten Konstanten
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Param {
11
12 // Konstanten für das Spiel
13 public static final int SPIEL_HÖHE = 50;
14 public static final int SPIEL_BREITE = 80;
15
16 // Konstanten für die View
17 // public static final Color FARBE_LEBENDIG = Color.RED;
18 // public static final Color FARBE_TOT = Color.WHITE;
19 public static final Color[] ZELLENFARBE = new Color[] {Color.WHITE, Color.RED, Color.ORANGE, Color.MAGENTA, Color.GREEN, Color.CYAN, Color.BLUE};
20 public static final int SKALIERUNG = 10;
21
22 // Konstanten für Durchführung
23 public static final long RUNDENZEIT = 120;
24 public static final int RUNDENZAHL = 1000;
25
26}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Position.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Position.java
new file mode 100644
index 0000000..546da7f
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Position.java
@@ -0,0 +1,27 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Position {
11
12 private final int x;
13 private final int y;
14
15 public Position(int x, int y) {
16 this.x = x;
17 this.y = y;
18 }
19
20 public int getX() {
21 return this.x;
22 }
23
24 public int getY() {
25 return this.y;
26 }
27}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spieler.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spieler.java
new file mode 100644
index 0000000..98bca6e
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spieler.java
@@ -0,0 +1,79 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4
5/**
6 * Controller
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Spieler {
11
12 private final Spielfeld spiel;
13 private final Ansicht ansicht;
14
15 public Spieler() {
16 this.spiel = new Spielfeld(Param.SPIEL_BREITE,Param.SPIEL_HÖHE);
17 this.ansicht = new Ansicht( Param.SPIEL_BREITE,Param.SPIEL_HÖHE,Param.SKALIERUNG);
18 ansicht.zeichneSpielfeld(spiel.getFeld());
19 ansicht.setText("Außerhalb Spielfeld klicken zum Beenden");
20
21 // Benutzer setzt Anfangspostionen
22 boolean nichtzuende = true;
23 do {
24 Position p = ansicht.getClick();
25 Zelle zelle = new Zelle(p, Zelle.LEBENDIG);
26 nichtzuende = spiel.setZelle(zelle);
27 if (nichtzuende) {
28 ansicht.zeichenZelle(zelle);
29 }
30 } while (nichtzuende);
31 }
32
33 public void spielDurchführen() {
34 for (int runde=0; runde < Param.RUNDENZAHL; runde++){
35 this.rundeDurchführen();
36 ansicht.setText("Runde "+runde);
37 ansicht.sleep(Param.RUNDENZEIT);
38 }
39 }
40
41
42 public void rundeDurchführen() {
43 ArrayList<Zelle> änderungen = new ArrayList<Zelle>();
44 // Änderungen anhand altem Zustand feststellen
45 for (Zelle zelle : spiel.getZellen()) {
46// ArrayList<Zelle> nachbarn = spiel.getNachbarn(zelle);
47 Zelle[] nachbarn = spiel.getNachbarnAryWrapped(zelle);
48 int lebendigeNachbarn = 0;
49 for (Zelle nachbar : nachbarn) {
50 if (nachbar.istLebendig()) lebendigeNachbarn++;
51 }
52 // if (zelle.istLebendig()) {
53 // if (lebendigeNachbarn <= 1 || lebendigeNachbarn >=4) {
54 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.TOT);
55 // änderungen.add(neu);
56 // }
57 // } else { // eventuell zu einem if umbauen, welches Zustand ins Gegenteil verkehrt
58 // if (lebendigeNachbarn == 3) {
59 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
60 // änderungen.add(neu);
61 // }
62 // }
63 Zelle neu;
64 if (zelle.istLebendig() && lebendigeNachbarn % 2 == 0)
65 neu = new Zelle(zelle.getPosition(),Zelle.TOT);
66 else if (! zelle.istLebendig() && lebendigeNachbarn % 2 == 1)
67 neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
68 else
69 neu = zelle.nachkommen();
70 änderungen.add(neu);
71 }
72 // Erkannte Änderungen nun einpflegen
73 for (Zelle zelle : änderungen) {
74 spiel.setZelle(zelle);
75 ansicht.zeichenZelle(zelle);
76 }
77 }
78
79}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spielfeld.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spielfeld.java
new file mode 100644
index 0000000..7b9ec60
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Spielfeld.java
@@ -0,0 +1,198 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4import java.util.Collections;
5
6/**
7 * Model
8 *
9 * Created by jost on 24.11.15.
10 */
11public class Spielfeld {
12
13 private final Zelle[][] feld;
14 private final int max_x; //Breite
15 private final int max_y; //Höhe
16
17 public Spielfeld(int breite, int höhe) {
18 this.max_x = breite;
19 this.max_y = höhe;
20 feld = new Zelle[this.max_x][this.max_y];
21 for (int x=0;x<max_x;x++) {
22 for (int y = 0; y < max_y; y++) {
23 final Position p = new Position(x, y);
24 feld[x][y] = new Zelle(p, Zelle.TOT);
25 }
26 }
27 }
28
29 /**
30 * Liefert Zelle des Spielfelds an einer Position.
31 * @param p Position, der Zelle ausgelesen werden soll
32 * @return Zelle des Spielfelds an dieser Position, falls vorhanden; sonst null.
33 */
34 public Zelle getZelle(Position p) {
35 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
36 return feld[p.getX()][p.getY()];
37 } else {
38 return null;
39 }
40 }
41
42 /**
43 * Setzt eine gegebene Zelle ins Spielfeld ein.
44 * Überschreibt vorherige Zelle.
45 *
46 * @param zelle Einzusetzende Zelle
47 * @return Ob die Position der Zelle im Spielfeld enthalten ist (false bedeutuet ungültig).
48 */
49 public boolean setZelle(Zelle zelle) {
50 final Position p = zelle.getPosition();
51 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
52 feld[p.getX()][p.getY()] = zelle;
53 return true;
54 } else {
55 return false;
56 }
57 }
58
59 /**
60 * Liefert das gesamte Spielfeld direkt aus;
61 * nicht so schöne, da interne Repräsentierung offenbart wird
62 * und das Array von aussen verändert werden kann! Autsch!
63 *
64 * @return Alle Zellen des Felds im 2D array
65 */
66 public Zelle[][] getFeld() {
67 return feld;
68 }
69
70 /**
71 * BESSERE ALTERNATIVE zu getter-Methode getFeld():
72 * Liefert alle Zellen des Spielfeldes aus. Vorteile:
73 * 1) Interne Repräsentation bleibt versteckt.
74 * 2) Da die Zellen immutable sind, kann hier das
75 * Spielfeld auch nicht woanders manipuliert werden.
76 *
77 * @return Alle Zellen des Spielfeldes als ArrayList
78 */
79 public ArrayList<Zelle> getZellen() {
80 ArrayList<Zelle> result = new ArrayList<>(max_x*max_y);
81 for (int x=0;x<max_x;x++) {
82 for (int y = 0; y < max_y; y++) {
83 result.add(feld[x][y]);
84 }
85 }
86
87 return result;
88 }
89
90 /**
91 * Genau wie getZellen, nur mit echtem Array anstatt ArrayList.
92 * Vorteile bleiben erhalten!
93 *
94 * @return Alle Zellen des Spielfeldes als Array
95 */
96 public Zelle[] getZellenAry() {
97 Zelle[] result = new Zelle[max_x*max_y];
98 int i = 0;
99 for (int x=0;x<max_x;x++) {
100 for (int y = 0; y < max_y; y++) {
101 result[i] = feld[x][y];
102 i++;
103 }
104 }
105 return result;
106 }
107
108 /**
109 * Berechnet alle Nachbarn einer Zelle.
110 *
111 * @param zelle deren Nachbarn berechnet werden sollen
112 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
113 */
114 public ArrayList<Zelle> getNachbarn(Zelle zelle) {
115 ArrayList<Zelle> result = new ArrayList<>();
116 Position pos = zelle.getPosition();
117 for (int x=-1; x<=1; x++) {
118 for (int y = -1; y <= 1; y++) {
119 if (x!=0 || y!=0) {
120 Zelle nachbar = this.getZelle(new Position(pos.getX() + x, pos.getY() + y));
121 if (nachbar != null) {
122 result.add(nachbar);
123 }
124 }
125 }
126 }
127 return result;
128 }
129
130 /**
131 * Berechnet alle Nachbarn einer Zelle.
132 * Variante von getNachbar mit Array anstatt ArrayList
133 *
134 * @param zelle deren Nachbarn berechnet werden sollen
135 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
136 */
137 public Zelle[] getNachbarnAry(Zelle zelle) {
138 Position pos = zelle.getPosition();
139 int minx = Math.max(pos.getX() - 1, 0);
140 int maxx = Math.min(pos.getX() + 1, this.max_x);
141 int miny = Math.max(pos.getY() - 1, 0);
142 int maxy = Math.min(pos.getY() + 1, this.max_y);
143 Zelle[] result = new Zelle[maxx - minx * maxy - miny];
144 int i = 0;
145 for (int x = minx; x <= maxx; x++) {
146 for (int y = miny; y <= maxy; y++) {
147 if (x!=0 || y!=0) {
148 result[i] = feld[x][y];
149 i++;
150 }
151 }
152 }
153 return result;
154 }
155
156 /**
157 * Berechnet alle Nachbarn einer Zelle auf Wrap-Around Spielfeld..
158 *
159 * @param zelle deren Nachbarn berechnet werden sollen
160 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
161 */
162 public ArrayList<Zelle> getNachbarnWrapped(Zelle zelle) {
163 ArrayList<Zelle> result = new ArrayList<Zelle>(8);
164 Position pos = zelle.getPosition();
165 for (int x = -1; x <= 1; x++) {
166 for (int y = -1; y <= 1; y++) {
167 if (x!=0 || y!=0) {
168 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
169 result.add(z);
170 }
171 }
172 }
173 return result;
174 }
175
176 /**
177 * Berechnet alle Nachbarn einer Zelle auf Warap-Around Spielfeld.
178 * Variante von getNachbarWrapped mit Array anstatt ArrayList
179 *
180 * @param zelle deren Nachbarn berechnet werden sollen
181 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
182 */
183 public Zelle[] getNachbarnAryWrapped(Zelle zelle) {
184 Zelle[] result = new Zelle[8];
185 Position pos = zelle.getPosition();
186 int i = 0;
187 for (int x = -1; x <= 1; x++) {
188 for (int y = -1; y <= 1; y++) {
189 if (x!=0 || y!=0) {
190 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
191 result[i] = z;
192 i++;
193 }
194 }
195 }
196 return result;
197 }
198}
diff --git a/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Zelle.java b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Zelle.java
new file mode 100644
index 0000000..a7c6ad6
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1B/de/lmu/tcs/Zelle.java
@@ -0,0 +1,47 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Zelle {
11
12 public final static int TOT=0;
13 public final static int LEBENDIG=1;
14
15 private final Position position;
16 private final int zustand;
17
18 public Zelle(Position position, int zustand) {
19 this.position = position;
20 this.zustand = zustand;
21 }
22
23 public Zelle(Zelle old) {
24 this.position = old.position;
25 this.zustand = old.zustand;
26 }
27
28 public Position getPosition() {
29 return position;
30 }
31
32 public boolean istLebendig() {
33 return zustand>=LEBENDIG;
34 }
35
36 public boolean istTot() {
37 return zustand==TOT;
38 }
39
40 public Zelle nachkommen() {
41 return this.istTot() ? (new Zelle(this)) : (new Zelle(position, zustand + 1));
42 }
43
44 public int alter() {
45 return this.istTot() ? -1 : (this.zustand - 1);
46 }
47}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Ansicht.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Ansicht.java
new file mode 100644
index 0000000..c59cd31
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Ansicht.java
@@ -0,0 +1,99 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * View
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Ansicht {
11
12 private final GraphicsWindow fenster;
13 private final int max_x; //Breite
14 private final int max_y; //Höhe
15 private final int skalierung;
16
17
18 public Ansicht(int x, int y, int skalierung) {
19 this.max_x = x;
20 this.max_y = y;
21 this.skalierung = skalierung;
22 Point furthestCenter = centerByIndex(x, y);
23 this.fenster = new GraphicsWindow(
24 (int) (furthestCenter.getX() + Math.sqrt(3) * 1/2 * (double) skalierung + (double) (y % 2) * Math.sqrt(3) * 1/2 * (double) skalierung)
25 , (int) (furthestCenter.getY() + (double) skalierung / 2)
26 );
27 }
28
29 public void zeichneZelle(Zelle zelle) {
30 Position pos = zelle.getPosition();
31 // Rectangle box = new Rectangle(pos.getX() * skalierung, pos.getY() * skalierung, skalierung - 1, skalierung - 1);
32 Polygon box = new Hexagon(centerByIndex(pos.getX(), pos.getY()), skalierung).asPolygon();
33 fenster.setColor(Color.GRAY);
34 fenster.draw(box);
35 if (zelle.istTot()) {
36 fenster.setColor(Param.ZELLENFARBE[0]);
37 } else {
38 fenster.setColor(Param.ZELLENFARBE[Math.min(zelle.alter() + 1, Param.ZELLENFARBE.length - 1)]);
39 }
40 fenster.fill(box);
41 }
42
43 public void zeichneSpielfeld(Zelle[][] feld) {
44 fenster.clear();
45
46// for (int x = 0; x < max_x; x++) {
47// for (int y = 0; y < max_y; y++) {
48// zeichenZelle(feld[x][y]);
49// }
50// Äquivalente Alternative ohne explizite Indizes:
51 for (Zelle[] zeile : feld) {
52 for (Zelle zelle : zeile) {
53 if (zelle != null)
54 zeichneZelle(zelle);
55 }
56 }
57 }
58
59 public Position getClick() {
60 Point point = fenster.mouseClick();
61 Point firstCenter = centerByIndex(0,0);
62 Position testStart = new Position(
63 (point.x - firstCenter.x) / ((int) (Math.sqrt(3) * (double) skalierung))
64 , (point.y - firstCenter.y) / ((int) (1.5 * (double) skalierung))
65 ); // bad guess -- P.S.: actually, now it's a pretty good guess
66 for (int d = 0; d < Math.max(max_x, max_y); d++) // and starting there we test everything (also, another extremely bad guess)
67 for (int dx = -d; dx <= d; dx++)
68 for (int dy = -d; dy <= d; dy++)
69 {
70 if (Math.abs(dx) < d && Math.abs(dy) < d)
71 continue;
72 int x = testStart.getX() + dx;
73 int y = testStart.getY() + dy;
74 // zeichneZelle(new Zelle(new Position(x, y), Zelle.LEBENDIG));
75 // try {Thread.sleep(100);} catch (Exception e){}
76 Hexagon test = new Hexagon(centerByIndex(x, y), skalierung);
77 if (test.contains(point))
78 return new Position(x, y);
79 }
80
81 return new Position(-1, -1);
82 }
83
84 public void sleep(long delay) {
85 fenster.sleep(delay);
86 }
87
88 public void setText(String message) {
89 fenster.setText(message);
90 }
91
92 public Point centerByIndex(int x, int y)
93 {
94 return new Point(
95 (int) (Math.sqrt(3) * ((double) skalierung) * (((double) x) + 1 + ((double) (y % 2)) / 2))
96 , (int) (((double) skalierung) * (1 + 1.5 * ((double) y)))
97 );
98 }
99}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/GraphicsWindow.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/GraphicsWindow.java
new file mode 100644
index 0000000..a1f90bf
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/GraphicsWindow.java
@@ -0,0 +1,393 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4import java.util.ArrayList;
5import javax.swing.JFrame;
6import javax.swing.JPanel;
7import javax.swing.Timer;
8
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.awt.event.MouseEvent;
15import java.awt.geom.RectangularShape;
16import java.awt.geom.GeneralPath;
17
18/**
19 Eine Klasse zu pädagogischen Zwecken.
20 Erlaubt die Eingabe von Punktkoordinaten
21 mittels Mausklicks, das Zeichnen einfacher
22 2D Objekte (java.awt.Shape), sowie die
23 Ausgabe von Texten in einer Statuszeile.
24 @version 3.043
25 @author Martin Hofmann und die EiP-Teams verschiedener Jahre
26 */
27
28public class GraphicsWindow {
29
30 private int width;
31 private int height;
32 private JFrame dasFenster;
33 private static int fensterZahl;
34 private static int fensterNr;
35 private Label label;
36 private GraphicsWindowPanel panel;
37 private Point mousePos;
38 private Color activeColor = Color.BLACK;
39 final private Color backColor = Color.WHITE;
40 MyMouseAdapter mouseListener;
41
42 /**
43 Erzeugt ein Fenster der Größe 640 auf 480 mit Textausgabe, Mauseingabe und Grafikausgabe.
44 */
45 public GraphicsWindow() {
46 this(640, 480);
47 }
48
49 /**
50 Erzeugt ein Fenster in vorgegebener Größe mit Textausgabe, Mauseingabe und Grafikausgabe.
51 @param width Breite des Fensters
52 @param height Höhe des Fensters
53 */
54 public GraphicsWindow(int width, int height) {
55 this.width = width;
56 this.height = height;
57 dasFenster = new JFrame();
58 dasFenster.setTitle("Grafikfenster " + ++fensterNr);
59 fensterZahl++;
60 dasFenster.setLocationByPlatform(true);
61 dasFenster.setSize(width,height+50);
62 dasFenster.getContentPane().setPreferredSize(new Dimension(width, height+50));
63 dasFenster.pack();
64 dasFenster.addWindowListener(new WindowAdapter(){
65 public void windowClosing(WindowEvent e) {
66 dasFenster.dispose(); // nicht gleich alle Fenster abschiessen
67 if (--fensterZahl<1) System.exit(0);
68 }
69 });
70
71 label = new Label("Statuszeile...");
72 label.setFont(new Font("Helvetica", Font.PLAIN, 12));
73 dasFenster.getContentPane().add(label,"North" );
74 panel = new GraphicsWindowPanel();
75 //panel.setBackground(Color.cyan);
76 panel.addCommand(new SetColor(activeColor));
77 dasFenster.getContentPane().add(panel,"Center");
78 mousePos = new Point();
79 mouseListener = new MyMouseAdapter();
80 panel.addMouseListener(mouseListener);
81 clear();
82 dasFenster.setVisible(true);
83 }
84
85 /**
86 Gibt eine Zeichenkette oben im Fenster aus.
87 @param text diese Zeichenkette
88 */
89 public void setText(String text) {
90 label.setText(text);
91 }
92 /**
93 Liest den oben im Fenster angezeigten Text aus.
94 @return den Text
95 */
96 public String getText() {
97 return label.getText();
98 }
99 /**
100 Wartet auf einen Mausklick. Die Methode blockiert das
101 aufrufende Programm solange bis der Mausklick erfolgt ist.
102 @return die Koordinaten des angeklickten Punkts
103 */
104
105 public Point mouseClick() {
106 try{
107 synchronized(mouseListener){mouseListener.wait();}
108 }
109 catch(InterruptedException e){
110 e.printStackTrace();
111 }
112 return mousePos;
113 }
114
115 class MyMouseAdapter extends MouseAdapter {
116
117 /**
118 Beendet das Warten auf den Mausklick und verwertet die Koordinaten.
119 Diese Methode ist nicht für den Anwender bestimmt.
120 */
121
122 synchronized public void mouseClicked(MouseEvent e){
123 mousePos = e.getPoint();
124 notifyAll();
125 }
126 }
127
128
129 /**
130 Schaltet die Zeichenfarbe auf die Hintergrundfarbe um. Dies ist
131 das Mittel, um gezeichnete Linien wieder zu löschen.
132 */
133 public void switchToBackgroundColor(){
134 activeColor = backColor;
135 panel.addCommand(new SwitchToBackgroundColor(activeColor));
136 panel.repaint();
137 }
138
139 /**
140 Schaltet die Zeichenfarbe auf Schwarz um.
141 */
142 public void switchToForegroundColor(){
143 activeColor = Color.BLACK;
144 panel.addCommand(new SetColor(activeColor));
145 panel.repaint();
146 }
147
148
149 /** Liefert die aktuelle Zeichenfarbe.
150 @return die aktuelle Zeichenfarbe des GraphicsWindow. */
151 public Color getColor() {
152 // return panel.getGraphics().getColor(); // getGraphics() has unpleasant side-effects. :(
153 /* Fixed by adding another instance variable activeColor for now. */
154 return activeColor;
155 }
156
157 /**
158 Zeichnet eine Linie in der aktuellen Zeichenfarbe.
159 @param x Anfangspunkt
160 @param y Endpunkt
161 */
162 public void drawLine(Point x, Point y){
163 // Odering points reduces the amount of graphical artifacts in rendering the same object in different ways
164 Point x1 = x;
165 Point y1 = y;
166 if ((x.x > y.x) || ((x.x == y.x) && (x.y > y.y))) {
167 x1 = y;
168 y1 = x;
169 }
170 panel.addCommand(new DrawLine(x1,y1));
171 panel.repaint();
172 }
173
174 /**
175 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
176 @param p Punkt
177 */
178 public void drawPoint(Point p){
179 drawLine(p, p);
180 }
181
182 /**
183 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
184 @param p Punkt
185 */
186 public void drawStringAt(String s, Point p){
187 Command c = new DrawString(s,p);
188 panel.addCommand(c);
189 panel.repaint();
190 }
191
192 /**
193 Zeichnet ein geometrisches Objekt.
194 */
195 public void draw(Shape s) {
196 panel.addCommand(new Draw(s));
197 panel.repaint();
198 }
199
200 /**
201 Füllt ein geometrisches Objekt aus.
202 */
203 public void fill(Shape s) {
204 panel.addCommand(new Fill(s));
205 panel.repaint();
206 }
207
208 /** Das aufrufende Programm wird für ein gegebene Zeitspanne blockiert.
209 @param millis Die Zeitspanne in Millisekunden*/
210 public void sleep(long millis) {
211 try {Thread.sleep(millis);} catch (Exception e){}
212 }
213
214 /** Setzt die Zeichenfarbe. */
215 public void setColor(Color d) {
216 activeColor = d;
217 panel.addCommand(new SetColor(activeColor));
218 panel.repaint();
219 }
220
221 /**
222 Setzt die Zeichenfarbe auf einen Grauwert
223 @param shade Grauwert zwischen 0(schwarz) und 255(weiß)
224 */
225 public void setGrayColor(int shade) {
226 setColor(new Color(shade, shade, shade));
227 }
228
229 /**
230 Setzt die Zeichenfarbe für die Mandelbrot-Aufgabe
231 @param n Anzahl der Iterationen, die durch die Farbe symboliziert werdem soll
232 */
233 public void setMandelColor(int n) {
234 float r = (float) Math.min(1.0,((double) n / 9.0) );
235 float g = (float) Math.min(1.0,((double) n / 99.0) );
236 float b = (float) Math.min(1.0,((double) n / 999.0) );
237 setColor(new Color(r, g, b));
238 }
239
240 /** Löscht das Bild */
241 public void clear() {
242// Color oldActive = activeColor;
243 panel.clearAll();
244// this.switchToBackgroundColor();
245// fill(new Rectangle(0,0,width,height));
246// setColor(oldActive);
247 }
248
249 public void killIn(int secs) {
250 Timer t = new Timer(1000*secs, new ActionListener(){
251 @Override
252 public void actionPerformed(ActionEvent e) {dasFenster.dispose();}
253 }
254 );
255 t.setRepeats(false);
256 t.start();
257 }
258}
259
260
261class GraphicsWindowPanel extends JPanel
262{
263 private static final long serialVersionUID = 1L;
264 private ArrayList<Command> cl = new ArrayList<Command>();
265
266 public void paintComponent(Graphics g)
267 {
268 super.paintComponent(g);
269 Graphics2D g2D = (Graphics2D)g;
270
271 ArrayList<Command> cl = this.cl; // Kopie wegen Nebenläufigkeit von Swing
272 int size = cl.size();
273 for (int i=0; i<size; i++) {
274 Command c = cl.get(i);
275 if (c != null) c.execute(g2D);
276 }
277 }
278
279 void addCommand(Command c)
280 {
281 cl.add(c);
282 }
283
284 void clearAll()
285 {
286// try {
287// SwingUtilities.invokeAndWait(new Runnable() {
288// @Override
289// public void run() {
290 cl = new ArrayList<Command>();
291// }
292// });
293// } catch (InterruptedException e) {
294// // TODO Auto-generated catch block
295// e.printStackTrace();
296// } catch (InvocationTargetException e) {
297// // TODO Auto-generated catch block
298// e.printStackTrace();
299// }
300 }
301}
302
303
304abstract class Command //implements Serializable
305{
306 abstract void execute(Graphics2D g2D);
307
308 /** Clone a shape. This method is needed because Shape
309 * does not define clone(), although many shape classes do.
310 * Kopiert aus jsky-2.6 auf ftp.eso.org */
311 static Shape cloneShape(Shape s) {
312 // FIXME Add more specific shapes
313 if (s instanceof RectangularShape) {
314 return (RectangularShape) ((RectangularShape) s).clone();
315 } else {
316 return new GeneralPath(s);
317 }
318 }
319
320}
321
322class DrawLine extends Command {
323 Point von;
324 Point bis;
325 DrawLine(Point von, Point bis) {
326 /* Clonen der Punkte essentiell um Aliasingeffekte beim Redraw zu verhindern */
327 this.von = new Point(von);
328 this.bis = new Point(bis);
329 }
330 void execute(Graphics2D g2D)
331 {
332 g2D.drawLine(this.von.x,this.von.y,this.bis.x,this.bis.y);
333 }
334}
335
336class SwitchToForegroundColor extends Command {
337 SwitchToForegroundColor() {}
338 void execute(Graphics2D g2D) {
339 g2D.setColor(Color.black);
340 }
341}
342
343class SwitchToBackgroundColor extends Command {
344 Color backcolor;
345 SwitchToBackgroundColor(Color backcolor) {this.backcolor = backcolor;}
346 void execute(Graphics2D g2D) {
347 g2D.setColor(backcolor);
348 }
349}
350
351class SetColor extends Command {
352 Color color;
353 SetColor(Color color) {this.color = color;}
354 void execute(Graphics2D g2D) {
355 g2D.setColor(this.color);
356 }
357}
358
359
360class Draw extends Command {
361 Shape shape;
362 Draw(Shape shape) {this.shape = cloneShape(shape);}
363 void execute(Graphics2D g2D) {
364 g2D.draw(this.shape);
365 }
366}
367
368class Fill extends Command {
369 Shape shape;
370 Fill(Shape shape) {this.shape = cloneShape(shape);}
371 void execute(Graphics2D g2D) {
372 g2D.fill(this.shape);
373 }
374}
375
376class DrawString extends Command {
377 String string;
378 Point position;
379 DrawString(String string, Point position) {this.string = string; this.position = position;}
380 @Override
381 void execute(Graphics2D g2D) {
382 g2D.drawString(string, position.x, position.y);
383 }
384}
385
386
387
388
389
390
391
392
393
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Hexagon.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Hexagon.java
new file mode 100644
index 0000000..12f1031
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Hexagon.java
@@ -0,0 +1,76 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5class Hexagon {
6 private final Point center;
7 private final int sideLength;
8
9 public Hexagon(Point center2, int sideLength2)
10 {
11 this.center = center2;
12 this.sideLength = sideLength2;
13 }
14
15 public Point[] vertices()
16 {
17 Point vertex = new Point((int) (Math.sqrt(3) * ((double) sideLength) / 2), sideLength / 2);
18 Point[] relative = { new Point(0, sideLength)
19 , vertex
20 , mirrory(vertex)
21 , new Point(0, -1 * sideLength)
22 , mirrorx(mirrory(vertex))
23 , mirrorx(vertex)
24 };
25
26 for (Point r : relative)
27 r.translate(center.x, center.y);
28
29 return relative;
30 }
31
32 private static Point mirrorx(Point r)
33 {
34 return new Point(r.x * -1, r.y);
35 }
36
37 private static Point mirrory(Point r)
38 {
39 return new Point(r.x, r.y * -1);
40 }
41
42 public int height()
43 {
44 return 2 * sideLength;
45 }
46
47 public int width()
48 {
49 return (int) (Math.sqrt(3) * (double) sideLength);
50 }
51
52 public boolean contains(Point r)
53 { // clever maths is clever (and very hexagon-specific)
54 int rx = Math.abs(r.x - center.x);
55 int ry = Math.abs(r.y - center.y);
56
57 if (rx > width() / 2 || ry > height())
58 return false;
59 return width() * height() - height() * rx - height() * ry >= 0;
60 }
61
62 public Rectangle boundingBox()
63 {
64 Point uL = new Point(center);
65 uL.translate(-1 * width() / 2, -1 * height() / 2);
66 return new Rectangle(uL, new Dimension(width(), height()));
67 }
68
69 public Polygon asPolygon()
70 {
71 Polygon ret = new Polygon();
72 for (Point r : vertices())
73 ret.addPoint(r.x, r.y);
74 return ret;
75 }
76}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Main.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Main.java
new file mode 100644
index 0000000..4177aca
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Main.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3
4/**
5 * Game of Life nach der Idee von John Horton Conway
6 *
7 * Fallstudie für Objektorientiertes Design nach MVC Entwurfswuster
8 * im Rahmen der
9 * "Einführung in die Programmierung" WS2015/16
10 *
11 * Lehrstuhl für Theoretische Informatik
12 * LMU München
13 *
14 * Prof Martin Hofmann, Dr Steffen Jost
15 *
16 * Created by jost on 24.11.15.
17 */
18public class Main {
19
20 public static void main(String[] args) {
21 Spieler spieler = new Spieler();
22 spieler.spielDurchführen();
23 System.exit(0);
24 }
25}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Param.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Param.java
new file mode 100644
index 0000000..9907909
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Param.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * Sammlung aller extern festgelegten Konstanten
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Param {
11
12 // Konstanten für das Spiel
13 public static final int SPIEL_HÖHE = 50;
14 public static final int SPIEL_BREITE = 80;
15
16 // Konstanten für die View
17 // public static final Color FARBE_LEBENDIG = Color.RED;
18 // public static final Color FARBE_TOT = Color.WHITE;
19 public static final Color[] ZELLENFARBE = new Color[] {Color.WHITE, Color.RED, Color.ORANGE, Color.MAGENTA, Color.GREEN, Color.CYAN, Color.BLUE};
20 public static final int SKALIERUNG = 10;
21
22 // Konstanten für Durchführung
23 public static final long RUNDENZEIT = 1000; // 120;
24 public static final int RUNDENZAHL = 1000;
25}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Position.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Position.java
new file mode 100644
index 0000000..9c98b77
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Position.java
@@ -0,0 +1,31 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Position {
11
12 private final int x;
13 private final int y;
14
15 public Position(int x, int y) {
16 this.x = x;
17 this.y = y;
18 }
19
20 public int getX() {
21 return this.x;
22 }
23
24 public int getY() {
25 return this.y;
26 }
27
28 public Position add(Position r) {
29 return new Position(this.x + r.x, this.y + r.y);
30 }
31}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spieler.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spieler.java
new file mode 100644
index 0000000..a33a7db
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spieler.java
@@ -0,0 +1,81 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4
5/**
6 * Controller
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Spieler {
11
12 private final Spielfeld spiel;
13 private final Ansicht ansicht;
14
15 public Spieler() {
16 this.spiel = new Spielfeld(Param.SPIEL_BREITE,Param.SPIEL_HÖHE);
17 this.ansicht = new Ansicht( Param.SPIEL_BREITE,Param.SPIEL_HÖHE,Param.SKALIERUNG);
18 ansicht.zeichneSpielfeld(spiel.getFeld());
19 ansicht.setText("Außerhalb Spielfeld klicken zum Beenden");
20
21 // Benutzer setzt Anfangspostionen
22 boolean nichtzuende = true;
23 do {
24 Position p = ansicht.getClick();
25 Zelle zelle = new Zelle(p, Zelle.LEBENDIG);
26 nichtzuende = spiel.setZelle(zelle);
27 if (nichtzuende) {
28 ansicht.zeichneZelle(zelle);
29 }
30 } while (nichtzuende);
31 }
32
33 public void spielDurchführen() {
34 for (int runde=0; runde < Param.RUNDENZAHL; runde++){
35 this.rundeDurchführen();
36 ansicht.setText("Runde "+runde);
37 ansicht.sleep(Param.RUNDENZEIT);
38 }
39 }
40
41
42 public void rundeDurchführen() {
43 ArrayList<Zelle> änderungen = new ArrayList<Zelle>();
44 // Änderungen anhand altem Zustand feststellen
45 for (Zelle zelle : spiel.getZellen()) {
46 if (zelle == null)
47 continue;
48 ArrayList<Zelle> nachbarn = spiel.getNachbarn(zelle);
49 // Zelle[] nachbarn = spiel.getNachbarnAryWrapped(zelle);
50 int lebendigeNachbarn = 0;
51 for (Zelle nachbar : nachbarn) {
52 if (nachbar.istLebendig()) lebendigeNachbarn++;
53 }
54 // if (zelle.istLebendig()) {
55 // if (lebendigeNachbarn <= 1 || lebendigeNachbarn >=4) {
56 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.TOT);
57 // änderungen.add(neu);
58 // }
59 // } else { // eventuell zu einem if umbauen, welches Zustand ins Gegenteil verkehrt
60 // if (lebendigeNachbarn == 3) {
61 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
62 // änderungen.add(neu);
63 // }
64 // }
65 Zelle neu;
66 if (zelle.istLebendig() && lebendigeNachbarn % 2 == 0)
67 neu = new Zelle(zelle.getPosition(),Zelle.TOT);
68 else if (! zelle.istLebendig() && lebendigeNachbarn % 2 == 1)
69 neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
70 else
71 neu = zelle.nachkommen();
72 änderungen.add(neu);
73 }
74 // Erkannte Änderungen nun einpflegen
75 for (Zelle zelle : änderungen) {
76 spiel.setZelle(zelle);
77 ansicht.zeichneZelle(zelle);
78 }
79 }
80
81}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spielfeld.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spielfeld.java
new file mode 100644
index 0000000..1044c1e
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Spielfeld.java
@@ -0,0 +1,205 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4import java.util.Collections;
5
6/**
7 * Model
8 *
9 * Created by jost on 24.11.15.
10 */
11public class Spielfeld {
12
13 private final Zelle[][] feld;
14 private final int max_x; //Breite
15 private final int max_y; //Höhe
16
17 public Spielfeld(int breite, int höhe) {
18 this.max_x = breite;
19 this.max_y = höhe;
20 feld = new Zelle[this.max_x][this.max_y];
21 for (int y = 0; y < max_y; y++) {
22 for (int x=0;x<max_x - (y % 2);x++) {
23 final Position p = new Position(x, y);
24 feld[x][y] = new Zelle(p, Zelle.TOT);
25 }
26 }
27 }
28
29 private boolean isValid(int x, int y)
30 {
31 return x >= 0 && x < max_x && y >= 0 && y < max_y;
32 }
33
34 /**
35 * Liefert Zelle des Spielfelds an einer Position.
36 * @param p Position, der Zelle ausgelesen werden soll
37 * @return Zelle des Spielfelds an dieser Position, falls vorhanden; sonst null.
38 */
39 public Zelle getZelle(Position p) {
40 if (isValid(p.getX(), p.getY())) {
41 return feld[p.getX()][p.getY()];
42 } else {
43 return null;
44 }
45 }
46
47 /**
48 * Setzt eine gegebene Zelle ins Spielfeld ein.
49 * Überschreibt vorherige Zelle.
50 *
51 * @param zelle Einzusetzende Zelle
52 * @return Ob die Position der Zelle im Spielfeld enthalten ist (false bedeutuet ungültig).
53 */
54 public boolean setZelle(Zelle zelle) {
55 final Position p = zelle.getPosition();
56 if (isValid(p.getX(), p.getY())) {
57 feld[p.getX()][p.getY()] = zelle;
58 return true;
59 } else {
60 return false;
61 }
62 }
63
64 /**
65 * Liefert das gesamte Spielfeld direkt aus;
66 * nicht so schöne, da interne Repräsentierung offenbart wird
67 * und das Array von aussen verändert werden kann! Autsch!
68 *
69 * @return Alle Zellen des Felds im 2D array
70 */
71 public Zelle[][] getFeld() {
72 return feld;
73 }
74
75 /**
76 * BESSERE ALTERNATIVE zu getter-Methode getFeld():
77 * Liefert alle Zellen des Spielfeldes aus. Vorteile:
78 * 1) Interne Repräsentation bleibt versteckt.
79 * 2) Da die Zellen immutable sind, kann hier das
80 * Spielfeld auch nicht woanders manipuliert werden.
81 *
82 * @return Alle Zellen des Spielfeldes als ArrayList
83 */
84 public ArrayList<Zelle> getZellen() {
85 ArrayList<Zelle> result = new ArrayList<>(max_x*max_y);
86 for (int x=0;x<max_x;x++) {
87 for (int y = 0; y < max_y; y++) {
88 result.add(feld[x][y]);
89 }
90 }
91
92 return result;
93 }
94
95 /**
96 * Genau wie getZellen, nur mit echtem Array anstatt ArrayList.
97 * Vorteile bleiben erhalten!
98 *
99 * @return Alle Zellen des Spielfeldes als Array
100 */
101 public Zelle[] getZellenAry() {
102 Zelle[] result = new Zelle[max_x*max_y];
103 int i = 0;
104 for (int x=0;x<max_x;x++) {
105 for (int y = 0; y < max_y; y++) {
106 result[i] = feld[x][y];
107 i++;
108 }
109 }
110 return result;
111 }
112
113 /**
114 * Berechnet alle Nachbarn einer Zelle.
115 *
116 * @param zelle deren Nachbarn berechnet werden sollen
117 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
118 */
119 public ArrayList<Zelle> getNachbarn(Zelle zelle) {
120 ArrayList<Zelle> result = new ArrayList<>();
121 if (zelle == null)
122 return result;
123 Position pos = zelle.getPosition();
124 Position[] offsets = { new Position(0, -1), new Position(1, -1)
125 , new Position(-1, 0), new Position(1, 0)
126 , new Position(0, 1), new Position (1, 1)
127 };
128 for (Position offset : offsets) {
129 Zelle nachbar = this.getZelle(pos.add(offset));
130 if (nachbar != null) {
131 result.add(nachbar);
132 }
133 }
134 return result;
135 }
136
137 // /**
138 // * Berechnet alle Nachbarn einer Zelle.
139 // * Variante von getNachbar mit Array anstatt ArrayList
140 // *
141 // * @param zelle deren Nachbarn berechnet werden sollen
142 // * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
143 // */
144 // public Zelle[] getNachbarnAry(Zelle zelle) {
145 // Position pos = zelle.getPosition();
146 // int minx = Math.max(pos.getX() - 1, 0);
147 // int maxx = Math.min(pos.getX() + 1, this.max_x);
148 // int miny = Math.max(pos.getY() - 1, 0);
149 // int maxy = Math.min(pos.getY() + 1, this.max_y);
150 // Zelle[] result = new Zelle[maxx - minx * maxy - miny];
151 // int i = 0;
152 // for (int x = minx; x <= maxx; x++) {
153 // for (int y = miny; y <= maxy; y++) {
154 // if (x!=0 || y!=0) {
155 // result[i] = feld[x][y];
156 // i++;
157 // }
158 // }
159 // }
160 // return result;
161 // }
162
163 /**
164 * Berechnet alle Nachbarn einer Zelle auf Wrap-Around Spielfeld..
165 *
166 * @param zelle deren Nachbarn berechnet werden sollen
167 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
168 */
169 public ArrayList<Zelle> getNachbarnWrapped(Zelle zelle) {
170 ArrayList<Zelle> result = new ArrayList<Zelle>(8);
171 Position pos = zelle.getPosition();
172 for (int x = -1; x <= 1; x++) {
173 for (int y = -1; y <= 1; y++) {
174 if (x!=0 || y!=0) {
175 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
176 result.add(z);
177 }
178 }
179 }
180 return result;
181 }
182
183 /**
184 * Berechnet alle Nachbarn einer Zelle auf Warap-Around Spielfeld.
185 * Variante von getNachbarWrapped mit Array anstatt ArrayList
186 *
187 * @param zelle deren Nachbarn berechnet werden sollen
188 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
189 */
190 public Zelle[] getNachbarnAryWrapped(Zelle zelle) {
191 Zelle[] result = new Zelle[8];
192 Position pos = zelle.getPosition();
193 int i = 0;
194 for (int x = -1; x <= 1; x++) {
195 for (int y = -1; y <= 1; y++) {
196 if (x!=0 || y!=0) {
197 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
198 result[i] = z;
199 i++;
200 }
201 }
202 }
203 return result;
204 }
205}
diff --git a/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Zelle.java b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Zelle.java
new file mode 100644
index 0000000..a7c6ad6
--- /dev/null
+++ b/ws2015/eip/blaetter/07/H7-1C/de/lmu/tcs/Zelle.java
@@ -0,0 +1,47 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Zelle {
11
12 public final static int TOT=0;
13 public final static int LEBENDIG=1;
14
15 private final Position position;
16 private final int zustand;
17
18 public Zelle(Position position, int zustand) {
19 this.position = position;
20 this.zustand = zustand;
21 }
22
23 public Zelle(Zelle old) {
24 this.position = old.position;
25 this.zustand = old.zustand;
26 }
27
28 public Position getPosition() {
29 return position;
30 }
31
32 public boolean istLebendig() {
33 return zustand>=LEBENDIG;
34 }
35
36 public boolean istTot() {
37 return zustand==TOT;
38 }
39
40 public Zelle nachkommen() {
41 return this.istTot() ? (new Zelle(this)) : (new Zelle(position, zustand + 1));
42 }
43
44 public int alter() {
45 return this.istTot() ? -1 : (this.zustand - 1);
46 }
47}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Ansicht.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Ansicht.java
new file mode 100644
index 0000000..49d3375
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Ansicht.java
@@ -0,0 +1,64 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * View
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Ansicht {
11
12 private final GraphicsWindow fenster;
13 private final int max_x; //Breite
14 private final int max_y; //Höhe
15 private final int skalierung;
16
17
18 public Ansicht(int x, int y, int skalierung) {
19 this.max_x = x;
20 this.max_y = y;
21 this.skalierung = skalierung;
22 this.fenster = new GraphicsWindow(max_x * skalierung, max_y * skalierung);
23 }
24
25 public void zeichenZelle(Zelle zelle) {
26 Position pos = zelle.getPosition();
27 Rectangle box = new Rectangle(pos.getX() * skalierung, pos.getY() * skalierung, skalierung - 1, skalierung - 1);
28 if (zelle.istTot()) {
29 fenster.setColor(Param.ZELLENFARBE[0]);
30 } else {
31 fenster.setColor(Param.ZELLENFARBE[Math.min(zelle.alter() + 1, Param.ZELLENFARBE.length - 1)]);
32 }
33 fenster.fill(box);
34 }
35
36 public void zeichneSpielfeld(Zelle[][] feld) {
37 fenster.clear();
38
39// for (int x = 0; x < max_x; x++) {
40// for (int y = 0; y < max_y; y++) {
41// zeichenZelle(feld[x][y]);
42// }
43// Äquivalente Alternative ohne explizite Indizes:
44 for (Zelle[] zeile : feld) {
45 for (Zelle zelle : zeile) {
46 zeichenZelle(zelle);
47 }
48 }
49 }
50
51 public Position getClick() {
52 Point point = fenster.mouseClick();
53 Position result = new Position(point.x / skalierung, point.y /skalierung);
54 return result;
55 }
56
57 public void sleep(long delay) {
58 fenster.sleep(delay);
59 }
60
61 public void setText(String message) {
62 fenster.setText(message);
63 }
64}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/GraphicsWindow.java b/ws2015/eip/blaetter/07/de/lmu/tcs/GraphicsWindow.java
new file mode 100644
index 0000000..a1f90bf
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/GraphicsWindow.java
@@ -0,0 +1,393 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4import java.util.ArrayList;
5import javax.swing.JFrame;
6import javax.swing.JPanel;
7import javax.swing.Timer;
8
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.awt.event.MouseEvent;
15import java.awt.geom.RectangularShape;
16import java.awt.geom.GeneralPath;
17
18/**
19 Eine Klasse zu pädagogischen Zwecken.
20 Erlaubt die Eingabe von Punktkoordinaten
21 mittels Mausklicks, das Zeichnen einfacher
22 2D Objekte (java.awt.Shape), sowie die
23 Ausgabe von Texten in einer Statuszeile.
24 @version 3.043
25 @author Martin Hofmann und die EiP-Teams verschiedener Jahre
26 */
27
28public class GraphicsWindow {
29
30 private int width;
31 private int height;
32 private JFrame dasFenster;
33 private static int fensterZahl;
34 private static int fensterNr;
35 private Label label;
36 private GraphicsWindowPanel panel;
37 private Point mousePos;
38 private Color activeColor = Color.BLACK;
39 final private Color backColor = Color.WHITE;
40 MyMouseAdapter mouseListener;
41
42 /**
43 Erzeugt ein Fenster der Größe 640 auf 480 mit Textausgabe, Mauseingabe und Grafikausgabe.
44 */
45 public GraphicsWindow() {
46 this(640, 480);
47 }
48
49 /**
50 Erzeugt ein Fenster in vorgegebener Größe mit Textausgabe, Mauseingabe und Grafikausgabe.
51 @param width Breite des Fensters
52 @param height Höhe des Fensters
53 */
54 public GraphicsWindow(int width, int height) {
55 this.width = width;
56 this.height = height;
57 dasFenster = new JFrame();
58 dasFenster.setTitle("Grafikfenster " + ++fensterNr);
59 fensterZahl++;
60 dasFenster.setLocationByPlatform(true);
61 dasFenster.setSize(width,height+50);
62 dasFenster.getContentPane().setPreferredSize(new Dimension(width, height+50));
63 dasFenster.pack();
64 dasFenster.addWindowListener(new WindowAdapter(){
65 public void windowClosing(WindowEvent e) {
66 dasFenster.dispose(); // nicht gleich alle Fenster abschiessen
67 if (--fensterZahl<1) System.exit(0);
68 }
69 });
70
71 label = new Label("Statuszeile...");
72 label.setFont(new Font("Helvetica", Font.PLAIN, 12));
73 dasFenster.getContentPane().add(label,"North" );
74 panel = new GraphicsWindowPanel();
75 //panel.setBackground(Color.cyan);
76 panel.addCommand(new SetColor(activeColor));
77 dasFenster.getContentPane().add(panel,"Center");
78 mousePos = new Point();
79 mouseListener = new MyMouseAdapter();
80 panel.addMouseListener(mouseListener);
81 clear();
82 dasFenster.setVisible(true);
83 }
84
85 /**
86 Gibt eine Zeichenkette oben im Fenster aus.
87 @param text diese Zeichenkette
88 */
89 public void setText(String text) {
90 label.setText(text);
91 }
92 /**
93 Liest den oben im Fenster angezeigten Text aus.
94 @return den Text
95 */
96 public String getText() {
97 return label.getText();
98 }
99 /**
100 Wartet auf einen Mausklick. Die Methode blockiert das
101 aufrufende Programm solange bis der Mausklick erfolgt ist.
102 @return die Koordinaten des angeklickten Punkts
103 */
104
105 public Point mouseClick() {
106 try{
107 synchronized(mouseListener){mouseListener.wait();}
108 }
109 catch(InterruptedException e){
110 e.printStackTrace();
111 }
112 return mousePos;
113 }
114
115 class MyMouseAdapter extends MouseAdapter {
116
117 /**
118 Beendet das Warten auf den Mausklick und verwertet die Koordinaten.
119 Diese Methode ist nicht für den Anwender bestimmt.
120 */
121
122 synchronized public void mouseClicked(MouseEvent e){
123 mousePos = e.getPoint();
124 notifyAll();
125 }
126 }
127
128
129 /**
130 Schaltet die Zeichenfarbe auf die Hintergrundfarbe um. Dies ist
131 das Mittel, um gezeichnete Linien wieder zu löschen.
132 */
133 public void switchToBackgroundColor(){
134 activeColor = backColor;
135 panel.addCommand(new SwitchToBackgroundColor(activeColor));
136 panel.repaint();
137 }
138
139 /**
140 Schaltet die Zeichenfarbe auf Schwarz um.
141 */
142 public void switchToForegroundColor(){
143 activeColor = Color.BLACK;
144 panel.addCommand(new SetColor(activeColor));
145 panel.repaint();
146 }
147
148
149 /** Liefert die aktuelle Zeichenfarbe.
150 @return die aktuelle Zeichenfarbe des GraphicsWindow. */
151 public Color getColor() {
152 // return panel.getGraphics().getColor(); // getGraphics() has unpleasant side-effects. :(
153 /* Fixed by adding another instance variable activeColor for now. */
154 return activeColor;
155 }
156
157 /**
158 Zeichnet eine Linie in der aktuellen Zeichenfarbe.
159 @param x Anfangspunkt
160 @param y Endpunkt
161 */
162 public void drawLine(Point x, Point y){
163 // Odering points reduces the amount of graphical artifacts in rendering the same object in different ways
164 Point x1 = x;
165 Point y1 = y;
166 if ((x.x > y.x) || ((x.x == y.x) && (x.y > y.y))) {
167 x1 = y;
168 y1 = x;
169 }
170 panel.addCommand(new DrawLine(x1,y1));
171 panel.repaint();
172 }
173
174 /**
175 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
176 @param p Punkt
177 */
178 public void drawPoint(Point p){
179 drawLine(p, p);
180 }
181
182 /**
183 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
184 @param p Punkt
185 */
186 public void drawStringAt(String s, Point p){
187 Command c = new DrawString(s,p);
188 panel.addCommand(c);
189 panel.repaint();
190 }
191
192 /**
193 Zeichnet ein geometrisches Objekt.
194 */
195 public void draw(Shape s) {
196 panel.addCommand(new Draw(s));
197 panel.repaint();
198 }
199
200 /**
201 Füllt ein geometrisches Objekt aus.
202 */
203 public void fill(Shape s) {
204 panel.addCommand(new Fill(s));
205 panel.repaint();
206 }
207
208 /** Das aufrufende Programm wird für ein gegebene Zeitspanne blockiert.
209 @param millis Die Zeitspanne in Millisekunden*/
210 public void sleep(long millis) {
211 try {Thread.sleep(millis);} catch (Exception e){}
212 }
213
214 /** Setzt die Zeichenfarbe. */
215 public void setColor(Color d) {
216 activeColor = d;
217 panel.addCommand(new SetColor(activeColor));
218 panel.repaint();
219 }
220
221 /**
222 Setzt die Zeichenfarbe auf einen Grauwert
223 @param shade Grauwert zwischen 0(schwarz) und 255(weiß)
224 */
225 public void setGrayColor(int shade) {
226 setColor(new Color(shade, shade, shade));
227 }
228
229 /**
230 Setzt die Zeichenfarbe für die Mandelbrot-Aufgabe
231 @param n Anzahl der Iterationen, die durch die Farbe symboliziert werdem soll
232 */
233 public void setMandelColor(int n) {
234 float r = (float) Math.min(1.0,((double) n / 9.0) );
235 float g = (float) Math.min(1.0,((double) n / 99.0) );
236 float b = (float) Math.min(1.0,((double) n / 999.0) );
237 setColor(new Color(r, g, b));
238 }
239
240 /** Löscht das Bild */
241 public void clear() {
242// Color oldActive = activeColor;
243 panel.clearAll();
244// this.switchToBackgroundColor();
245// fill(new Rectangle(0,0,width,height));
246// setColor(oldActive);
247 }
248
249 public void killIn(int secs) {
250 Timer t = new Timer(1000*secs, new ActionListener(){
251 @Override
252 public void actionPerformed(ActionEvent e) {dasFenster.dispose();}
253 }
254 );
255 t.setRepeats(false);
256 t.start();
257 }
258}
259
260
261class GraphicsWindowPanel extends JPanel
262{
263 private static final long serialVersionUID = 1L;
264 private ArrayList<Command> cl = new ArrayList<Command>();
265
266 public void paintComponent(Graphics g)
267 {
268 super.paintComponent(g);
269 Graphics2D g2D = (Graphics2D)g;
270
271 ArrayList<Command> cl = this.cl; // Kopie wegen Nebenläufigkeit von Swing
272 int size = cl.size();
273 for (int i=0; i<size; i++) {
274 Command c = cl.get(i);
275 if (c != null) c.execute(g2D);
276 }
277 }
278
279 void addCommand(Command c)
280 {
281 cl.add(c);
282 }
283
284 void clearAll()
285 {
286// try {
287// SwingUtilities.invokeAndWait(new Runnable() {
288// @Override
289// public void run() {
290 cl = new ArrayList<Command>();
291// }
292// });
293// } catch (InterruptedException e) {
294// // TODO Auto-generated catch block
295// e.printStackTrace();
296// } catch (InvocationTargetException e) {
297// // TODO Auto-generated catch block
298// e.printStackTrace();
299// }
300 }
301}
302
303
304abstract class Command //implements Serializable
305{
306 abstract void execute(Graphics2D g2D);
307
308 /** Clone a shape. This method is needed because Shape
309 * does not define clone(), although many shape classes do.
310 * Kopiert aus jsky-2.6 auf ftp.eso.org */
311 static Shape cloneShape(Shape s) {
312 // FIXME Add more specific shapes
313 if (s instanceof RectangularShape) {
314 return (RectangularShape) ((RectangularShape) s).clone();
315 } else {
316 return new GeneralPath(s);
317 }
318 }
319
320}
321
322class DrawLine extends Command {
323 Point von;
324 Point bis;
325 DrawLine(Point von, Point bis) {
326 /* Clonen der Punkte essentiell um Aliasingeffekte beim Redraw zu verhindern */
327 this.von = new Point(von);
328 this.bis = new Point(bis);
329 }
330 void execute(Graphics2D g2D)
331 {
332 g2D.drawLine(this.von.x,this.von.y,this.bis.x,this.bis.y);
333 }
334}
335
336class SwitchToForegroundColor extends Command {
337 SwitchToForegroundColor() {}
338 void execute(Graphics2D g2D) {
339 g2D.setColor(Color.black);
340 }
341}
342
343class SwitchToBackgroundColor extends Command {
344 Color backcolor;
345 SwitchToBackgroundColor(Color backcolor) {this.backcolor = backcolor;}
346 void execute(Graphics2D g2D) {
347 g2D.setColor(backcolor);
348 }
349}
350
351class SetColor extends Command {
352 Color color;
353 SetColor(Color color) {this.color = color;}
354 void execute(Graphics2D g2D) {
355 g2D.setColor(this.color);
356 }
357}
358
359
360class Draw extends Command {
361 Shape shape;
362 Draw(Shape shape) {this.shape = cloneShape(shape);}
363 void execute(Graphics2D g2D) {
364 g2D.draw(this.shape);
365 }
366}
367
368class Fill extends Command {
369 Shape shape;
370 Fill(Shape shape) {this.shape = cloneShape(shape);}
371 void execute(Graphics2D g2D) {
372 g2D.fill(this.shape);
373 }
374}
375
376class DrawString extends Command {
377 String string;
378 Point position;
379 DrawString(String string, Point position) {this.string = string; this.position = position;}
380 @Override
381 void execute(Graphics2D g2D) {
382 g2D.drawString(string, position.x, position.y);
383 }
384}
385
386
387
388
389
390
391
392
393
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Main.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Main.java
new file mode 100644
index 0000000..4177aca
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Main.java
@@ -0,0 +1,25 @@
1package de.lmu.tcs;
2
3
4/**
5 * Game of Life nach der Idee von John Horton Conway
6 *
7 * Fallstudie für Objektorientiertes Design nach MVC Entwurfswuster
8 * im Rahmen der
9 * "Einführung in die Programmierung" WS2015/16
10 *
11 * Lehrstuhl für Theoretische Informatik
12 * LMU München
13 *
14 * Prof Martin Hofmann, Dr Steffen Jost
15 *
16 * Created by jost on 24.11.15.
17 */
18public class Main {
19
20 public static void main(String[] args) {
21 Spieler spieler = new Spieler();
22 spieler.spielDurchführen();
23 System.exit(0);
24 }
25}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Param.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Param.java
new file mode 100644
index 0000000..88f8248
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Param.java
@@ -0,0 +1,26 @@
1package de.lmu.tcs;
2
3import java.awt.*;
4
5/**
6 * Sammlung aller extern festgelegten Konstanten
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Param {
11
12 // Konstanten für das Spiel
13 public static final int SPIEL_HÖHE = 50;
14 public static final int SPIEL_BREITE = 80;
15
16 // Konstanten für die View
17 // public static final Color FARBE_LEBENDIG = Color.RED;
18 // public static final Color FARBE_TOT = Color.WHITE;
19 public static final Color[] ZELLENFARBE = new Color[] {Color.WHITE, Color.RED, Color.ORANGE, Color.MAGENTA, Color.GREEN, Color.CYAN, Color.BLUE};
20 public static final int SKALIERUNG = 10;
21
22 // Konstanten für Durchführung
23 public static final long RUNDENZEIT = 120;
24 public static final int RUNDENZAHL = 1000;
25
26}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Position.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Position.java
new file mode 100644
index 0000000..546da7f
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Position.java
@@ -0,0 +1,27 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Position {
11
12 private final int x;
13 private final int y;
14
15 public Position(int x, int y) {
16 this.x = x;
17 this.y = y;
18 }
19
20 public int getX() {
21 return this.x;
22 }
23
24 public int getY() {
25 return this.y;
26 }
27}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Spieler.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Spieler.java
new file mode 100644
index 0000000..98bca6e
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Spieler.java
@@ -0,0 +1,79 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4
5/**
6 * Controller
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Spieler {
11
12 private final Spielfeld spiel;
13 private final Ansicht ansicht;
14
15 public Spieler() {
16 this.spiel = new Spielfeld(Param.SPIEL_BREITE,Param.SPIEL_HÖHE);
17 this.ansicht = new Ansicht( Param.SPIEL_BREITE,Param.SPIEL_HÖHE,Param.SKALIERUNG);
18 ansicht.zeichneSpielfeld(spiel.getFeld());
19 ansicht.setText("Außerhalb Spielfeld klicken zum Beenden");
20
21 // Benutzer setzt Anfangspostionen
22 boolean nichtzuende = true;
23 do {
24 Position p = ansicht.getClick();
25 Zelle zelle = new Zelle(p, Zelle.LEBENDIG);
26 nichtzuende = spiel.setZelle(zelle);
27 if (nichtzuende) {
28 ansicht.zeichenZelle(zelle);
29 }
30 } while (nichtzuende);
31 }
32
33 public void spielDurchführen() {
34 for (int runde=0; runde < Param.RUNDENZAHL; runde++){
35 this.rundeDurchführen();
36 ansicht.setText("Runde "+runde);
37 ansicht.sleep(Param.RUNDENZEIT);
38 }
39 }
40
41
42 public void rundeDurchführen() {
43 ArrayList<Zelle> änderungen = new ArrayList<Zelle>();
44 // Änderungen anhand altem Zustand feststellen
45 for (Zelle zelle : spiel.getZellen()) {
46// ArrayList<Zelle> nachbarn = spiel.getNachbarn(zelle);
47 Zelle[] nachbarn = spiel.getNachbarnAryWrapped(zelle);
48 int lebendigeNachbarn = 0;
49 for (Zelle nachbar : nachbarn) {
50 if (nachbar.istLebendig()) lebendigeNachbarn++;
51 }
52 // if (zelle.istLebendig()) {
53 // if (lebendigeNachbarn <= 1 || lebendigeNachbarn >=4) {
54 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.TOT);
55 // änderungen.add(neu);
56 // }
57 // } else { // eventuell zu einem if umbauen, welches Zustand ins Gegenteil verkehrt
58 // if (lebendigeNachbarn == 3) {
59 // Zelle neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
60 // änderungen.add(neu);
61 // }
62 // }
63 Zelle neu;
64 if (zelle.istLebendig() && lebendigeNachbarn % 2 == 0)
65 neu = new Zelle(zelle.getPosition(),Zelle.TOT);
66 else if (! zelle.istLebendig() && lebendigeNachbarn % 2 == 1)
67 neu = new Zelle(zelle.getPosition(),Zelle.LEBENDIG);
68 else
69 neu = zelle.nachkommen();
70 änderungen.add(neu);
71 }
72 // Erkannte Änderungen nun einpflegen
73 for (Zelle zelle : änderungen) {
74 spiel.setZelle(zelle);
75 ansicht.zeichenZelle(zelle);
76 }
77 }
78
79}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Spielfeld.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Spielfeld.java
new file mode 100644
index 0000000..7b9ec60
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Spielfeld.java
@@ -0,0 +1,198 @@
1package de.lmu.tcs;
2
3import java.util.ArrayList;
4import java.util.Collections;
5
6/**
7 * Model
8 *
9 * Created by jost on 24.11.15.
10 */
11public class Spielfeld {
12
13 private final Zelle[][] feld;
14 private final int max_x; //Breite
15 private final int max_y; //Höhe
16
17 public Spielfeld(int breite, int höhe) {
18 this.max_x = breite;
19 this.max_y = höhe;
20 feld = new Zelle[this.max_x][this.max_y];
21 for (int x=0;x<max_x;x++) {
22 for (int y = 0; y < max_y; y++) {
23 final Position p = new Position(x, y);
24 feld[x][y] = new Zelle(p, Zelle.TOT);
25 }
26 }
27 }
28
29 /**
30 * Liefert Zelle des Spielfelds an einer Position.
31 * @param p Position, der Zelle ausgelesen werden soll
32 * @return Zelle des Spielfelds an dieser Position, falls vorhanden; sonst null.
33 */
34 public Zelle getZelle(Position p) {
35 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
36 return feld[p.getX()][p.getY()];
37 } else {
38 return null;
39 }
40 }
41
42 /**
43 * Setzt eine gegebene Zelle ins Spielfeld ein.
44 * Überschreibt vorherige Zelle.
45 *
46 * @param zelle Einzusetzende Zelle
47 * @return Ob die Position der Zelle im Spielfeld enthalten ist (false bedeutuet ungültig).
48 */
49 public boolean setZelle(Zelle zelle) {
50 final Position p = zelle.getPosition();
51 if (p.getX() >= 0 && p.getX() < max_x && p.getY() >= 0 && p.getY() < max_y) {
52 feld[p.getX()][p.getY()] = zelle;
53 return true;
54 } else {
55 return false;
56 }
57 }
58
59 /**
60 * Liefert das gesamte Spielfeld direkt aus;
61 * nicht so schöne, da interne Repräsentierung offenbart wird
62 * und das Array von aussen verändert werden kann! Autsch!
63 *
64 * @return Alle Zellen des Felds im 2D array
65 */
66 public Zelle[][] getFeld() {
67 return feld;
68 }
69
70 /**
71 * BESSERE ALTERNATIVE zu getter-Methode getFeld():
72 * Liefert alle Zellen des Spielfeldes aus. Vorteile:
73 * 1) Interne Repräsentation bleibt versteckt.
74 * 2) Da die Zellen immutable sind, kann hier das
75 * Spielfeld auch nicht woanders manipuliert werden.
76 *
77 * @return Alle Zellen des Spielfeldes als ArrayList
78 */
79 public ArrayList<Zelle> getZellen() {
80 ArrayList<Zelle> result = new ArrayList<>(max_x*max_y);
81 for (int x=0;x<max_x;x++) {
82 for (int y = 0; y < max_y; y++) {
83 result.add(feld[x][y]);
84 }
85 }
86
87 return result;
88 }
89
90 /**
91 * Genau wie getZellen, nur mit echtem Array anstatt ArrayList.
92 * Vorteile bleiben erhalten!
93 *
94 * @return Alle Zellen des Spielfeldes als Array
95 */
96 public Zelle[] getZellenAry() {
97 Zelle[] result = new Zelle[max_x*max_y];
98 int i = 0;
99 for (int x=0;x<max_x;x++) {
100 for (int y = 0; y < max_y; y++) {
101 result[i] = feld[x][y];
102 i++;
103 }
104 }
105 return result;
106 }
107
108 /**
109 * Berechnet alle Nachbarn einer Zelle.
110 *
111 * @param zelle deren Nachbarn berechnet werden sollen
112 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
113 */
114 public ArrayList<Zelle> getNachbarn(Zelle zelle) {
115 ArrayList<Zelle> result = new ArrayList<>();
116 Position pos = zelle.getPosition();
117 for (int x=-1; x<=1; x++) {
118 for (int y = -1; y <= 1; y++) {
119 if (x!=0 || y!=0) {
120 Zelle nachbar = this.getZelle(new Position(pos.getX() + x, pos.getY() + y));
121 if (nachbar != null) {
122 result.add(nachbar);
123 }
124 }
125 }
126 }
127 return result;
128 }
129
130 /**
131 * Berechnet alle Nachbarn einer Zelle.
132 * Variante von getNachbar mit Array anstatt ArrayList
133 *
134 * @param zelle deren Nachbarn berechnet werden sollen
135 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
136 */
137 public Zelle[] getNachbarnAry(Zelle zelle) {
138 Position pos = zelle.getPosition();
139 int minx = Math.max(pos.getX() - 1, 0);
140 int maxx = Math.min(pos.getX() + 1, this.max_x);
141 int miny = Math.max(pos.getY() - 1, 0);
142 int maxy = Math.min(pos.getY() + 1, this.max_y);
143 Zelle[] result = new Zelle[maxx - minx * maxy - miny];
144 int i = 0;
145 for (int x = minx; x <= maxx; x++) {
146 for (int y = miny; y <= maxy; y++) {
147 if (x!=0 || y!=0) {
148 result[i] = feld[x][y];
149 i++;
150 }
151 }
152 }
153 return result;
154 }
155
156 /**
157 * Berechnet alle Nachbarn einer Zelle auf Wrap-Around Spielfeld..
158 *
159 * @param zelle deren Nachbarn berechnet werden sollen
160 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
161 */
162 public ArrayList<Zelle> getNachbarnWrapped(Zelle zelle) {
163 ArrayList<Zelle> result = new ArrayList<Zelle>(8);
164 Position pos = zelle.getPosition();
165 for (int x = -1; x <= 1; x++) {
166 for (int y = -1; y <= 1; y++) {
167 if (x!=0 || y!=0) {
168 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
169 result.add(z);
170 }
171 }
172 }
173 return result;
174 }
175
176 /**
177 * Berechnet alle Nachbarn einer Zelle auf Warap-Around Spielfeld.
178 * Variante von getNachbarWrapped mit Array anstatt ArrayList
179 *
180 * @param zelle deren Nachbarn berechnet werden sollen
181 * @return alle Nachbarn von {@code zelle}, Anzahl Nachbarn variabel
182 */
183 public Zelle[] getNachbarnAryWrapped(Zelle zelle) {
184 Zelle[] result = new Zelle[8];
185 Position pos = zelle.getPosition();
186 int i = 0;
187 for (int x = -1; x <= 1; x++) {
188 for (int y = -1; y <= 1; y++) {
189 if (x!=0 || y!=0) {
190 Zelle z = getZelle(new Position((pos.getX() + x + max_x )% max_x, (pos.getY() + y + max_y) % max_y));
191 result[i] = z;
192 i++;
193 }
194 }
195 }
196 return result;
197 }
198}
diff --git a/ws2015/eip/blaetter/07/de/lmu/tcs/Zelle.java b/ws2015/eip/blaetter/07/de/lmu/tcs/Zelle.java
new file mode 100644
index 0000000..a7c6ad6
--- /dev/null
+++ b/ws2015/eip/blaetter/07/de/lmu/tcs/Zelle.java
@@ -0,0 +1,47 @@
1package de.lmu.tcs;
2
3/**
4 * Model
5 *
6 * Immutable
7 *
8 * Created by jost on 24.11.15.
9 */
10public class Zelle {
11
12 public final static int TOT=0;
13 public final static int LEBENDIG=1;
14
15 private final Position position;
16 private final int zustand;
17
18 public Zelle(Position position, int zustand) {
19 this.position = position;
20 this.zustand = zustand;
21 }
22
23 public Zelle(Zelle old) {
24 this.position = old.position;
25 this.zustand = old.zustand;
26 }
27
28 public Position getPosition() {
29 return position;
30 }
31
32 public boolean istLebendig() {
33 return zustand>=LEBENDIG;
34 }
35
36 public boolean istTot() {
37 return zustand==TOT;
38 }
39
40 public Zelle nachkommen() {
41 return this.istTot() ? (new Zelle(this)) : (new Zelle(position, zustand + 1));
42 }
43
44 public int alter() {
45 return this.istTot() ? -1 : (this.zustand - 1);
46 }
47}
diff --git a/ws2015/eip/blaetter/07/manifest b/ws2015/eip/blaetter/07/manifest
new file mode 100644
index 0000000..2e42f40
--- /dev/null
+++ b/ws2015/eip/blaetter/07/manifest
@@ -0,0 +1,3 @@
1H7-1A
2H7-1B
3H7-1C \ No newline at end of file