diff --git a/bin/uebung09/chess/Board.class b/bin/uebung09/chess/Board.class new file mode 100644 index 0000000..0c92eac Binary files /dev/null and b/bin/uebung09/chess/Board.class differ diff --git a/bin/uebung09/chess/ChessApp.class b/bin/uebung09/chess/ChessApp.class new file mode 100644 index 0000000..b0686be Binary files /dev/null and b/bin/uebung09/chess/ChessApp.class differ diff --git a/bin/uebung09/chess/Color.class b/bin/uebung09/chess/Color.class new file mode 100644 index 0000000..68ceb58 Binary files /dev/null and b/bin/uebung09/chess/Color.class differ diff --git a/bin/uebung09/chess/Knight.class b/bin/uebung09/chess/Knight.class new file mode 100644 index 0000000..8bc030e Binary files /dev/null and b/bin/uebung09/chess/Knight.class differ diff --git a/bin/uebung09/chess/Piece.class b/bin/uebung09/chess/Piece.class new file mode 100644 index 0000000..9b266d6 Binary files /dev/null and b/bin/uebung09/chess/Piece.class differ diff --git a/bin/uebung09/chess/Queen.class b/bin/uebung09/chess/Queen.class new file mode 100644 index 0000000..fd98e42 Binary files /dev/null and b/bin/uebung09/chess/Queen.class differ diff --git a/bin/uebung09/collection/Set.class b/bin/uebung09/collection/Set.class new file mode 100644 index 0000000..90e4147 Binary files /dev/null and b/bin/uebung09/collection/Set.class differ diff --git a/bin/uebung09/collection/SetFactory.class b/bin/uebung09/collection/SetFactory.class new file mode 100644 index 0000000..032e4b2 Binary files /dev/null and b/bin/uebung09/collection/SetFactory.class differ diff --git a/bin/uebung10/logo/DarkForest.class b/bin/uebung10/logo/DarkForest.class new file mode 100644 index 0000000..d7978e6 Binary files /dev/null and b/bin/uebung10/logo/DarkForest.class differ diff --git a/bin/uebung10/logo/Demo.class b/bin/uebung10/logo/Demo.class new file mode 100644 index 0000000..6616076 Binary files /dev/null and b/bin/uebung10/logo/Demo.class differ diff --git a/bin/uebung10/logo/HanselGretelFrame.class b/bin/uebung10/logo/HanselGretelFrame.class new file mode 100644 index 0000000..98c39bf Binary files /dev/null and b/bin/uebung10/logo/HanselGretelFrame.class differ diff --git a/bin/uebung10/logo/Turtle.class b/bin/uebung10/logo/Turtle.class new file mode 100644 index 0000000..c40331a Binary files /dev/null and b/bin/uebung10/logo/Turtle.class differ diff --git a/src/uebung09/chess/Board.java b/src/uebung09/chess/Board.java new file mode 100644 index 0000000..2cfa92a --- /dev/null +++ b/src/uebung09/chess/Board.java @@ -0,0 +1,54 @@ +package chess; + +import java.util.ArrayList; +import java.util.List; + +public class Board { + private final Piece[][] field = new Piece[8][8]; + private final List pieces = new ArrayList<>(); + + void add(Piece piece) { + if (piece.getBoard() != this) + throw new IllegalArgumentException("wrong board"); + final Piece existing = pieceAt(piece.getRow(), piece.getCol()); + if (existing != null) + throw new IllegalArgumentException("already occupied by " + existing); + field[piece.getRow() - 1][piece.getCol() - 1] = piece; + pieces.add(piece); + } + + public void printBoard() { + System.out.println(" 1 2 3 4 5 6 7 8"); + System.out.println(" +---+---+---+---+---+---+---+---+"); + for (int row = 1; row <= 8; row++) { + System.out.print("" + row + " "); + for (int col = 1; col <= 8; col++) { + final Piece p = pieceAt(row, col); + final char c = p == null ? ' ' : p.charRep(); + System.out.print("| " + c + " "); + } + System.out.println("|"); + System.out.println(" +---+---+---+---+---+---+---+---+"); + } + } + + public Piece pieceAt(int row, int col) { + return field[row - 1][col - 1]; + } + + public void check() { + for (Piece p1 : pieces) { + System.out.println(p1.toString()); + for (Piece p2 : pieces) + if (p1 != p2) + if (p1.canCapture(p2)) + System.out.println(" can capture " + p2.toString()); + else + System.out.println(" cannot capture " + p2.toString()); + } + } + + public String toString() { + return pieces.toString(); + } +} diff --git a/src/uebung09/chess/ChessApp.java b/src/uebung09/chess/ChessApp.java new file mode 100644 index 0000000..3b6442c --- /dev/null +++ b/src/uebung09/chess/ChessApp.java @@ -0,0 +1,82 @@ +package chess; + +import java.io.InputStream; +import java.util.NoSuchElementException; +import java.util.Scanner; + +public class ChessApp { + private static final String HELP = "h"; + private static final String CHECK = "c"; + private static final String ABORT = "a"; + private static final String WHITE_QUEEN = "q"; + private static final String BLACK_QUEEN = "Q"; + private static final String WHITE_KNIGHT = "n"; + private static final String BLACK_KNIGHT = "N"; + + private final Scanner scanner; + private final Board board; + + public static void main(String[] args) { + new ChessApp(System.in, new Board()).playChess(); + } + + private ChessApp(InputStream in, Board board) { + scanner = new Scanner(in); + this.board = board; + } + + private void playChess() { + board.printBoard(); + commandLoop(); + System.out.println("Terminated"); + } + + private void commandLoop() { + while (true) { + System.out.printf("Type in command (%s for help):%n", HELP); + try { + final String command = scanner.next(); + if (ABORT.equals(command)) return; + switch (command) { + case HELP -> help(); + case CHECK -> board.check(); + case BLACK_QUEEN -> addQueen(Color.black); + case WHITE_QUEEN -> addQueen(Color.white); + case BLACK_KNIGHT -> addKnight(Color.black); + case WHITE_KNIGHT -> addKnight(Color.white); + default -> System.out.println("Invalid command " + command); + } + } + catch (IllegalArgumentException ex) { + System.out.println(ex.getMessage()); + } + catch (NoSuchElementException ex) { + return; + } + } + } + + private void addKnight(Color color) { + final int row = scanner.nextInt(); + final int col = scanner.nextInt(); + new Knight(color, board, row, col); + board.printBoard(); + } + + private void addQueen(Color color) { + final int row = scanner.nextInt(); + final int col = scanner.nextInt(); + new Queen(color, board, row, col); + board.printBoard(); + } + + private void help() { + System.out.println("Commands:"); + System.out.println(ABORT + ": terminate the program"); + System.out.println(CHECK + ": check the pieces on the board"); + System.out.println(WHITE_KNIGHT + " : place a new white knight at specified position"); + System.out.println(BLACK_KNIGHT + " : place a new black knight at specified position"); + System.out.println(WHITE_QUEEN + " : place a new white queen at specified position"); + System.out.println(BLACK_QUEEN + " : place a new black queen at specified position"); + } +} diff --git a/src/uebung09/chess/Color.java b/src/uebung09/chess/Color.java new file mode 100644 index 0000000..3d5151b --- /dev/null +++ b/src/uebung09/chess/Color.java @@ -0,0 +1,5 @@ +package chess; + +public enum Color { + black, white +} diff --git a/src/uebung09/chess/Knight.java b/src/uebung09/chess/Knight.java new file mode 100644 index 0000000..815cfee --- /dev/null +++ b/src/uebung09/chess/Knight.java @@ -0,0 +1,28 @@ +package chess; + +import static java.lang.Math.abs; + +public class Knight extends Piece { + public Knight(Color color, Board board, int row, int col) { + super(color, board, row, col); + } + + @Override + public char charRep() { + return getColor() == Color.white ? 'n' : 'N'; + } + + @Override + public String toString() { + return String.format("%s knight at (%d,%d)", getColor(), getRow(), getCol()); + } + + @Override + public boolean canCapture(Piece other) { + if (getBoard() != other.getBoard() || getColor() == other.getColor()) + return false; + final int dr = abs(getRow() - other.getRow()); + final int dc = abs(getCol() - other.getCol()); + return dr == 2 && dc == 1 || dr == 1 && dc == 2; + } +} diff --git a/src/uebung09/chess/Piece.java b/src/uebung09/chess/Piece.java new file mode 100644 index 0000000..5b6a716 --- /dev/null +++ b/src/uebung09/chess/Piece.java @@ -0,0 +1,38 @@ +package chess; + +public abstract class Piece { + private Color color; + private Board board; + private int row; + private int col; + + protected Piece(Color color, Board board, int row, int col) { + if (row < 1 || row > 8 || col < 1 || col > 8) + throw new IllegalArgumentException("Invalid pos " + row + "/" + col); + this.color = color; + this.board = board; + this.row = row; + this.col = col; + board.add(this); + } + + public Color getColor() { + return color; + } + + public Board getBoard() { + return board; + } + + public int getRow() { + return row; + } + + public int getCol() { + return col; + } + + public abstract char charRep(); + + public abstract boolean canCapture(Piece other); +} diff --git a/src/uebung09/chess/Queen.java b/src/uebung09/chess/Queen.java new file mode 100644 index 0000000..d75f4b6 --- /dev/null +++ b/src/uebung09/chess/Queen.java @@ -0,0 +1,40 @@ +package chess; + +import static java.lang.Integer.signum; +import static java.lang.Math.abs; + +public class Queen extends Piece { + public Queen(Color color, Board board, int row, int col) { + super(color, board, row, col); + } + + @Override + public char charRep() { + return getColor() == Color.white ? 'q' : 'Q'; + } + + @Override + public String toString() { + return String.format("%s queen at (%d,%d)", getColor(), getRow(), getCol()); + } + + @Override + public boolean canCapture(Piece other) { + if (getBoard() != other.getBoard() || getColor() == other.getColor()) + return false; + if (other.getRow() != getRow() && + other.getCol() != getCol() && + abs(other.getRow() - getRow()) != abs(other.getCol() - getCol())) + return false; + final int dr = signum(other.getRow() - getRow()); + final int dc = signum(other.getCol() - getCol()); + int r = getRow() + dr; + int c = getCol() + dc; + while (r != other.getRow() || c != other.getCol()) { + if (getBoard().pieceAt(r, c) != null) return false; + r += dr; + c += dc; + } + return true; + } +} diff --git a/src/uebung09/collection/Set.java b/src/uebung09/collection/Set.java new file mode 100644 index 0000000..cdcb82d --- /dev/null +++ b/src/uebung09/collection/Set.java @@ -0,0 +1,61 @@ +package collection; + +/** + * A set of elements that does not contain any element twice. + * + * @param the type of all contained elements. + */ +public interface Set extends Iterable { + /** + * Returns the number of elements stored in this set. + * + * @return the number of elements in this set + */ + int size(); + + /** + * Returns true if this set contains no elements. + * + * @return true if this set contains no elements + */ + boolean isEmpty(); + + /** + * Returns true if this set contains the specified element. + * + * @return true if this set contains the specified element. + */ + boolean contains(Object el); + + /** + * Returns the union set of this set and the specified set. + * + * @param other a set + * @return the union set of this set and the specified set. + */ + Set union(Set other); + + /** + * returns the set resulting from adding the specified element to this set. + * + * @param element an element (must not be null) + * @return the set resulting from adding the specified element to this set. + */ + Set add(E element); + + /** + * Returns the intersection of this set and the specified set. + * + * @param other a set + * @return the intersection of this set and the specified set. + */ + Set intersection(Set other); + + /** + * Returns true if all elements of this set are contained in the specified set. + * + * @param other a set + * @return true if all elements of this set are contained in the specified set. + */ + boolean subsetOf(Set other); +} \ No newline at end of file diff --git a/src/uebung09/collection/SetFactory.java b/src/uebung09/collection/SetFactory.java new file mode 100644 index 0000000..1359aca --- /dev/null +++ b/src/uebung09/collection/SetFactory.java @@ -0,0 +1,41 @@ +package collection; + +public class SetFactory { + + private SetFactory() { /* don't instantiate */ } + + /** + * Returns the empty set. + * + * @param the element type of the returned set. + * @return the empty set. + */ + static Set create() { + // TODO implement + return null; + } + + /** + * Returns the singleton set containing the specified element. + * + * @param element an element (must not be null) + * @param the element type of the returned set. + * @return the singleton set containing the specified element. + */ + static Set create(T element) { + // TODO implement + return null; + } + + /** + * Returns a set containing the specified elements. The specified elements may contain equal elements. + * + * @param elems elements of the returned set (may contain equal elements) + * @param the element type of the returned set. + * @return a set containing the specified elements. + */ + static Set create(T... elems) { + // TODO implement + return null; + } +} diff --git a/src/uebung10/logo/DarkForest.java b/src/uebung10/logo/DarkForest.java new file mode 100644 index 0000000..c8a660d --- /dev/null +++ b/src/uebung10/logo/DarkForest.java @@ -0,0 +1,5 @@ +package logo; + +public interface DarkForest { + void breadCrumb(double x, double y); +} diff --git a/src/uebung10/logo/Demo.java b/src/uebung10/logo/Demo.java new file mode 100644 index 0000000..94740c7 --- /dev/null +++ b/src/uebung10/logo/Demo.java @@ -0,0 +1,19 @@ +package logo; + +public class Demo { + public static void main(String[] args) { + final Stmt prog = new Sequence(new PenDown(), new Go(95), + new Turn(90), new Go(95), + new Turn(90), new Go(95), + new Turn(90), new Go(95)); + final Stmt prog2 = new Sequence(new PenDown(), new Go(100), new Turn(120), new Go(100)); + final Stmt prog3 = new Sequence(new PenDown(), new Go(100), new Turn(120), + new Go(25), new PenUp(), new Go(20), new PenDown(), new Go(55), + new PenUp(), new Turn(60), new Go(50), new Turn(90), + new PenDown(), new Go(60)); + final DarkForest gr = new HanselGretelFrame("Logo!"); + final Turtle turtle = new Turtle(250, 250, 0); + final Visitor visitor = new HanselGretelVisitor(30, turtle, gr); + prog3.accept(visitor); + } +} diff --git a/src/uebung10/logo/HanselGretelFrame.java b/src/uebung10/logo/HanselGretelFrame.java new file mode 100644 index 0000000..734f4df --- /dev/null +++ b/src/uebung10/logo/HanselGretelFrame.java @@ -0,0 +1,56 @@ +package logo; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.Ellipse2D; +import java.util.ArrayList; +import java.util.List; + +public class HanselGretelFrame extends JFrame implements DarkForest { + private static final double RADIUS = 2; + private static final Stroke THIN = new BasicStroke(0.2f); + + private final List path = new ArrayList<>(); + private final List dots = new ArrayList<>(); + + private JPanel panel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + final Graphics2D g2d = (Graphics2D) g; + + super.paintComponent(g2d); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g2d.setColor(Color.BLACK); + g2d.setStroke(THIN); + for (Shape pe : new ArrayList<>(path)) + g2d.draw(pe); + g2d.setColor(Color.RED); + for (Shape pe : new ArrayList<>(dots)) + g2d.fill(pe); + } + }; + + public HanselGretelFrame(String title) { + super(title); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setSize(500, 500); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + setVisible(true); + } + + @Override + public void breadCrumb(double x, double y) { + dots.add(new Ellipse2D.Double(x - RADIUS, y - RADIUS, 2 * RADIUS, 2 * RADIUS)); + repaint(); + } +} diff --git a/src/uebung10/logo/Turtle.java b/src/uebung10/logo/Turtle.java new file mode 100644 index 0000000..497bfd3 --- /dev/null +++ b/src/uebung10/logo/Turtle.java @@ -0,0 +1,35 @@ +package logo; + +public class Turtle { + private double x; + private double y; + private double angle; + + public Turtle(double x, double y, double angle) { + this.x = x; + this.y = y; + this.angle = angle; + } + + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getAngle() { + return angle; + } + + public void turn(double degrees) { + angle += degrees; + } + + public void go(double dist) { + final double rad = Math.toRadians(angle); + x += dist * Math.cos(rad); + y -= dist * Math.sin(rad); + } +} diff --git a/test/uebung/uebung09/iterator/Array2dIteratorTest.java b/test/uebung/uebung09/iterator/Array2dIteratorTest.java new file mode 100644 index 0000000..14e3a8e --- /dev/null +++ b/test/uebung/uebung09/iterator/Array2dIteratorTest.java @@ -0,0 +1,43 @@ +package iterator; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +public class Array2dIteratorTest { + @Test + public void testArray2dIterator() { + final String[][] array = {{}, {"foo", "bar"}, {"baz"}, {}}; + final Iterator it = new Array2dIterator<>(array); + assertTrue(it.hasNext()); + assertEquals("foo", it.next()); + assertTrue(it.hasNext()); + assertEquals("bar", it.next()); + assertTrue(it.hasNext()); + assertEquals("baz", it.next()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testArray2dIteratorOnlyEmpty() { + final String[][] array = {{}, {}, {}}; + final Iterator it = new Array2dIterator<>(array); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testArray2dIteratorEmpty() { + final String[][] array = {}; + final Iterator it = new Array2dIterator<>(array); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } +} diff --git a/test/uebung/uebung09/iterator/SkipNullIteratorTest.java b/test/uebung/uebung09/iterator/SkipNullIteratorTest.java new file mode 100644 index 0000000..372fb2c --- /dev/null +++ b/test/uebung/uebung09/iterator/SkipNullIteratorTest.java @@ -0,0 +1,122 @@ +package iterator; + +import org.junit.Test; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +public class SkipNullIteratorTest { + @Test + public void testEmpty() { + final Iterator it = new SkipNullIterator<>(emptyList().iterator()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testNull() { + final Iterator it = new SkipNullIterator<>(asList(null, null).iterator()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testNonNull() { + final Iterator it = new SkipNullIterator<>(asList("foo").iterator()); + assertTrue(it.hasNext()); + assertEquals("foo", it.next()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testMixed() { + final Iterator it = new SkipNullIterator<>(asList(null, "foo", null).iterator()); + assertTrue(it.hasNext()); + assertEquals("foo", it.next()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testMixed2() { + final Iterator oriIt = asList("a", "b", null, "c").iterator(); + Iterator it = new SkipNullIterator<>(oriIt); + assertTrue(it.hasNext()); + assertEquals("a", it.next()); + assertTrue(it.hasNext()); + assertEquals("b", it.next()); + assertTrue(it.hasNext()); + assertEquals("c", it.next()); + assertFalse(it.hasNext()); + assertThrows(NoSuchElementException.class, it::next); + } + + @Test + public void testDontCallInCtor() { + final Iterator dontCallNext = new Iterator<>() { + @Override + public boolean hasNext() { + throw new RuntimeException(); + } + + @Override + public String next() { + throw new RuntimeException(); + } + }; + + new SkipNullIterator<>(dontCallNext); + } + + @Test + public void testSkipNullIteratorInfinity() { + final Iterator oriIt = new Iterator<>() { + @Override + public boolean hasNext() { + return true; + } + + @Override + public String next() { + return "infinity"; + } + }; + + final Iterator it = new SkipNullIterator<>(oriIt); + for (int i = 0; i < 1000; i++) { + assertTrue(it.hasNext()); + assertEquals("infinity", it.next()); + } + } + + @Test + public void testPathological() { + final Iterator oriIt = new Iterator<>() { + private int ctr; + + @Override + public boolean hasNext() { + return true; + } + + @Override + public String next() { + return ctr++ > 100000 ? "infinity" : null; + } + }; + + final Iterator it = new SkipNullIterator<>(oriIt); + for (int i = 0; i < 1000; i++) { + assertTrue(it.hasNext()); + assertEquals("infinity", it.next()); + } + } +} \ No newline at end of file