initial commit

This commit is contained in:
Dominic 2019-11-29 19:27:56 +01:00
commit c74d331b66
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
17 changed files with 1699 additions and 0 deletions

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# Progra WS 2019/20
Dieses Repository enthält Code, der während des Tutoriums entstanden ist. Solltet ihr Fehler finden, so weist mich bitte auf diese hin. Ich möchte ausdrücklich darauf hinweisen, dass es sich bei diesem Code nicht um die Musterlösung handelt; diese findet ihr im RWTHMoodle.

45
tut5/src/A.java Normal file
View file

@ -0,0 +1,45 @@
public class A
{
private Integer i;
private double d;
public A()
{
this.i = 1;
this.d = 4;
}
public A(Integer x, double y)
{
this.i = x;
this.d = y;
}
public A(int x, double y)
{
this.i = 3;
this.d = x + y;
}
public int f(Integer x)
{
return this.i + x;
}
public int f(double i)
{
this.d = i;
return this.i;
}
public static void main(String args[])
{
A a1 = new A();
System.out.println(a1.f(5));
System.out.println(a1.d);
System.out.println(a1.f(Long.valueOf(2)));
A a2 = new A(1, 1);
System.out.println(a2.i);
System.out.println(a2.d);
}
}

126
tut5/src/Circle.java Normal file
View file

@ -0,0 +1,126 @@
public class Circle
{
private int x;
private int y;
private int radius;
/**
* Erstellt einen neuen Kreis mit den angegebenen Werten. Wenn der radius negativ ist,
* wird ein Fehler zurückgegeben.
*
* @param x Die x-Koordinate des Mittelpunktes des Kreises.
* @param y Die y-Koordinate des Mittelpunktes des Kreises.
* @param radius Der Radius des Kreises.
* @return Der neu erstellte Kreis.
*/
public static Circle newCircle(int x, int y, int radius)
{
if (radius < 0)
{
Utils.error("negativer Radius");
return null;
}
Circle circle = new Circle();
circle.x = x;
circle.y = y;
circle.radius = radius;
return circle;
}
public static Circle newCircle(int radius)
{
return newCircle(0, 0, radius);
}
public Circle clone()
{
return newCircle(this.x, this.y, this.radius);
}
public int getX()
{
return this.x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return this.y;
}
public void setY(int y)
{
this.y = y;
}
public int getRadius()
{
return this.radius;
}
public void setRadius(int radius)
{
if (radius < 0)
Utils.error("negativer Radius");
else
this.radius = radius;
}
public boolean contains(Circle ...other)
{
for (Circle circle : other)
{
if (Utils.dist(this.x, this.y, circle.x, circle.y) > this.radius - circle.radius)
return false;
}
return true;
}
public static Circle circumscriber(int x, int y, Circle ...circles)
{
for (int radius = 1; true; radius++)
{
Circle circle = newCircle(x, y, radius);
if (circle.contains(circles))
return circle;
}
}
public String toString()
{
// (10|11),12
return "(" + this.x + "|" + this.y + ")," + this.radius;
}
public void performAction(CircleAction action)
{
switch(action)
{
case UP:
this.y -= 10;
break;
case DOWN:
this.y += 10;
break;
case LEFT:
this.x -= 10;
break;
case RIGHT:
this.x += 10;
break;
case BIGGER:
this.radius += 10;
break;
case SMALLER:
this.radius -= 10;
break;
default:
break;
}
}
}

View file

@ -0,0 +1,4 @@
public enum CircleAction
{
UP, DOWN, LEFT, RIGHT, BIGGER, SMALLER, IDLE, NOOP
}

58
tut5/src/Utils.java Normal file
View file

@ -0,0 +1,58 @@
import java.awt.*;
public class Utils {
private Utils(){}
/**
* Berechnet den Abstand zwischen den Punkten (xa,ya) und (xb,yb).
* @param xa der x-Anteil des ersten Punktes
* @param ya der y-Anteil des ersten Punktes
* @param xb der x-Anteil des zweiten Punktes
* @param yb der y-Anteil des zweiten Punktes
* @return den Abstand der beiden Punkte
*/
public static double dist(int xa, int ya, int xb, int yb) {
return new Point(xa, ya).distance(new Point(xb, yb));
}
/**
* Gibt eine Fehlermeldung aus.
* @param msg die Fehlermeldung, die ausgegeben werden soll
*/
public static void error(String msg) {
System.err.println(msg);
}
/**
* Berechnet das Maximum der Argumente.
* @param args die Werte, deren Maximum bestimmt werden soll
* @return den maximalen Wert aller Argumente
*/
public static int max(int... args) {
if (args.length == 0) {
error("Called max without arguments!");
}
int res = args[0];
for (int i = 1; i < args.length; i++) {
res = Math.max(res, args[i]);
}
return res;
}
/**
* Berechnet das Minimum der Argumente.
* @param args die Werte, deren Minimum bestimmt werden soll
* @return den minimalen Wert aller Argumente
*/
public static int min(int... args) {
if (args.length == 0) {
error("Called min without arguments!");
}
int res = args[0];
for (int i = 1; i < args.length; i++) {
res = Math.min(res, args[i]);
}
return res;
}
}

126
tut5/src/XCircle.java Normal file
View file

@ -0,0 +1,126 @@
import java.awt.*;
import java.awt.event.*;
import java.nio.file.*;
import javax.swing.*;
@SuppressWarnings("serial")
class MyCanvas extends JComponent {
private Circle circle;
public MyCanvas(Circle circle) {
this.setPreferredSize(new Dimension(300, 230));
this.circle = circle;
}
@Override
public void paint(Graphics g) {
g.drawOval(circle.getX() - circle.getRadius() / 2,
circle.getY() - circle.getRadius() / 2,
circle.getRadius(),
circle.getRadius());
}
}
@SuppressWarnings("serial")
class MyButton extends JButton {
MyButton(String label) {
super(label);
setPreferredSize(new Dimension(120, 30));
}
}
abstract class ClickListener implements MouseListener {
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
abstract class KeyPressedListener implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
public class XCircle {
private XCircle(){}
public static void main(String[] a) {
final Circle circle = Circle.newCircle(150, 115, 50);
final JFrame window = new JFrame();
window.setLayout(new FlowLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(300, 300, 300, 300);
JComponent canvas = new MyCanvas(circle);
window.getContentPane().add(canvas);
JButton bigger = addButton(window, circle, "Bigger!", CircleAction.BIGGER);
JButton narrower = addButton(window, circle, "Smaller!", CircleAction.SMALLER);
KeyListener kl = new KeyPressedListener() {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
circle.performAction(CircleAction.UP);
break;
case KeyEvent.VK_DOWN:
circle.performAction(CircleAction.DOWN);
break;
case KeyEvent.VK_LEFT:
circle.performAction(CircleAction.LEFT);
break;
case KeyEvent.VK_RIGHT:
circle.performAction(CircleAction.RIGHT);
break;
default:
return;
}
window.repaint();
}
};
for (JComponent c : new JComponent[] { canvas, bigger, narrower }) {
c.addKeyListener(kl);
}
window.setVisible(true);
}
private static JButton addButton(final JFrame window, final Circle circle, final String label, final CircleAction action) {
JButton button = new MyButton(label);
button.addMouseListener(new ClickListener() {
@Override
public void mouseClicked(MouseEvent e) {
circle.performAction(action);
window.repaint();
}
});
window.getContentPane().add(button);
return button;
}
}

147
tut6/src/BoolTreeNode.java Normal file
View file

@ -0,0 +1,147 @@
public class BoolTreeNode
{
private String variable;
private BoolTreeNode child1;
private BoolTreeNode child2;
private BoolTreeNode(String variableInput)
{
variable = variableInput;
}
private BoolTreeNode(BoolTreeNode negated)
{
child1 = negated;
}
private BoolTreeNode(BoolTreeNode kind1, BoolTreeNode kind2)
{
child1 = kind1;
child2 = kind2;
}
public static BoolTreeNode boolTreeTrueNode()
{
return new BoolTreeNode("true");
}
public static BoolTreeNode boolTreeFalseNode()
{
return new BoolTreeNode("false");
}
public static BoolTreeNode boolTreeVariableNode(String variableInput)
{
if (variableInput == null || variableInput.length() == 0 || variableInput.equals("true") || variableInput.equals("false"))
{
Utils.error("ungueltiger Name der Variablen");
return null;
}
return new BoolTreeNode(variableInput);
}
public static BoolTreeNode boolTreeNotNode(BoolTreeNode negated)
{
return new BoolTreeNode(negated);
}
public static BoolTreeNode boolTreeAndNode(BoolTreeNode child1, BoolTreeNode child2)
{
return new BoolTreeNode(child1, child2);
}
public int depth()
{
if (child2 != null) // konjunktionsknoten
{
int depth1 = child1.depth();
int depth2 = child2.depth();
return Utils.max(depth1, depth2) + 1;
}
if (child1 != null) // negationsknoten
{
return child1.depth() + 1;
}
// variablenknoten
return 0;
}
public boolean isLeaf()
{
return (depth() == 0);
}
public boolean isTrueLeaf()
{
return isLeaf() && variable.equals("true");
}
public boolean isFalseLeaf()
{
return isLeaf() && variable.equals("false");
}
public boolean isNegation()
{
return (child1 != null && child2 == null);
}
public boolean isConjunction()
{
return (child1 != null && child2 != null);
}
/**
* Wertet den durch diesen Baum dargestellten Booleschen Ausdruck aus.
*
* @param trueVars Die Namen aller Variablen, die true sind.
* @return Den Wert des Ausdruckes.
*/
public boolean evaluate(String ...trueVars)
{
if (isLeaf()) // variablenknoten
return Utils.evaluateVariable(variable, trueVars);
if (isConjunction()) // konjunktionsknoten
return child1.evaluate(trueVars) && child2.evaluate(trueVars);
// negationsknoten
return !child1.evaluate(trueVars);
}
/**
* Entfernt doppelte Negationen aus dem Baum.
*
* @return true wenn eine doppelte Negation gefunden wurde und entfernt wurde.
*/
public boolean removeDoubleNegations()
{
if (isLeaf())
return false;
if (isConjunction())
return child1.removeDoubleNegations() | child2.removeDoubleNegations();
// negationsknoten
if (!child1.isNegation())
return false;
BoolTreeNode grandchild = child1.child1;
variable = grandchild.variable;
child1 = grandchild.child1;
child2 = grandchild.child2;
child1.removeDoubleNegations();
child2.removeDoubleNegations();
return true;
}
public static void main(String args[])
{
BoolTreeNode tree = boolTreeAndNode(
boolTreeNotNode(boolTreeNotNode(boolTreeVariableNode("a"))),
boolTreeNotNode(boolTreeNotNode(boolTreeVariableNode("b"))));
System.out.println(tree.removeDoubleNegations());
System.out.println("fertig");
}
}

734
tut6/src/Canvas.java Normal file
View file

@ -0,0 +1,734 @@
/*
* HINWEIS:
*
* Sie brauchen den Java-Code, der in dieser Datei steht, nicht zu lesen oder zu
* verstehen. Alle Hinweise, die zur Verwendung der Datei noetig sind, koennen Sie
* aus den jeweiligen Aufgabentexten entnehmen.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
/**
* User interface for a Logo-like language. Allows to see the painting process step-by-step.
*/
public class Canvas {
/**
* The color brown.
*/
public static final Color BROWN = new Color(160, 82, 45);
/**
* The color green.
*/
public static final Color GREEN = Color.GREEN;
/**
* Adds the current position to the specified bounds.
* @param g The graphics object to draw on.
* @param boundsParam The bounds of the canvas.
*/
private static void addCurrentPos(Graphics2D g, Rectangle boundsParam) {
if (boundsParam != null) {
Canvas.addToBounds(new Point2D.Float(0f, 0f), boundsParam, g);
}
}
/**
* Adds a point to the bounds, transformed as in the current graphics object.
* @param point The point to add to the bounds.
* @param boundsParam The bounds.
* @param g The graphics object storing affine transformations.
*/
private static void addToBounds(Point2D point, Rectangle boundsParam, Graphics2D g) {
boundsParam.add(g.getTransform().transform(point, null));
}
/**
* Adds a rectangle to the bounds, transformed as in the current graphics object.
* @param r The rectangle to add to the bounds.
* @param boundsParam The bounds.
* @param g The graphics object storing affine transformations.
*/
private static void addToBounds(Rectangle2D r, Rectangle boundsParam, Graphics2D g) {
double maxX = r.getMaxX();
double maxY = r.getMaxY();
double minX = r.getMinX();
double minY = r.getMinY();
Canvas.addToBounds(new Point2D.Double(maxX, maxY), boundsParam, g);
Canvas.addToBounds(new Point2D.Double(maxX, minY), boundsParam, g);
Canvas.addToBounds(new Point2D.Double(minX, maxY), boundsParam, g);
Canvas.addToBounds(new Point2D.Double(minX, minY), boundsParam, g);
}
/**
* The bounds of the canvas.
*/
protected Rectangle bounds;
/**
* The actions to be executed on the canvas.
*/
private ArrayList<Canvas.GraphicAction> actions = new ArrayList<>();
/**
* The actual drawing on the canvas.
*/
private final JComponent drawing = new JPanel() {
/**
* For serialization.
*/
private static final long serialVersionUID = -1665573331455268961L;
@Override
public Dimension getPreferredSize() {
synchronized (Canvas.this) {
return Canvas.this.bounds == null ? new Dimension(100, 100) : Canvas.this.bounds.getSize();
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
synchronized (Canvas.this) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle clipBounds = g.getClipBounds();
g2.setColor(Color.WHITE);
g2.fill(clipBounds);
g2.setColor(Color.BLACK);
AffineTransform t = g2.getTransform();
int drawCounter;
// do we have current bounds?
if (Canvas.this.bounds == null) {
Rectangle newBounds = new Rectangle();
Canvas.this.transformations.clear();
drawCounter = 0;
for (GraphicAction a : Canvas.this.actions) {
a.replay(g2, false, newBounds);
if (a.drawsSomething()) {
drawCounter++;
}
}
Canvas.this.bounds = new Rectangle(newBounds);
}
// move the drawing inside the screen
GraphicAction init = new Move(20 - Canvas.this.bounds.x, 20 - Canvas.this.bounds.y);
// draw all lines
g2.setTransform(t);
Canvas.this.transformations.clear();
drawCounter = 0;
init.replay(g2, true, null);
for (GraphicAction a : Canvas.this.actions) {
boolean draw = !(a instanceof DrawTextLabel);
a.replay(g2, draw, null);
if (a.drawsSomething()) {
drawCounter++;
}
if (drawCounter >= Canvas.this.renderMaxDraws) {
break;
}
}
// draw all labels
g2.setTransform(t);
Canvas.this.transformations.clear();
drawCounter = 0;
init.replay(g2, true, null);
for (GraphicAction a : Canvas.this.actions) {
boolean draw = (a instanceof DrawTextLabel);
a.replay(g2, draw, null);
if (a.drawsSomething()) {
drawCounter++;
}
if (drawCounter >= Canvas.this.renderMaxDraws) {
break;
}
}
}
}
};
/**
* The number of actions actually drawing something. Used to step forward and backward through the painting process.
*/
private int draws;
/**
* Listener to execute the paint actions.
*/
private final ActionListener handler = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "start":
Canvas.this.renderMaxDraws = 0;
break;
case "next":
Canvas.this.renderMaxDraws++;
break;
case "back":
Canvas.this.renderMaxDraws--;
break;
case "end":
Canvas.this.renderMaxDraws = Canvas.this.draws;
break;
}
Canvas.this.step.setText("Schritt: " + Canvas.this.renderMaxDraws);
Canvas.this.drawing.repaint();
}
};
/**
* Current step in the stepwise view of the painting process.
*/
private int renderMaxDraws = 0;
/**
* Label for showing the current step.
*/
private final JLabel step = new JLabel("Schritt: " + this.renderMaxDraws);
/**
* Used to (re-)store positions and orientations on the canvas.
*/
private final Stack<AffineTransform> transformations = new Stack<>();
/**
* The frame to display the canvas.
*/
private final JFrame ui = new JFrame() {
/**
* For serialization.
*/
private static final long serialVersionUID = 8620900696432559397L;
{
// set up components
final JScrollPane scrollPane = new JScrollPane(Canvas.this.drawing);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
final JPanel panel = new JPanel();
final JButton startButton = new JButton("Anfang");
startButton.setActionCommand("start");
startButton.addActionListener(Canvas.this.handler);
final JButton backButton = new JButton("Zurueck");
backButton.setActionCommand("back");
backButton.addActionListener(Canvas.this.handler);
final JButton forwardButton = new JButton("Vor");
forwardButton.setActionCommand("next");
forwardButton.addActionListener(Canvas.this.handler);
final JButton endButton = new JButton("Ende");
endButton.setActionCommand("end");
endButton.addActionListener(Canvas.this.handler);
// configure frame
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
// set up layout
GroupLayout jPanel1Layout = new GroupLayout(panel);
panel.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(
GroupLayout.Alignment.LEADING
).addGap(0, 158, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(
GroupLayout.Alignment.LEADING
).addGap(0, 36, Short.MAX_VALUE)
);
GroupLayout layout = new GroupLayout(this.getContentPane());
this.getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(
GroupLayout.Alignment.LEADING
).addGroup(
GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap().addGroup(
layout.createParallelGroup(
GroupLayout.Alignment.TRAILING
).addComponent(
scrollPane,
GroupLayout.Alignment.LEADING,
GroupLayout.DEFAULT_SIZE,
458,
Short.MAX_VALUE
).addGroup(
GroupLayout.Alignment.LEADING,
layout.createSequentialGroup().addComponent(
startButton
).addGap(
6,
6,
6
).addComponent(
backButton
).addGap(
6,
6,
6
).addComponent(
forwardButton
).addGap(
6,
6,
6
).addComponent(
endButton
).addGap(
18,
18,
18
).addComponent(
Canvas.this.step
).addPreferredGap(
LayoutStyle.ComponentPlacement.RELATED
).addComponent(
panel,
GroupLayout.DEFAULT_SIZE,
GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE
)
)
).addContainerGap()
)
);
layout.setVerticalGroup(
layout.createParallelGroup(
GroupLayout.Alignment.LEADING
).addGroup(
GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup().addContainerGap().addComponent(
scrollPane,
GroupLayout.DEFAULT_SIZE,
400,
Short.MAX_VALUE
).addPreferredGap(
LayoutStyle.ComponentPlacement.RELATED
).addGroup(
layout.createParallelGroup(
GroupLayout.Alignment.TRAILING
).addComponent(
panel,
GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE
).addGroup(
layout.createParallelGroup(
GroupLayout.Alignment.BASELINE
).addComponent(
startButton
).addComponent(
backButton
).addComponent(
forwardButton
).addComponent(
endButton
).addComponent(
Canvas.this.step
)
)
).addContainerGap()
)
);
// make frame visible
this.pack();
this.setVisible(true);
}
};
/**
* Choose the specified color for further painting.
* @param c The color to choose.
*/
public void chooseColor(Color c) {
this.addAction(new ChooseColor(c));
}
/**
* Draws a line of length {@code length} in the current direction. The current position is moved to the end of the
* line.
* @param length The length of the line to draw.
*/
public void drawForward(int length) {
this.addAction(new DrawForward(length));
}
/**
* Draws a box with the text {@code text} at the current position.
* @param text The text to draw.
*/
public void drawTextLabel(String text) {
this.addAction(new DrawTextLabel(text));
}
/**
* Moves the current position by {@code x} units to the right and {@code y} units down according to the current
* orientation (so if the orientation is rotated by 180 degrees, the move goes left and up instead of right and
* down). This does not draw anything.
* @param x The measure to go right.
* @param y The measure to go down.
*/
public void move(double x, double y) {
this.addAction(new Move(x, y));
}
/**
* Moves the current position by {@code length} units in the current direction without drawing anything.
* @param length The measure to move the current position.
*/
public void moveForward(int length) {
this.addAction(new MoveForward(length));
}
/**
* Sets the current position and orientation to the top-most stored position and orientation. See {@link #push()}.
*/
public void pop() {
this.addAction(new Pop());
}
/**
* Stores the current position and orientation.
* By a subsequent {@link #pop()}, this position and orientation can be restored.
*/
public void push() {
this.addAction(new Push());
}
/**
* Refreshes the shown frame.
*/
public void refresh() {
synchronized (this) {}
this.drawing.revalidate();
this.ui.revalidate();
this.ui.repaint();
}
/**
* Turns the current orientation by {@code degrees} degrees (360 degrees form a circle) clockwise.
* Negative values turn counter-clockwise.
* @param degrees The degrees to turn the orientation.
*/
public void rotate(int degrees) {
this.addAction(new Rotate(degrees));
}
/**
* Draws a filled square of the specified length {@code length} at the current position and with the current
* orientation.
* @param length The length of the square to draw.
*/
public void square(double length) {
this.addAction(new DrawSquare(length));
}
/**
* Adds the specified action to the list of actions to be executed and updates the corresponding counter. Moreover,
* the current bounds are deleted.
* @param action The action to add.
*/
private void addAction(GraphicAction action) {
synchronized (this) {
this.actions.add(action);
if (action.drawsSomething()) {
this.draws++;
}
this.bounds = null;
}
}
/**
* Action to choose a color.
*/
private class ChooseColor extends GraphicAction {
/**
* The color to choose.
*/
private final Color color;
/**
* @param c The color to choose.
*/
ChooseColor(Color c) {
this.color = c;
}
@Override
public boolean drawsSomething() {
return false;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
g.setColor(this.color);
}
}
/**
* Action to draw a line forward.
*/
private class DrawForward extends MoveForward {
/**
* @param length The length of the line to draw.
*/
DrawForward(int length) {
super(length);
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
if (draw) {
g.drawLine(0, 0, 0, this.length);
}
super.replay(g, draw, boundsParam);
}
}
/**
* Action to draw a square.
*/
private class DrawSquare extends GraphicAction {
/**
* The length of the square.
*/
private final double length;
/**
* @param length The length of the square.
*/
DrawSquare(double length) {
this.length = length;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
double hl = this.length / 2;
Rectangle2D r = new Rectangle2D.Double();
r.setFrame(-hl, -hl, this.length, this.length);
g.fill(r);
if (boundsParam != null) {
Canvas.addToBounds(r, boundsParam, g);
}
}
}
/**
* Action to draw a text label.
*/
private class DrawTextLabel extends GraphicAction {
/**
* The text of the label.
*/
private final String text;
/**
* @param text The text of the label.
*/
DrawTextLabel(String text) {
this.text = text;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
AffineTransform origTrans = g.getTransform();
Point2D center = origTrans.transform(new Point2D.Double(0, 0), null);
FontRenderContext frc = g.getFontRenderContext();
Font f = g.getFont();
TextLayout tl = new TextLayout(this.text, f, frc);
double w = tl.getBounds().getWidth();
double h = tl.getBounds().getHeight();
// move the text to the center of the box
AffineTransform trans = new AffineTransform();
trans.setToTranslation(Math.round(center.getX() - w / 2), Math.round(center.getY() + h / 2));
g.setTransform(trans);
// draw the box
Rectangle r = new Rectangle(0, (int)-h, (int)w, (int)h);
if (draw) {
Shape textShape = tl.getOutline(new AffineTransform());
g.setColor(Color.BLACK);
r.grow(4, 4);
g.setColor(Color.WHITE);
g.fill(r);
g.setColor(Color.BLACK);
g.draw(r);
g.fill(textShape);
}
if (boundsParam != null) {
Canvas.addToBounds(r, boundsParam, g);
}
// restore original orientation
g.setTransform(origTrans);
}
}
/**
* An action for our canvas.
*/
private abstract class GraphicAction {
/**
* @return True if this action actually draws something. False otherwise. Needs to be overridden by actions not
* drawing something.
*/
public boolean drawsSomething() {
return true;
}
/**
* The drawing method used in this canvas.
* @param g The graphics object to draw on.
* @param draw Flag to indicate whether the drawing action should actually be displayed.
* @param boundsParam The bounds of the canvas.
*/
abstract void replay(Graphics2D g, boolean draw, Rectangle boundsParam);
}
/**
* Action for moving the current position.
*/
private class Move extends GraphicAction {
/**
* The measure to move right.
*/
private final double x;
/**
* The measure to move down.
*/
private final double y;
/**
* @param x The measure to move right.
* @param y The measure to move down.
*/
Move(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public boolean drawsSomething() {
return false;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
g.translate(this.x, this.y);
if (boundsParam != null) {
Canvas.addToBounds(new Point2D.Double(this.x, this.y), boundsParam, g);
}
}
}
/**
* Action for moving forward.
*/
private class MoveForward extends GraphicAction {
/**
* The number of units to move forward.
*/
final int length;
/**
* @param length The number of units to move forward.
*/
MoveForward(int length) {
this.length = length;
}
@Override
public boolean drawsSomething() {
return false;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
Canvas.addCurrentPos(g, boundsParam);
AffineTransform t = g.getTransform();
t.translate(0, this.length);
g.setTransform(t);
Canvas.addCurrentPos(g, boundsParam);
}
}
/**
* Action for restoring a position and orientation.
*/
private class Pop extends GraphicAction {
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
g.setTransform(Canvas.this.transformations.pop());
}
}
/**
* Action for storing the current position and orientation.
*/
private class Push extends GraphicAction {
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
Canvas.this.transformations.push(g.getTransform());
}
}
/**
* Action for rotation the current orientation.
*/
private class Rotate extends GraphicAction {
/**
* The degrees to turn the current orientation.
*/
final int degree;
/**
* @param degree The degrees to turn the current orientation.
*/
Rotate(int degree) {
this.degree = degree;
}
@Override
public boolean drawsSomething() {
return false;
}
@Override
void replay(Graphics2D g, boolean draw, Rectangle boundsParam) {
AffineTransform t = g.getTransform();
t.rotate(this.degree / 180.0 * Math.PI);
g.setTransform(t);
}
}
}

83
tut6/src/Squares.java Normal file
View file

@ -0,0 +1,83 @@
/**
* Program for drawing a square fractal.
*/
public class Squares
{
/**
* @param args Contains the parameters for the drawing. The first
* (mandatory) is the recursion level. The second (optional)
* is the base length of the first square. The default value
* for this length is 100 if it is not specified. Each
* parameter must be positive.
*/
public static void main(String args[])
{
int level;
int length = 100;
switch (args.length)
{
case 2:
length = Integer.parseInt(args[1]);
// fall-through
case 1:
level = Integer.parseInt(args[0]);
break;
default:
System.out.println(
"Es muessen zwischen 1 und 2 Parameter angegeben werden "
+ "(Level und eventuell Basislaenge)!"
);
return;
}
if (level < 1)
{
System.out.println("Das Rekursionslevel muss positiv sein!");
return;
}
if (length < 1)
{
System.out.println("Die Basislaenge muss positiv sein!");
return;
}
Canvas c = new Canvas();
Squares.paintFractal(c, level, length);
c.refresh();
}
/**
* Draws a square fractal with the specified recursion level and base length
* on the specified canvas.
*
* @param c The canvas to draw the tree on.
* @param level The current recursion level.
* @param length The current length.
*/
private static void paintFractal(Canvas c, int level, double length)
{
if (level <= 0)
return;
c.square(length);
// oben links
c.move(-length/2, -length/2);
paintFractal(c, level-1, length/2);
// oben rechts
c.move(length, 0);
paintFractal(c, level-1, length/2);
// unten rechts
c.move(0, length);
paintFractal(c, level-1, length/2);
// unten links
c.move(-length, 0);
paintFractal(c, level-1, length/2);
// zurueck zum mittelpunkt
c.move(length/2, -length/2);
}
}

69
tut6/src/Utils.java Normal file
View file

@ -0,0 +1,69 @@
import java.awt.*;
public class Utils {
private Utils(){}
/**
* Evaluiert eine Variable bei mit wahr angenommenen Variablen
* @param elem der Name der zu evaluierenden Variable oder true oder false
* @param strings die Namen genau der Variablen, die für diese Evalutaion als wahr angenommen werden
* @return true, wenn die Variable zu true evaluiert wird, sonst false
*/
public static boolean evaluateVariable(String elem, String... strings) {
if (elem.equals("true")) {
//variable is constant true
return true;
} else if (elem.equals("false")) {
//variable is constant false
return false;
} else {
return contains(elem,strings);
}
}
/**
* Gibt zurück, ob elem in strings enthalten ist
* @param elem der String, nach dem gesucht werden soll
* @param strings die Strings, die durchsucht werden sollen
* @return wenn elem in strings enthalten ist, sonst false
*/
public static boolean contains(String elem, String... strings) {
if (strings == null) {
//strings is null, elem cannot be contained
return false;
}
for (String string : strings) {
if (string.equals(elem)) {
//elem is in strings
return true;
}
}
//elem has not been found in strings
return false;
}
/**
* Gibt eine Fehlermeldung aus.
* @param msg die Fehlermeldung, die ausgegeben werden soll
*/
public static void error(String msg) {
System.err.println(msg);
}
/**
* Berechnet das Maximum der Argumente.
* @param args die Werte, deren Maximum bestimmt werden soll
* @return den maximalen Wert aller Argumente
*/
public static int max(int... args) {
if (args.length == 0) {
error("Called max without arguments!");
}
int res = args[0];
for (int i = 1; i < args.length; i++) {
res = Math.max(res, args[i]);
}
return res;
}
}

24
tut7/src/Buerger.java Normal file
View file

@ -0,0 +1,24 @@
public class Buerger
{
private final String name;
public Buerger(final String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
public boolean hatDiebesgut()
{
return false;
}
public void aktion(Buerger buerger[])
{
}
}

36
tut7/src/Dieb.java Normal file
View file

@ -0,0 +1,36 @@
public class Dieb extends Buerger
{
private int diebesgut;
public Dieb(String name)
{
super(name);
diebesgut = 0;
}
@Override
public boolean hatDiebesgut()
{
return (diebesgut > 0);
}
@Override
public void aktion(Buerger buerger[])
{
for (int i = 0; i < 5; i++)
{
int zufall = Zufall.zahl(buerger.length);
if (buerger[zufall] instanceof ReicherBuerger)
{
ReicherBuerger rb = (ReicherBuerger)buerger[zufall];
int klauen = Zufall.zahl(rb.getReichtum());
diebesgut += klauen;
rb.setReichtum(rb.getReichtum() - klauen);
}
else if (buerger[zufall] instanceof Polizist)
{
return;
}
}
}
}

19
tut7/src/Gefangener.java Normal file
View file

@ -0,0 +1,19 @@
public class Gefangener extends Dieb
{
public Gefangener(String name)
{
super(name);
}
@Override
public boolean hatDiebesgut()
{
return false;
}
@Override
public void aktion(Buerger buerger[])
{
System.out.println("Gefangener " + toString() + " aergert sich im Gefaengnis");
}
}

19
tut7/src/Polizist.java Normal file
View file

@ -0,0 +1,19 @@
public class Polizist extends Buerger
{
public Polizist(String name)
{
super(name);
}
@Override
public void aktion(Buerger buerger[])
{
for (int i = 0; i < buerger.length; i++)
{
if (buerger[i].hatDiebesgut())
{
buerger[i] = new Gefangener(buerger[i].toString());
}
}
}
}

View file

@ -0,0 +1,28 @@
public class ReicherBuerger extends Buerger
{
private int reichtum;
public ReicherBuerger(String name, int reichtum)
{
super(name);
this.reichtum = reichtum;
}
@Override
public void aktion(Buerger buerger[])
{
int zufall = Zufall.zahl(reichtum);
System.out.println("Buerger " + toString() + " besticht einen Politiker mit " + zufall + " Euro");
reichtum -= zufall;
}
public int getReichtum()
{
return reichtum;
}
public void setReichtum(int reichtum)
{
this.reichtum = reichtum;
}
}

36
tut7/src/Stadt.java Normal file
View file

@ -0,0 +1,36 @@
public class Stadt
{
private Buerger buerger[];
public Stadt(int anzahl)
{
buerger = new Buerger[anzahl];
for (int i = 0; i < anzahl; i++)
{
int zufall = Zufall.zahl(4);
switch (zufall) {
case 0:
buerger[i] = new Dieb(Zufall.name());
break;
case 1:
buerger[i] = new Gefangener(Zufall.name());
break;
case 2:
buerger[i] = new ReicherBuerger(Zufall.name(), Zufall.zahl(998) + 2);
break;
case 3:
buerger[i] = new Polizist(Zufall.name());
}
}
}
public static void main(String args[])
{
Stadt stadt = new Stadt(10);
for (int i = 0; i < 10; i++)
{
int zufall = Zufall.zahl(10);
stadt.buerger[zufall].aktion(stadt.buerger);
}
}
}

142
tut7/src/Zufall.java Normal file
View file

@ -0,0 +1,142 @@
import java.util.Random;
public class Zufall {
private static Random r = new Random();
/**
* Gibt eine zufaellige Zahl zwischen {@code 0} und {@code i - 1} zurueck.
*
* @param i Die Obergrenze (nicht eingeschlossen).
* @return Die Zufallszahl.
*/
public static int zahl(int i) {
return r.nextInt(i);
}
private static String[] artikel = { "Adventskalender", "Armband", "Buch",
"Christbaumschmuck", "Fensterbild", "Glasfigur", "Handschuhe",
"Holzkrippe", "Holzpuzzle", "Kerze", "Kette", "Kuscheldecke",
"Lichterkette", "Muetze", "Räucherhaus", "Rucksack", "Schal",
"Seife", "Schlitten", "Socken", "Stofftier", "Tasse", "Teedose",
"Teelichtkarussel", "Uhr", "Weihnachtspyramide", "Weihnachtsstern",
"Windlicht" };
private static String[] namen = { "Aaron", "Achmed", "Achmet", "Adrian",
"Ahmad", "Ahmed", "Ahmet", "Aileen", "Alena", "Alex", "Alexander",
"Alexandra", "Ali", "Alica", "Alice", "Alicia", "Alina", "Amelie",
"Amely", "Anabel", "Andre", "Andrea", "Andreas", "Angelina",
"Angelique", "Anica", "Anika", "Anja", "Ann", "Anna", "Annabel",
"Annabell", "Annabelle", "Annalena", "Anne", "Annica", "Annika",
"Annkathrin", "Annkatrin", "Anton", "Antonia", "Armin", "Arne",
"Arthur", "Artur", "Ayleen", "Aylin", "Bastian", "Ben", "Benedict",
"Benedikt", "Benjamin", "Bennet", "Bennett", "Bianca", "Bianka",
"Birte", "Birthe", "Bjarne", "Brian", "Bryan", "Calvin", "Can",
"Caren", "Carina", "Carl", "Carla", "Carlotta", "Carolin",
"Carolina", "Caroline", "Carsten", "Catarina", "Catharina",
"Cathrin", "Catrin", "Cedric", "Cedrik", "Celina", "Celine", "Cem",
"Chantal", "Chantale", "Charlin", "Charline", "Charlotte",
"Chiara", "Chris", "Christian", "Christin", "Christina",
"Christine", "Christof", "Christoph", "Christopher", "Cindy",
"Claas", "Clara", "Claudia", "Clemens", "Colin", "Collin",
"Conrad", "Constantin", "Corinna", "Cornelius", "Dana", "Daniel",
"Daniela", "Danny", "Dario", "David", "Denis", "Denise", "Deniz",
"Dennis", "Diana", "Dilara", "Dominic", "Dominik", "Dominique",
"Dustin", "Eike", "Eileen", "Elena", "Elias", "Elisa", "Elisabeth",
"Emilia", "Emilie", "Emily", "Emma", "Emmily", "Emre", "Enrico",
"Eric", "Erik", "Esther", "Eva", "Fabian", "Fabienne", "Fabio",
"Felix", "Fenja", "Finja", "Finn", "Finnja", "Fiona", "Florian",
"Frank", "Franziska", "Frederic", "Frederik", "Frederike",
"Friederike", "Fynn", "Gabriel", "Georg", "Gerrit", "Gina",
"Gregor", "Greta", "Hanna", "Hannah", "Hannes", "Hans", "Hauke",
"Helen", "Helena", "Hendrik", "Henning", "Henri", "Henrik",
"Henrike", "Henry", "Ina", "Inga", "Isabel", "Isabell", "Isabelle",
"Ivonne", "Jacob", "Jacqueline", "Jakob", "Jan", "Jana", "Janek",
"Janin", "Janina", "Janine", "Janis", "Janna", "Janne", "Jannek",
"Jannes", "Jannik", "Jannika", "Jannis", "Jaqueline", "Jasmin",
"Jasmina", "Jason", "Jasper", "Jean", "Jennifer", "Jenny", "Jens",
"Jeremie", "Jeremy", "Jerome", "Jessica", "Jessika", "Jil", "Jill",
"Joana", "Joanna", "Joel", "Johan", "Johann", "Johanna",
"Johannes", "John", "Jona", "Jonah", "Jonas", "Jonathan",
"Josefine", "Josephine", "Joshua", "Judith", "Jule", "Julia",
"Julian", "Juliane", "Julie", "Julien", "Julius", "Justin",
"Justus", "Kai", "Kaja", "Karen", "Karina", "Karl", "Karla",
"Karlotta", "Karolina", "Karoline", "Karsten", "Katarina",
"Katharina", "Kathrin", "Katja", "Katrin", "Kay", "Kerstin",
"Kevin", "Kiara", "Kilian", "Kim", "Kimberley", "Kimberly", "Kira",
"Klaas", "Klara", "Klemens", "Konrad", "Konstantin", "Korinna",
"Kornelius", "Kristian", "Kristin", "Kristina", "Kristine",
"Kristof", "Kyra", "Lara", "Larissa", "Lars", "Lasse", "Laura",
"Lea", "Leah", "Leif", "Lena", "Lennard", "Lennart", "Leo", "Leon",
"Leonard", "Leoni", "Leonie", "Levin", "Lidia", "Lili", "Lilli",
"Lilly", "Lina", "Linda", "Linn", "Linus", "Lisa", "Liza",
"Lorenz", "Louis", "Louisa", "Louise", "Luca", "Lucas", "Lucie",
"Lucy", "Luis", "Luisa", "Luise", "Luka", "Lukas", "Lydia", "Lynn",
"Madeleine", "Mads", "Magdalena", "Maik", "Maike", "Maja", "Malin",
"Malina", "Malte", "Mandy", "Manuel", "Mara", "Marah", "Marc",
"Marcel", "Marco", "Marcus", "Mareike", "Marek", "Maren", "Maria",
"Mariam", "Marie", "Marina", "Mario", "Marius", "Mark", "Marko",
"Markus", "Marleen", "Marlene", "Marlon", "Marten", "Martin",
"Marvin", "Marwin", "Mathias", "Mathies", "Mathis", "Matis",
"Mats", "Matthias", "Matthis", "Mattis", "Maurice", "Max", "Maxi",
"Maximilian", "Maya", "Mehmet", "Meik", "Meike", "Melanie",
"Melina", "Melissa", "Melvin", "Merle", "Merlin", "Mia", "Michael",
"Michaela", "Michel", "Michelle", "Mike", "Milena", "Mira",
"Miriam", "Mirko", "Mohamed", "Mohammed", "Mona", "Monique",
"Moritz", "Morten", "Muhammed", "Nadine", "Nadja", "Natalie",
"Natascha", "Nathalie", "Neele", "Nele", "Nic", "Nicholas", "Nick",
"Niclas", "Nico", "Nicolai", "Nicolas", "Nicole", "Niels", "Nik",
"Niklas", "Niko", "Nikolai", "Nikolas", "Nils", "Nina", "Noah",
"Nora", "Norman", "Ole", "Oliver", "Olivia", "Oscar", "Oskar",
"Pascal", "Patricia", "Patrick", "Patrik", "Patrizia", "Paul",
"Paula", "Paulina", "Pauline", "Peer", "Per", "Peter", "Phil",
"Philip", "Philipp", "Pia", "Pierre", "Rafael", "Ralf", "Ralph",
"Ramona", "Raphael", "Rebecca", "Rebekka", "Ricarda", "Ricardo",
"Riccardo", "Richard", "Rico", "Riko", "Robert", "Robin", "Roman",
"Ronja", "Ruben", "Sabine", "Sabrina", "Samantha", "Samira",
"Samuel", "Sandra", "Sandro", "Sandy", "Sara", "Sarah", "Sascha",
"Saskia", "Sebastian", "Selina", "Simon", "Simone", "Sina",
"Sinah", "Sofia", "Sofie", "Sonja", "Sophia", "Sophie", "Stefan",
"Stefanie", "Steffen", "Stella", "Stephan", "Stephanie", "Steve",
"Steven", "Susanne", "Svantje", "Svea", "Sven", "Svenja",
"Swantje", "Swen", "Tabea", "Tamara", "Tania", "Tanja", "Tatjana",
"Teresa", "Tessa", "Theresa", "Thies", "Thilo", "Thomas",
"Thorben", "Thore", "Thorge", "Thorsten", "Til", "Till", "Tilo",
"Tim", "Timm", "Timo", "Timon", "Tina", "Tobias", "Tom", "Tomas",
"Toni", "Tony", "Torben", "Tore", "Torge", "Torsten", "Tristan",
"Valentin", "Valerie", "Vanessa", "Verena", "Victor", "Victoria",
"Vievienne", "Viktor", "Viktoria", "Vincent", "Vivien", "Wibke",
"Wiebke", "Yannic", "Yannick", "Yannik", "Yannis", "Yasemin",
"Yasmin", "Yasmina", "Yvonne", "Zoe" };
private static String[] suesswaren = { "gebrannte Mandeln", "Lebkuchen",
"Makronen", "Marzipan", "Pralinen", "Printen", "Schokoladenkugeln",
"Schokofruechte", "Spekulatius", "Waffeln", "Zimtsterne",
"Zuckerstange" };
/**
* Gibt einen zufaelligen Artikel zurueck.
*
* @return Der Artikel.
*/
public static String artikel() {
return artikel[r.nextInt(artikel.length)];
}
/**
* Gibt einen zufaelligen Vornamen zurueck, der in den 90ern beliebt war.
*
* @return Der Vorname.
*/
public static String name() {
return namen[r.nextInt(namen.length)];
}
/**
* Gibt eine zufaellige Suessware zurueck.
*
* @return Die Suessware.
*/
public static String suessware() {
return suesswaren[r.nextInt(suesswaren.length)];
}
}